diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 42bcaab429..4656ce5258 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -3006,6 +3006,12 @@ PERPLEXITY_SEARCH_CONTEXT_USAGE = PersistentConfig( os.getenv("PERPLEXITY_SEARCH_CONTEXT_USAGE", "medium"), ) +PERPLEXITY_SEARCH_API_URL = PersistentConfig( + "PERPLEXITY_SEARCH_API_URL", + "rag.web.search.perplexity_search_api_url", + os.getenv("PERPLEXITY_SEARCH_API_URL", "https://api.perplexity.ai/search"), +) + SOUGOU_API_SID = PersistentConfig( "SOUGOU_API_SID", "rag.web.search.sougou_api_sid", diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index f0aeeab02a..6682e5e72d 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -319,6 +319,7 @@ from open_webui.config import ( PERPLEXITY_API_KEY, PERPLEXITY_MODEL, PERPLEXITY_SEARCH_CONTEXT_USAGE, + PERPLEXITY_SEARCH_API_URL, SOUGOU_API_SID, SOUGOU_API_SK, KAGI_SEARCH_API_KEY, @@ -958,6 +959,7 @@ app.state.config.EXA_API_KEY = EXA_API_KEY app.state.config.PERPLEXITY_API_KEY = PERPLEXITY_API_KEY app.state.config.PERPLEXITY_MODEL = PERPLEXITY_MODEL app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = PERPLEXITY_SEARCH_CONTEXT_USAGE +app.state.config.PERPLEXITY_SEARCH_API_URL = PERPLEXITY_SEARCH_API_URL app.state.config.SOUGOU_API_SID = SOUGOU_API_SID app.state.config.SOUGOU_API_SK = SOUGOU_API_SK app.state.config.EXTERNAL_WEB_SEARCH_URL = EXTERNAL_WEB_SEARCH_URL diff --git a/backend/open_webui/retrieval/web/perplexity_search.py b/backend/open_webui/retrieval/web/perplexity_search.py index e3e0caa2b3..97961f478b 100644 --- a/backend/open_webui/retrieval/web/perplexity_search.py +++ b/backend/open_webui/retrieval/web/perplexity_search.py @@ -3,6 +3,7 @@ from typing import Optional, Literal import requests from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.utils.headers import include_user_info_headers from open_webui.env import SRC_LOG_LEVELS @@ -15,6 +16,8 @@ def search_perplexity_search( query: str, count: int, filter_list: Optional[list[str]] = None, + api_url: str = "https://api.perplexity.ai/search", + user=None, ) -> list[SearchResult]: """Search using Perplexity API and return the results as a list of SearchResult objects. @@ -23,6 +26,8 @@ def search_perplexity_search( query (str): The query to search for count (int): Maximum number of results to return filter_list (Optional[list[str]]): List of domains to filter results + api_url (str): Custom API URL (defaults to https://api.perplexity.ai/search) + user: Optional user object for forwarding user info headers """ @@ -30,8 +35,11 @@ def search_perplexity_search( if hasattr(api_key, "__str__"): api_key = str(api_key) + if hasattr(api_url, "__str__"): + api_url = str(api_url) + try: - url = "https://api.perplexity.ai/search" + url = api_url # Create payload for the API call payload = { @@ -44,6 +52,10 @@ def search_perplexity_search( "Content-Type": "application/json", } + # Forward user info headers if user is provided + if user is not None: + headers = include_user_info_headers(headers, user) + # Make the API request response = requests.request("POST", url, json=payload, headers=headers) # Parse the JSON response diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py index d57151b509..e98e0c226e 100644 --- a/backend/open_webui/routers/retrieval.py +++ b/backend/open_webui/routers/retrieval.py @@ -528,6 +528,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)): "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, "PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL, "PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE, + "PERPLEXITY_SEARCH_API_URL": request.app.state.config.PERPLEXITY_SEARCH_API_URL, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, @@ -585,6 +586,7 @@ class WebConfig(BaseModel): PERPLEXITY_API_KEY: Optional[str] = None PERPLEXITY_MODEL: Optional[str] = None PERPLEXITY_SEARCH_CONTEXT_USAGE: Optional[str] = None + PERPLEXITY_SEARCH_API_URL: Optional[str] = None SOUGOU_API_SID: Optional[str] = None SOUGOU_API_SK: Optional[str] = None WEB_LOADER_ENGINE: Optional[str] = None @@ -1108,6 +1110,9 @@ async def update_rag_config( request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE = ( form_data.web.PERPLEXITY_SEARCH_CONTEXT_USAGE ) + request.app.state.config.PERPLEXITY_SEARCH_API_URL = ( + form_data.web.PERPLEXITY_SEARCH_API_URL + ) request.app.state.config.SOUGOU_API_SID = form_data.web.SOUGOU_API_SID request.app.state.config.SOUGOU_API_SK = form_data.web.SOUGOU_API_SK @@ -1253,6 +1258,7 @@ async def update_rag_config( "PERPLEXITY_API_KEY": request.app.state.config.PERPLEXITY_API_KEY, "PERPLEXITY_MODEL": request.app.state.config.PERPLEXITY_MODEL, "PERPLEXITY_SEARCH_CONTEXT_USAGE": request.app.state.config.PERPLEXITY_SEARCH_CONTEXT_USAGE, + "PERPLEXITY_SEARCH_API_URL": request.app.state.config.PERPLEXITY_SEARCH_API_URL, "SOUGOU_API_SID": request.app.state.config.SOUGOU_API_SID, "SOUGOU_API_SK": request.app.state.config.SOUGOU_API_SK, "WEB_LOADER_ENGINE": request.app.state.config.WEB_LOADER_ENGINE, @@ -1852,6 +1858,8 @@ def search_web( query, request.app.state.config.WEB_SEARCH_RESULT_COUNT, request.app.state.config.WEB_SEARCH_DOMAIN_FILTER_LIST, + request.app.state.config.PERPLEXITY_SEARCH_API_URL, + user, ) else: raise Exception("No PERPLEXITY_API_KEY found in environment variables") diff --git a/src/lib/components/admin/Settings/WebSearch.svelte b/src/lib/components/admin/Settings/WebSearch.svelte index e7325cb582..4134bcd018 100644 --- a/src/lib/components/admin/Settings/WebSearch.svelte +++ b/src/lib/components/admin/Settings/WebSearch.svelte @@ -150,6 +150,26 @@ {:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity_search'} +