88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
		
		
			
		
	
	
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
|  | import logging | ||
|  | from typing import Optional, List | ||
|  | import requests | ||
|  | 
 | ||
|  | from open_webui.retrieval.web.main import SearchResult, get_filtered_results | ||
|  | from open_webui.env import SRC_LOG_LEVELS | ||
|  | 
 | ||
|  | log = logging.getLogger(__name__) | ||
|  | log.setLevel(SRC_LOG_LEVELS["RAG"]) | ||
|  | 
 | ||
|  | 
 | ||
|  | def search_perplexity( | ||
|  |     api_key: str, | ||
|  |     query: str, | ||
|  |     count: int, | ||
|  |     filter_list: Optional[list[str]] = None, | ||
|  | ) -> list[SearchResult]: | ||
|  |     """Search using Perplexity API and return the results as a list of SearchResult objects.
 | ||
|  | 
 | ||
|  |     Args: | ||
|  |       api_key (str): A Perplexity API key | ||
|  |       query (str): The query to search for | ||
|  |       count (int): Maximum number of results to return | ||
|  | 
 | ||
|  |     """
 | ||
|  | 
 | ||
|  |     # Handle PersistentConfig object | ||
|  |     if hasattr(api_key, "__str__"): | ||
|  |         api_key = str(api_key) | ||
|  | 
 | ||
|  |     try: | ||
|  |         url = "https://api.perplexity.ai/chat/completions" | ||
|  | 
 | ||
|  |         # Create payload for the API call | ||
|  |         payload = { | ||
|  |             "model": "sonar", | ||
|  |             "messages": [ | ||
|  |                 { | ||
|  |                     "role": "system", | ||
|  |                     "content": "You are a search assistant. Provide factual information with citations.", | ||
|  |                 }, | ||
|  |                 {"role": "user", "content": query}, | ||
|  |             ], | ||
|  |             "temperature": 0.2,  # Lower temperature for more factual responses | ||
|  |             "stream": False, | ||
|  |         } | ||
|  | 
 | ||
|  |         headers = { | ||
|  |             "Authorization": f"Bearer {api_key}", | ||
|  |             "Content-Type": "application/json", | ||
|  |         } | ||
|  | 
 | ||
|  |         # Make the API request | ||
|  |         response = requests.request("POST", url, json=payload, headers=headers) | ||
|  | 
 | ||
|  |         # Parse the JSON response | ||
|  |         json_response = response.json() | ||
|  | 
 | ||
|  |         # Extract citations from the response | ||
|  |         citations = json_response.get("citations", []) | ||
|  | 
 | ||
|  |         # Create search results from citations | ||
|  |         results = [] | ||
|  |         for i, citation in enumerate(citations[:count]): | ||
|  |             # Extract content from the response to use as snippet | ||
|  |             content = "" | ||
|  |             if "choices" in json_response and json_response["choices"]: | ||
|  |                 if i == 0: | ||
|  |                     content = json_response["choices"][0]["message"]["content"] | ||
|  | 
 | ||
|  |             result = {"link": citation, "title": f"Source {i+1}", "snippet": content} | ||
|  |             results.append(result) | ||
|  | 
 | ||
|  |         if filter_list: | ||
|  | 
 | ||
|  |             results = get_filtered_results(results, filter_list) | ||
|  | 
 | ||
|  |         return [ | ||
|  |             SearchResult( | ||
|  |                 link=result["link"], title=result["title"], snippet=result["snippet"] | ||
|  |             ) | ||
|  |             for result in results[:count] | ||
|  |         ] | ||
|  | 
 | ||
|  |     except Exception as e: | ||
|  |         log.error(f"Error searching with Perplexity API: {e}") | ||
|  |         return [] |