mirror of
https://github.com/open-webui/open-webui
synced 2025-05-30 02:02:13 +00:00
enh: bypass embedding and retrieval
This commit is contained in:
parent
1c2e36f1b7
commit
57010901e6
@ -1502,13 +1502,16 @@ VECTOR_DB = os.environ.get("VECTOR_DB", "chroma")
|
|||||||
# Chroma
|
# Chroma
|
||||||
if VECTOR_DB == "chroma":
|
if VECTOR_DB == "chroma":
|
||||||
import chromadb
|
import chromadb
|
||||||
|
|
||||||
CHROMA_DATA_PATH = f"{DATA_DIR}/vector_db"
|
CHROMA_DATA_PATH = f"{DATA_DIR}/vector_db"
|
||||||
CHROMA_TENANT = os.environ.get("CHROMA_TENANT", chromadb.DEFAULT_TENANT)
|
CHROMA_TENANT = os.environ.get("CHROMA_TENANT", chromadb.DEFAULT_TENANT)
|
||||||
CHROMA_DATABASE = os.environ.get("CHROMA_DATABASE", chromadb.DEFAULT_DATABASE)
|
CHROMA_DATABASE = os.environ.get("CHROMA_DATABASE", chromadb.DEFAULT_DATABASE)
|
||||||
CHROMA_HTTP_HOST = os.environ.get("CHROMA_HTTP_HOST", "")
|
CHROMA_HTTP_HOST = os.environ.get("CHROMA_HTTP_HOST", "")
|
||||||
CHROMA_HTTP_PORT = int(os.environ.get("CHROMA_HTTP_PORT", "8000"))
|
CHROMA_HTTP_PORT = int(os.environ.get("CHROMA_HTTP_PORT", "8000"))
|
||||||
CHROMA_CLIENT_AUTH_PROVIDER = os.environ.get("CHROMA_CLIENT_AUTH_PROVIDER", "")
|
CHROMA_CLIENT_AUTH_PROVIDER = os.environ.get("CHROMA_CLIENT_AUTH_PROVIDER", "")
|
||||||
CHROMA_CLIENT_AUTH_CREDENTIALS = os.environ.get("CHROMA_CLIENT_AUTH_CREDENTIALS", "")
|
CHROMA_CLIENT_AUTH_CREDENTIALS = os.environ.get(
|
||||||
|
"CHROMA_CLIENT_AUTH_CREDENTIALS", ""
|
||||||
|
)
|
||||||
# Comma-separated list of header=value pairs
|
# Comma-separated list of header=value pairs
|
||||||
CHROMA_HTTP_HEADERS = os.environ.get("CHROMA_HTTP_HEADERS", "")
|
CHROMA_HTTP_HEADERS = os.environ.get("CHROMA_HTTP_HEADERS", "")
|
||||||
if CHROMA_HTTP_HEADERS:
|
if CHROMA_HTTP_HEADERS:
|
||||||
@ -1608,6 +1611,14 @@ DOCUMENT_INTELLIGENCE_KEY = PersistentConfig(
|
|||||||
os.getenv("DOCUMENT_INTELLIGENCE_KEY", ""),
|
os.getenv("DOCUMENT_INTELLIGENCE_KEY", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
BYPASS_EMBEDDING_AND_RETRIEVAL = PersistentConfig(
|
||||||
|
"BYPASS_EMBEDDING_AND_RETRIEVAL",
|
||||||
|
"rag.bypass_embedding_and_retrieval",
|
||||||
|
os.environ.get("BYPASS_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
RAG_TOP_K = PersistentConfig(
|
RAG_TOP_K = PersistentConfig(
|
||||||
"RAG_TOP_K", "rag.top_k", int(os.environ.get("RAG_TOP_K", "3"))
|
"RAG_TOP_K", "rag.top_k", int(os.environ.get("RAG_TOP_K", "3"))
|
||||||
)
|
)
|
||||||
@ -1824,10 +1835,10 @@ RAG_WEB_SEARCH_ENGINE = PersistentConfig(
|
|||||||
os.getenv("RAG_WEB_SEARCH_ENGINE", ""),
|
os.getenv("RAG_WEB_SEARCH_ENGINE", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
RAG_WEB_SEARCH_FULL_CONTEXT = PersistentConfig(
|
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = PersistentConfig(
|
||||||
"RAG_WEB_SEARCH_FULL_CONTEXT",
|
"BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL",
|
||||||
"rag.web.search.full_context",
|
"rag.web.search.bypass_embedding_and_retrieval",
|
||||||
os.getenv("RAG_WEB_SEARCH_FULL_CONTEXT", "False").lower() == "true",
|
os.getenv("BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true",
|
||||||
)
|
)
|
||||||
|
|
||||||
# You can provide a list of your own websites to filter after performing a web search.
|
# You can provide a list of your own websites to filter after performing a web search.
|
||||||
|
@ -162,6 +162,7 @@ from open_webui.config import (
|
|||||||
RAG_TEMPLATE,
|
RAG_TEMPLATE,
|
||||||
DEFAULT_RAG_TEMPLATE,
|
DEFAULT_RAG_TEMPLATE,
|
||||||
RAG_FULL_CONTEXT,
|
RAG_FULL_CONTEXT,
|
||||||
|
BYPASS_EMBEDDING_AND_RETRIEVAL,
|
||||||
RAG_EMBEDDING_MODEL,
|
RAG_EMBEDDING_MODEL,
|
||||||
RAG_EMBEDDING_MODEL_AUTO_UPDATE,
|
RAG_EMBEDDING_MODEL_AUTO_UPDATE,
|
||||||
RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE,
|
RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE,
|
||||||
@ -191,7 +192,7 @@ from open_webui.config import (
|
|||||||
YOUTUBE_LOADER_PROXY_URL,
|
YOUTUBE_LOADER_PROXY_URL,
|
||||||
# Retrieval (Web Search)
|
# Retrieval (Web Search)
|
||||||
RAG_WEB_SEARCH_ENGINE,
|
RAG_WEB_SEARCH_ENGINE,
|
||||||
RAG_WEB_SEARCH_FULL_CONTEXT,
|
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL,
|
||||||
RAG_WEB_SEARCH_RESULT_COUNT,
|
RAG_WEB_SEARCH_RESULT_COUNT,
|
||||||
RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
|
RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
|
||||||
RAG_WEB_SEARCH_TRUST_ENV,
|
RAG_WEB_SEARCH_TRUST_ENV,
|
||||||
@ -531,6 +532,7 @@ app.state.config.FILE_MAX_COUNT = RAG_FILE_MAX_COUNT
|
|||||||
|
|
||||||
|
|
||||||
app.state.config.RAG_FULL_CONTEXT = RAG_FULL_CONTEXT
|
app.state.config.RAG_FULL_CONTEXT = RAG_FULL_CONTEXT
|
||||||
|
app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL = BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
app.state.config.ENABLE_RAG_HYBRID_SEARCH = ENABLE_RAG_HYBRID_SEARCH
|
app.state.config.ENABLE_RAG_HYBRID_SEARCH = ENABLE_RAG_HYBRID_SEARCH
|
||||||
app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = (
|
app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = (
|
||||||
ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION
|
ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION
|
||||||
@ -567,7 +569,9 @@ app.state.config.YOUTUBE_LOADER_PROXY_URL = YOUTUBE_LOADER_PROXY_URL
|
|||||||
|
|
||||||
app.state.config.ENABLE_RAG_WEB_SEARCH = ENABLE_RAG_WEB_SEARCH
|
app.state.config.ENABLE_RAG_WEB_SEARCH = ENABLE_RAG_WEB_SEARCH
|
||||||
app.state.config.RAG_WEB_SEARCH_ENGINE = RAG_WEB_SEARCH_ENGINE
|
app.state.config.RAG_WEB_SEARCH_ENGINE = RAG_WEB_SEARCH_ENGINE
|
||||||
app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT = RAG_WEB_SEARCH_FULL_CONTEXT
|
app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = (
|
||||||
|
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL
|
||||||
|
)
|
||||||
app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = RAG_WEB_SEARCH_DOMAIN_FILTER_LIST
|
app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = RAG_WEB_SEARCH_DOMAIN_FILTER_LIST
|
||||||
|
|
||||||
app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = ENABLE_GOOGLE_DRIVE_INTEGRATION
|
app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = ENABLE_GOOGLE_DRIVE_INTEGRATION
|
||||||
|
@ -17,6 +17,7 @@ from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT
|
|||||||
from open_webui.utils.misc import get_last_user_message, calculate_sha256_string
|
from open_webui.utils.misc import get_last_user_message, calculate_sha256_string
|
||||||
|
|
||||||
from open_webui.models.users import UserModel
|
from open_webui.models.users import UserModel
|
||||||
|
from open_webui.models.files import Files
|
||||||
|
|
||||||
from open_webui.env import (
|
from open_webui.env import (
|
||||||
SRC_LOG_LEVELS,
|
SRC_LOG_LEVELS,
|
||||||
@ -342,6 +343,7 @@ def get_embedding_function(
|
|||||||
|
|
||||||
|
|
||||||
def get_sources_from_files(
|
def get_sources_from_files(
|
||||||
|
request,
|
||||||
files,
|
files,
|
||||||
queries,
|
queries,
|
||||||
embedding_function,
|
embedding_function,
|
||||||
@ -359,19 +361,64 @@ def get_sources_from_files(
|
|||||||
relevant_contexts = []
|
relevant_contexts = []
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
|
|
||||||
|
context = None
|
||||||
if file.get("docs"):
|
if file.get("docs"):
|
||||||
|
# BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL
|
||||||
context = {
|
context = {
|
||||||
"documents": [[doc.get("content") for doc in file.get("docs")]],
|
"documents": [[doc.get("content") for doc in file.get("docs")]],
|
||||||
"metadatas": [[doc.get("metadata") for doc in file.get("docs")]],
|
"metadatas": [[doc.get("metadata") for doc in file.get("docs")]],
|
||||||
}
|
}
|
||||||
elif file.get("context") == "full":
|
elif file.get("context") == "full":
|
||||||
|
# Manual Full Mode Toggle
|
||||||
context = {
|
context = {
|
||||||
"documents": [[file.get("file").get("data", {}).get("content")]],
|
"documents": [[file.get("file").get("data", {}).get("content")]],
|
||||||
"metadatas": [[{"file_id": file.get("id"), "name": file.get("name")}]],
|
"metadatas": [[{"file_id": file.get("id"), "name": file.get("name")}]],
|
||||||
}
|
}
|
||||||
else:
|
elif (
|
||||||
context = None
|
file.get("type") != "web_search"
|
||||||
|
and request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
|
):
|
||||||
|
# BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
|
if file.get("type") == "collection":
|
||||||
|
file_ids = file.get("data", {}).get("file_ids", [])
|
||||||
|
|
||||||
|
documents = []
|
||||||
|
metadatas = []
|
||||||
|
for file_id in file_ids:
|
||||||
|
file_object = Files.get_file_by_id(file_id)
|
||||||
|
|
||||||
|
if file_object:
|
||||||
|
documents.append(file_object.data.get("content", ""))
|
||||||
|
metadatas.append(
|
||||||
|
{
|
||||||
|
"file_id": file_id,
|
||||||
|
"name": file_object.filename,
|
||||||
|
"source": file_object.filename,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"documents": [documents],
|
||||||
|
"metadatas": [metadatas],
|
||||||
|
}
|
||||||
|
|
||||||
|
elif file.get("id"):
|
||||||
|
file_object = Files.get_file_by_id(file.get("id"))
|
||||||
|
if file_object:
|
||||||
|
context = {
|
||||||
|
"documents": [[file_object.data.get("content", "")]],
|
||||||
|
"metadatas": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"file_id": file.get("id"),
|
||||||
|
"name": file_object.filename,
|
||||||
|
"source": file_object.filename,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
}
|
||||||
|
else:
|
||||||
collection_names = []
|
collection_names = []
|
||||||
if file.get("type") == "collection":
|
if file.get("type") == "collection":
|
||||||
if file.get("legacy"):
|
if file.get("legacy"):
|
||||||
@ -434,6 +481,7 @@ def get_sources_from_files(
|
|||||||
if context:
|
if context:
|
||||||
if "data" in file:
|
if "data" in file:
|
||||||
del file["data"]
|
del file["data"]
|
||||||
|
|
||||||
relevant_contexts.append({**context, "file": file})
|
relevant_contexts.append({**context, "file": file})
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
|
@ -107,8 +107,7 @@ class ChromaClient:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except:
|
||||||
log.exception(f"{e}")
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get(self, collection_name: str) -> Optional[GetResult]:
|
def get(self, collection_name: str) -> Optional[GetResult]:
|
||||||
|
@ -352,6 +352,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
|
|||||||
"status": True,
|
"status": True,
|
||||||
"pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES,
|
"pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES,
|
||||||
"RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT,
|
"RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT,
|
||||||
|
"BYPASS_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL,
|
||||||
"enable_google_drive_integration": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
|
"enable_google_drive_integration": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
|
||||||
"enable_onedrive_integration": request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION,
|
"enable_onedrive_integration": request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION,
|
||||||
"content_extraction": {
|
"content_extraction": {
|
||||||
@ -378,7 +379,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
|
|||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
"ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
||||||
"RAG_WEB_SEARCH_FULL_CONTEXT": request.app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT,
|
"BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL,
|
||||||
"search": {
|
"search": {
|
||||||
"enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH,
|
"enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH,
|
||||||
"drive": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
|
"drive": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
|
||||||
@ -473,11 +474,12 @@ class WebSearchConfig(BaseModel):
|
|||||||
class WebConfig(BaseModel):
|
class WebConfig(BaseModel):
|
||||||
search: WebSearchConfig
|
search: WebSearchConfig
|
||||||
ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION: Optional[bool] = None
|
ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION: Optional[bool] = None
|
||||||
RAG_WEB_SEARCH_FULL_CONTEXT: Optional[bool] = None
|
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL: Optional[bool] = None
|
||||||
|
|
||||||
|
|
||||||
class ConfigUpdateForm(BaseModel):
|
class ConfigUpdateForm(BaseModel):
|
||||||
RAG_FULL_CONTEXT: Optional[bool] = None
|
RAG_FULL_CONTEXT: Optional[bool] = None
|
||||||
|
BYPASS_EMBEDDING_AND_RETRIEVAL: Optional[bool] = None
|
||||||
pdf_extract_images: Optional[bool] = None
|
pdf_extract_images: Optional[bool] = None
|
||||||
enable_google_drive_integration: Optional[bool] = None
|
enable_google_drive_integration: Optional[bool] = None
|
||||||
enable_onedrive_integration: Optional[bool] = None
|
enable_onedrive_integration: Optional[bool] = None
|
||||||
@ -504,6 +506,12 @@ async def update_rag_config(
|
|||||||
else request.app.state.config.RAG_FULL_CONTEXT
|
else request.app.state.config.RAG_FULL_CONTEXT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL = (
|
||||||
|
form_data.BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
|
if form_data.BYPASS_EMBEDDING_AND_RETRIEVAL is not None
|
||||||
|
else request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
|
)
|
||||||
|
|
||||||
request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = (
|
request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = (
|
||||||
form_data.enable_google_drive_integration
|
form_data.enable_google_drive_integration
|
||||||
if form_data.enable_google_drive_integration is not None
|
if form_data.enable_google_drive_integration is not None
|
||||||
@ -557,8 +565,8 @@ async def update_rag_config(
|
|||||||
request.app.state.config.ENABLE_RAG_WEB_SEARCH = form_data.web.search.enabled
|
request.app.state.config.ENABLE_RAG_WEB_SEARCH = form_data.web.search.enabled
|
||||||
request.app.state.config.RAG_WEB_SEARCH_ENGINE = form_data.web.search.engine
|
request.app.state.config.RAG_WEB_SEARCH_ENGINE = form_data.web.search.engine
|
||||||
|
|
||||||
request.app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT = (
|
request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = (
|
||||||
form_data.web.RAG_WEB_SEARCH_FULL_CONTEXT
|
form_data.web.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL
|
||||||
)
|
)
|
||||||
|
|
||||||
request.app.state.config.SEARXNG_QUERY_URL = (
|
request.app.state.config.SEARXNG_QUERY_URL = (
|
||||||
@ -626,6 +634,7 @@ async def update_rag_config(
|
|||||||
"status": True,
|
"status": True,
|
||||||
"pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES,
|
"pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES,
|
||||||
"RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT,
|
"RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT,
|
||||||
|
"BYPASS_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL,
|
||||||
"file": {
|
"file": {
|
||||||
"max_size": request.app.state.config.FILE_MAX_SIZE,
|
"max_size": request.app.state.config.FILE_MAX_SIZE,
|
||||||
"max_count": request.app.state.config.FILE_MAX_COUNT,
|
"max_count": request.app.state.config.FILE_MAX_COUNT,
|
||||||
@ -650,7 +659,7 @@ async def update_rag_config(
|
|||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
"ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
||||||
"RAG_WEB_SEARCH_FULL_CONTEXT": request.app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT,
|
"BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL,
|
||||||
"search": {
|
"search": {
|
||||||
"enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH,
|
"enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH,
|
||||||
"engine": request.app.state.config.RAG_WEB_SEARCH_ENGINE,
|
"engine": request.app.state.config.RAG_WEB_SEARCH_ENGINE,
|
||||||
@ -1019,6 +1028,7 @@ def process_file(
|
|||||||
hash = calculate_sha256_string(text_content)
|
hash = calculate_sha256_string(text_content)
|
||||||
Files.update_file_hash_by_id(file.id, hash)
|
Files.update_file_hash_by_id(file.id, hash)
|
||||||
|
|
||||||
|
if not request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL:
|
||||||
try:
|
try:
|
||||||
result = save_docs_to_vector_db(
|
result = save_docs_to_vector_db(
|
||||||
request,
|
request,
|
||||||
@ -1049,6 +1059,14 @@ def process_file(
|
|||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"status": True,
|
||||||
|
"collection_name": None,
|
||||||
|
"filename": file.filename,
|
||||||
|
"content": text_content,
|
||||||
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
if "No pandoc was found" in str(e):
|
if "No pandoc was found" in str(e):
|
||||||
@ -1408,9 +1426,11 @@ async def process_web_search(
|
|||||||
)
|
)
|
||||||
docs = await loader.aload()
|
docs = await loader.aload()
|
||||||
|
|
||||||
if request.app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT:
|
if request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL:
|
||||||
return {
|
return {
|
||||||
"status": True,
|
"status": True,
|
||||||
|
"collection_name": None,
|
||||||
|
"filenames": urls,
|
||||||
"docs": [
|
"docs": [
|
||||||
{
|
{
|
||||||
"content": doc.page_content,
|
"content": doc.page_content,
|
||||||
@ -1418,7 +1438,6 @@ async def process_web_search(
|
|||||||
}
|
}
|
||||||
for doc in docs
|
for doc in docs
|
||||||
],
|
],
|
||||||
"filenames": urls,
|
|
||||||
"loaded_count": len(docs),
|
"loaded_count": len(docs),
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
|
@ -351,24 +351,25 @@ async def chat_web_search_handler(
|
|||||||
all_results.append(results)
|
all_results.append(results)
|
||||||
files = form_data.get("files", [])
|
files = form_data.get("files", [])
|
||||||
|
|
||||||
if request.app.state.config.RAG_WEB_SEARCH_FULL_CONTEXT:
|
if results.get("collection_name"):
|
||||||
files.append(
|
|
||||||
{
|
|
||||||
"docs": results.get("docs", []),
|
|
||||||
"name": searchQuery,
|
|
||||||
"type": "web_search_docs",
|
|
||||||
"urls": results["filenames"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
files.append(
|
files.append(
|
||||||
{
|
{
|
||||||
"collection_name": results["collection_name"],
|
"collection_name": results["collection_name"],
|
||||||
"name": searchQuery,
|
"name": searchQuery,
|
||||||
"type": "web_search_results",
|
"type": "web_search",
|
||||||
"urls": results["filenames"],
|
"urls": results["filenames"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
elif results.get("docs"):
|
||||||
|
files.append(
|
||||||
|
{
|
||||||
|
"docs": results.get("docs", []),
|
||||||
|
"name": searchQuery,
|
||||||
|
"type": "web_search",
|
||||||
|
"urls": results["filenames"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
form_data["files"] = files
|
form_data["files"] = files
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
@ -518,6 +519,7 @@ async def chat_completion_files_handler(
|
|||||||
sources = []
|
sources = []
|
||||||
|
|
||||||
if files := body.get("metadata", {}).get("files", None):
|
if files := body.get("metadata", {}).get("files", None):
|
||||||
|
queries = []
|
||||||
try:
|
try:
|
||||||
queries_response = await generate_queries(
|
queries_response = await generate_queries(
|
||||||
request,
|
request,
|
||||||
@ -543,8 +545,8 @@ async def chat_completion_files_handler(
|
|||||||
queries_response = {"queries": [queries_response]}
|
queries_response = {"queries": [queries_response]}
|
||||||
|
|
||||||
queries = queries_response.get("queries", [])
|
queries = queries_response.get("queries", [])
|
||||||
except Exception as e:
|
except:
|
||||||
queries = []
|
pass
|
||||||
|
|
||||||
if len(queries) == 0:
|
if len(queries) == 0:
|
||||||
queries = [get_last_user_message(body["messages"])]
|
queries = [get_last_user_message(body["messages"])]
|
||||||
@ -556,6 +558,7 @@ async def chat_completion_files_handler(
|
|||||||
sources = await loop.run_in_executor(
|
sources = await loop.run_in_executor(
|
||||||
executor,
|
executor,
|
||||||
lambda: get_sources_from_files(
|
lambda: get_sources_from_files(
|
||||||
|
request=request,
|
||||||
files=files,
|
files=files,
|
||||||
queries=queries,
|
queries=queries,
|
||||||
embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION(
|
embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION(
|
||||||
@ -738,6 +741,7 @@ async def process_chat_payload(request, form_data, metadata, user, model):
|
|||||||
|
|
||||||
tool_ids = form_data.pop("tool_ids", None)
|
tool_ids = form_data.pop("tool_ids", None)
|
||||||
files = form_data.pop("files", None)
|
files = form_data.pop("files", None)
|
||||||
|
|
||||||
# Remove files duplicates
|
# Remove files duplicates
|
||||||
if files:
|
if files:
|
||||||
files = list({json.dumps(f, sort_keys=True): f for f in files}.values())
|
files = list({json.dumps(f, sort_keys=True): f for f in files}.values())
|
||||||
@ -795,8 +799,6 @@ async def process_chat_payload(request, form_data, metadata, user, model):
|
|||||||
if len(sources) > 0:
|
if len(sources) > 0:
|
||||||
context_string = ""
|
context_string = ""
|
||||||
for source_idx, source in enumerate(sources):
|
for source_idx, source in enumerate(sources):
|
||||||
source_id = source.get("source", {}).get("name", "")
|
|
||||||
|
|
||||||
if "document" in source:
|
if "document" in source:
|
||||||
for doc_idx, doc_context in enumerate(source["document"]):
|
for doc_idx, doc_context in enumerate(source["document"]):
|
||||||
context_string += f"<source><source_id>{source_idx}</source_id><source_context>{doc_context}</source_context></source>\n"
|
context_string += f"<source><source_id>{source_idx}</source_id><source_context>{doc_context}</source_context></source>\n"
|
||||||
@ -1913,7 +1915,9 @@ async def process_chat_response(
|
|||||||
)
|
)
|
||||||
|
|
||||||
log.info(f"content_blocks={content_blocks}")
|
log.info(f"content_blocks={content_blocks}")
|
||||||
log.info(f"serialize_content_blocks={serialize_content_blocks(content_blocks)}")
|
log.info(
|
||||||
|
f"serialize_content_blocks={serialize_content_blocks(content_blocks)}"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = await generate_chat_completion(
|
res = await generate_chat_completion(
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
let pdfExtractImages = true;
|
let pdfExtractImages = true;
|
||||||
|
|
||||||
let RAG_FULL_CONTEXT = false;
|
let RAG_FULL_CONTEXT = false;
|
||||||
|
let BYPASS_EMBEDDING_AND_RETRIEVAL = false;
|
||||||
|
|
||||||
let enableGoogleDriveIntegration = false;
|
let enableGoogleDriveIntegration = false;
|
||||||
let enableOneDriveIntegration = false;
|
let enableOneDriveIntegration = false;
|
||||||
@ -170,12 +171,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
await embeddingModelUpdateHandler();
|
|
||||||
|
|
||||||
if (querySettings.hybrid) {
|
|
||||||
await rerankingModelUpdateHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentExtractionEngine === 'tika' && tikaServerUrl === '') {
|
if (contentExtractionEngine === 'tika' && tikaServerUrl === '') {
|
||||||
toast.error($i18n.t('Tika Server URL required.'));
|
toast.error($i18n.t('Tika Server URL required.'));
|
||||||
return;
|
return;
|
||||||
@ -187,6 +182,15 @@
|
|||||||
toast.error($i18n.t('Document Intelligence endpoint and key required.'));
|
toast.error($i18n.t('Document Intelligence endpoint and key required.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!BYPASS_EMBEDDING_AND_RETRIEVAL) {
|
||||||
|
await embeddingModelUpdateHandler();
|
||||||
|
|
||||||
|
if (querySettings.hybrid) {
|
||||||
|
await rerankingModelUpdateHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const res = await updateRAGConfig(localStorage.token, {
|
const res = await updateRAGConfig(localStorage.token, {
|
||||||
pdf_extract_images: pdfExtractImages,
|
pdf_extract_images: pdfExtractImages,
|
||||||
enable_google_drive_integration: enableGoogleDriveIntegration,
|
enable_google_drive_integration: enableGoogleDriveIntegration,
|
||||||
@ -196,6 +200,7 @@
|
|||||||
max_count: fileMaxCount === '' ? null : fileMaxCount
|
max_count: fileMaxCount === '' ? null : fileMaxCount
|
||||||
},
|
},
|
||||||
RAG_FULL_CONTEXT: RAG_FULL_CONTEXT,
|
RAG_FULL_CONTEXT: RAG_FULL_CONTEXT,
|
||||||
|
BYPASS_EMBEDDING_AND_RETRIEVAL: BYPASS_EMBEDDING_AND_RETRIEVAL,
|
||||||
chunk: {
|
chunk: {
|
||||||
text_splitter: textSplitter,
|
text_splitter: textSplitter,
|
||||||
chunk_overlap: chunkOverlap,
|
chunk_overlap: chunkOverlap,
|
||||||
@ -260,6 +265,7 @@
|
|||||||
chunkOverlap = res.chunk.chunk_overlap;
|
chunkOverlap = res.chunk.chunk_overlap;
|
||||||
|
|
||||||
RAG_FULL_CONTEXT = res.RAG_FULL_CONTEXT;
|
RAG_FULL_CONTEXT = res.RAG_FULL_CONTEXT;
|
||||||
|
BYPASS_EMBEDDING_AND_RETRIEVAL = res.BYPASS_EMBEDDING_AND_RETRIEVAL;
|
||||||
|
|
||||||
contentExtractionEngine = res.content_extraction.engine;
|
contentExtractionEngine = res.content_extraction.engine;
|
||||||
tikaServerUrl = res.content_extraction.tika_server_url;
|
tikaServerUrl = res.content_extraction.tika_server_url;
|
||||||
@ -328,9 +334,6 @@
|
|||||||
<select
|
<select
|
||||||
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
|
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
|
||||||
bind:value={contentExtractionEngine}
|
bind:value={contentExtractionEngine}
|
||||||
on:change={(e) => {
|
|
||||||
showDocumentIntelligenceConfig = e.target.value === 'document_intelligence';
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<option value="">{$i18n.t('Default')} </option>
|
<option value="">{$i18n.t('Default')} </option>
|
||||||
<option value="tika">{$i18n.t('Tika')}</option>
|
<option value="tika">{$i18n.t('Tika')}</option>
|
||||||
@ -375,6 +378,24 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<div class=" mb-2.5 flex w-full justify-between">
|
||||||
|
<div class=" self-center text-xs font-medium">
|
||||||
|
<Tooltip content={$i18n.t('Full Context Mode')} placement="top-start">
|
||||||
|
{$i18n.t('Bypass Embedding and Retrieval')}
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center relative">
|
||||||
|
<Tooltip
|
||||||
|
content={BYPASS_EMBEDDING_AND_RETRIEVAL
|
||||||
|
? 'Inject the entire content as context for comprehensive processing, this is recommended for complex queries.'
|
||||||
|
: 'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'}
|
||||||
|
>
|
||||||
|
<Switch bind:state={BYPASS_EMBEDDING_AND_RETRIEVAL} />
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if !BYPASS_EMBEDDING_AND_RETRIEVAL}
|
||||||
<div class=" mb-2.5 flex w-full justify-between">
|
<div class=" mb-2.5 flex w-full justify-between">
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Text Splitter')}</div>
|
<div class=" self-center text-xs font-medium">{$i18n.t('Text Splitter')}</div>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative">
|
||||||
@ -424,8 +445,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if !BYPASS_EMBEDDING_AND_RETRIEVAL}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Embedding')}</div>
|
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Embedding')}</div>
|
||||||
|
|
||||||
@ -433,7 +456,9 @@
|
|||||||
|
|
||||||
<div class=" mb-2.5 flex flex-col w-full justify-between">
|
<div class=" mb-2.5 flex flex-col w-full justify-between">
|
||||||
<div class="flex w-full justify-between">
|
<div class="flex w-full justify-between">
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Embedding Model Engine')}</div>
|
<div class=" self-center text-xs font-medium">
|
||||||
|
{$i18n.t('Embedding Model Engine')}
|
||||||
|
</div>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative">
|
||||||
<select
|
<select
|
||||||
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
|
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
|
||||||
@ -695,7 +720,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Query')}</div>
|
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Retrieval')}</div>
|
||||||
|
|
||||||
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
|
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
|
||||||
|
|
||||||
@ -756,6 +781,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Files')}</div>
|
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Files')}</div>
|
||||||
|
@ -118,14 +118,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" py-0.5 flex w-full justify-between">
|
<div class=" py-0.5 flex w-full justify-between">
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('Full Context Mode')}</div>
|
<div class=" self-center text-xs font-medium">
|
||||||
|
<Tooltip content={$i18n.t('Full Context Mode')} placement="top-start">
|
||||||
|
{$i18n.t('Bypass Embedding and Retrieval')}
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={webConfig.RAG_WEB_SEARCH_FULL_CONTEXT
|
content={webConfig.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL
|
||||||
? 'Inject the entire web results as context for comprehensive processing, this is recommended for complex queries.'
|
? 'Inject the entire content as context for comprehensive processing, this is recommended for complex queries.'
|
||||||
: 'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'}
|
: 'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'}
|
||||||
>
|
>
|
||||||
<Switch bind:state={webConfig.RAG_WEB_SEARCH_FULL_CONTEXT} />
|
<Switch bind:state={webConfig.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
|
console.log('sources', sources);
|
||||||
citations = sources.reduce((acc, source) => {
|
citations = sources.reduce((acc, source) => {
|
||||||
if (Object.keys(source).length === 0) {
|
if (Object.keys(source).length === 0) {
|
||||||
return acc;
|
return acc;
|
||||||
@ -53,7 +54,7 @@
|
|||||||
const distance = source.distances?.[index];
|
const distance = source.distances?.[index];
|
||||||
|
|
||||||
// Within the same citation there could be multiple documents
|
// Within the same citation there could be multiple documents
|
||||||
const id = metadata?.source ?? 'N/A';
|
const id = metadata?.source ?? source?.source?.id ?? 'N/A';
|
||||||
let _source = source?.source;
|
let _source = source?.source;
|
||||||
|
|
||||||
if (metadata?.name) {
|
if (metadata?.name) {
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={enableFullContent
|
content={enableFullContent
|
||||||
? 'Inject the entire document as context for comprehensive processing, this is recommended for complex queries.'
|
? 'Inject the entire content as context for comprehensive processing, this is recommended for complex queries.'
|
||||||
: 'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'}
|
: 'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'}
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-1.5 text-xs">
|
<div class="flex items-center gap-1.5 text-xs">
|
||||||
|
Loading…
Reference in New Issue
Block a user