Просмотр исходного кода

feat: Add custom API endpoint and user info headers for Perplexity Search (#31) (#19147)

Co-authored-by: Claude <noreply@anthropic.com>
Classic298 3 месяцев назад
Родитель
Сommit
ad17d35ac4

+ 6 - 0
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",

+ 2 - 0
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

+ 13 - 1
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

+ 8 - 0
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")

+ 20 - 0
src/lib/components/admin/Settings/WebSearch.svelte

@@ -150,6 +150,26 @@
 								</div>
 							</div>
 						{:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity_search'}
+							<div class="mb-2.5 flex w-full flex-col">
+								<div>
+									<div class=" self-center text-xs font-medium mb-1">
+										{$i18n.t('Perplexity Search API URL')}
+									</div>
+
+									<div class="flex w-full">
+										<div class="flex-1">
+											<input
+												class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden"
+												type="text"
+												placeholder={$i18n.t('Enter Perplexity Search API URL')}
+												bind:value={webConfig.PERPLEXITY_SEARCH_API_URL}
+												autocomplete="off"
+											/>
+										</div>
+									</div>
+								</div>
+							</div>
+
 							<div class="mb-2.5 flex w-full flex-col">
 								<div>
 									<div class=" self-center text-xs font-medium mb-1">