mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-11 22:52:54 +00:00
refac
This commit is contained in:
parent
31b272d3c9
commit
12b14124b9
4 changed files with 43 additions and 27 deletions
|
|
@ -1271,6 +1271,9 @@ AZURE_AI_SEARCH_ENDPOINT = os.getenv('AZURE_AI_SEARCH_ENDPOINT', '')
|
|||
AZURE_AI_SEARCH_INDEX_NAME = os.getenv('AZURE_AI_SEARCH_INDEX_NAME', '')
|
||||
|
||||
EXA_API_KEY = os.getenv('EXA_API_KEY', '')
|
||||
EXA_MAX_CONTENT_LENGTH = int(os.environ['EXA_MAX_CONTENT_LENGTH']) if os.getenv('EXA_MAX_CONTENT_LENGTH') else None
|
||||
if EXA_MAX_CONTENT_LENGTH is not None and EXA_MAX_CONTENT_LENGTH <= 0:
|
||||
raise ValueError('EXA_MAX_CONTENT_LENGTH must be a positive integer or unset')
|
||||
|
||||
PERPLEXITY_API_KEY = os.getenv('PERPLEXITY_API_KEY', '')
|
||||
|
||||
|
|
@ -3001,6 +3004,7 @@ DEFAULT_CONFIG = {
|
|||
'web.search.azure_ai_search_endpoint': AZURE_AI_SEARCH_ENDPOINT,
|
||||
'web.search.azure_ai_search_index_name': AZURE_AI_SEARCH_INDEX_NAME,
|
||||
'web.search.exa_api_key': EXA_API_KEY,
|
||||
'web.search.exa_max_content_length': EXA_MAX_CONTENT_LENGTH,
|
||||
'web.search.perplexity_api_key': PERPLEXITY_API_KEY,
|
||||
'web.search.perplexity_model': PERPLEXITY_MODEL,
|
||||
'web.search.perplexity_search_context_usage': PERPLEXITY_SEARCH_CONTEXT_USAGE,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
from open_webui.retrieval.web.main import SearchResult
|
||||
|
|
@ -10,18 +8,12 @@ log = logging.getLogger(__name__)
|
|||
EXA_API_BASE = 'https://api.exa.ai'
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExaResult:
|
||||
url: str
|
||||
title: str
|
||||
text: str
|
||||
|
||||
|
||||
def search_exa(
|
||||
api_key: str,
|
||||
query: str,
|
||||
count: int,
|
||||
filter_list: Optional[list[str]] = None,
|
||||
filter_list: list[str] | None = None,
|
||||
max_content_length: int | None = None,
|
||||
) -> list[SearchResult]:
|
||||
"""Search using Exa Search API and return the results as a list of SearchResult objects.
|
||||
|
||||
|
|
@ -29,7 +21,8 @@ def search_exa(
|
|||
api_key (str): A Exa Search API key
|
||||
query (str): The query to search for
|
||||
count (int): Number of results to return
|
||||
filter_list (Optional[list[str]]): List of domains to filter results by
|
||||
filter_list (list[str] | None): List of domains to filter results by
|
||||
max_content_length (int | None): Maximum characters per result; None leaves text unlimited.
|
||||
"""
|
||||
log.info('Searching with Exa for query: %s', query)
|
||||
|
||||
|
|
@ -39,7 +32,7 @@ def search_exa(
|
|||
'query': query,
|
||||
'numResults': count or 5,
|
||||
'includeDomains': filter_list,
|
||||
'contents': {'text': True, 'highlights': True},
|
||||
'contents': {'text': {'maxCharacters': max_content_length} if max_content_length is not None else True},
|
||||
'type': 'auto', # Use the auto search type (keyword or neural)
|
||||
}
|
||||
|
||||
|
|
@ -48,22 +41,13 @@ def search_exa(
|
|||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
results = []
|
||||
for result in data['results']:
|
||||
results.append(
|
||||
ExaResult(
|
||||
url=result['url'],
|
||||
title=result['title'],
|
||||
text=result['text'],
|
||||
)
|
||||
)
|
||||
|
||||
results = data['results']
|
||||
log.info('Found %s results', len(results))
|
||||
return [
|
||||
SearchResult(
|
||||
link=result.url,
|
||||
title=result.title,
|
||||
snippet=result.text,
|
||||
link=result['url'],
|
||||
title=result['title'],
|
||||
snippet=(result.get('text') or '')[:max_content_length],
|
||||
)
|
||||
for result in results
|
||||
]
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ from open_webui.utils.misc import (
|
|||
calculate_sha256_string,
|
||||
sanitize_text_for_db,
|
||||
)
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
@ -297,6 +297,7 @@ RETRIEVAL_CONFIG_KEYS = {
|
|||
'ENABLE_WEB_SEARCH_CONFIRMATION': 'web.search.confirmation.enable',
|
||||
'WEB_SEARCH_CONFIRMATION_CONTENT': 'web.search.confirmation.content',
|
||||
'EXA_API_KEY': 'web.search.exa_api_key',
|
||||
'EXA_MAX_CONTENT_LENGTH': 'web.search.exa_max_content_length',
|
||||
'EXTERNAL_DOCUMENT_LOADER_API_KEY': 'rag.external_document_loader_api_key',
|
||||
'EXTERNAL_DOCUMENT_LOADER_HEADERS': 'rag.external_document_loader_headers',
|
||||
'EXTERNAL_DOCUMENT_LOADER_URL': 'rag.external_document_loader_url',
|
||||
|
|
@ -745,6 +746,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
|
|||
'BING_SEARCH_V7_ENDPOINT': config.BING_SEARCH_V7_ENDPOINT,
|
||||
'BING_SEARCH_V7_SUBSCRIPTION_KEY': config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
|
||||
'EXA_API_KEY': config.EXA_API_KEY,
|
||||
'EXA_MAX_CONTENT_LENGTH': config.EXA_MAX_CONTENT_LENGTH,
|
||||
'PERPLEXITY_API_KEY': config.PERPLEXITY_API_KEY,
|
||||
'PERPLEXITY_MODEL': config.PERPLEXITY_MODEL,
|
||||
'PERPLEXITY_SEARCH_CONTEXT_USAGE': config.PERPLEXITY_SEARCH_CONTEXT_USAGE,
|
||||
|
|
@ -824,6 +826,7 @@ class WebConfig(BaseModel):
|
|||
BING_SEARCH_V7_ENDPOINT: str | None = None
|
||||
BING_SEARCH_V7_SUBSCRIPTION_KEY: str | None = None
|
||||
EXA_API_KEY: str | None = None
|
||||
EXA_MAX_CONTENT_LENGTH: int | None = Field(default=None, gt=0, strict=True)
|
||||
PERPLEXITY_API_KEY: str | None = None
|
||||
PERPLEXITY_MODEL: str | None = None
|
||||
PERPLEXITY_SEARCH_CONTEXT_USAGE: str | None = None
|
||||
|
|
@ -1342,6 +1345,7 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend
|
|||
config.BING_SEARCH_V7_ENDPOINT = form_data.web.BING_SEARCH_V7_ENDPOINT
|
||||
config.BING_SEARCH_V7_SUBSCRIPTION_KEY = form_data.web.BING_SEARCH_V7_SUBSCRIPTION_KEY
|
||||
config.EXA_API_KEY = form_data.web.EXA_API_KEY
|
||||
config.EXA_MAX_CONTENT_LENGTH = form_data.web.EXA_MAX_CONTENT_LENGTH
|
||||
config.PERPLEXITY_API_KEY = form_data.web.PERPLEXITY_API_KEY
|
||||
config.PERPLEXITY_MODEL = form_data.web.PERPLEXITY_MODEL
|
||||
config.PERPLEXITY_SEARCH_CONTEXT_USAGE = form_data.web.PERPLEXITY_SEARCH_CONTEXT_USAGE
|
||||
|
|
@ -1494,6 +1498,7 @@ async def update_rag_config(request: Request, form_data: ConfigForm, user=Depend
|
|||
'BING_SEARCH_V7_ENDPOINT': config.BING_SEARCH_V7_ENDPOINT,
|
||||
'BING_SEARCH_V7_SUBSCRIPTION_KEY': config.BING_SEARCH_V7_SUBSCRIPTION_KEY,
|
||||
'EXA_API_KEY': config.EXA_API_KEY,
|
||||
'EXA_MAX_CONTENT_LENGTH': config.EXA_MAX_CONTENT_LENGTH,
|
||||
'PERPLEXITY_API_KEY': config.PERPLEXITY_API_KEY,
|
||||
'PERPLEXITY_MODEL': config.PERPLEXITY_MODEL,
|
||||
'PERPLEXITY_SEARCH_CONTEXT_USAGE': config.PERPLEXITY_SEARCH_CONTEXT_USAGE,
|
||||
|
|
@ -2691,6 +2696,7 @@ async def search_web(request: Request, engine: str, query: str, user=None) -> li
|
|||
query,
|
||||
config.WEB_SEARCH_RESULT_COUNT,
|
||||
config.WEB_SEARCH_DOMAIN_FILTER_LIST,
|
||||
max_content_length=config.EXA_MAX_CONTENT_LENGTH,
|
||||
)
|
||||
else:
|
||||
raise Exception('No EXA_API_KEY found in environment variables')
|
||||
|
|
|
|||
|
|
@ -98,7 +98,11 @@
|
|||
: (webConfig.LINKUP_SEARCH_PARAMS ?? {});
|
||||
|
||||
const res = await updateRAGConfig(localStorage.token, {
|
||||
web: { ...webConfig, LINKUP_SEARCH_PARAMS: linkupParams }
|
||||
web: {
|
||||
...webConfig,
|
||||
EXA_MAX_CONTENT_LENGTH: webConfig.EXA_MAX_CONTENT_LENGTH ?? null,
|
||||
LINKUP_SEARCH_PARAMS: linkupParams
|
||||
}
|
||||
});
|
||||
|
||||
// Convert arrays back to strings for display
|
||||
|
|
@ -711,6 +715,24 @@
|
|||
bind:value={webConfig.EXA_API_KEY}
|
||||
/>
|
||||
</div>
|
||||
<AdminSettingField
|
||||
className="mt-1.5"
|
||||
label={$i18n.t('Max Content Length')}
|
||||
forId="exa-max-content-length"
|
||||
description={$i18n.t(
|
||||
'Maximum characters per Exa search result. Leave empty for no limit.'
|
||||
)}
|
||||
>
|
||||
<input
|
||||
id="exa-max-content-length"
|
||||
class={inputClass}
|
||||
type="number"
|
||||
min="1"
|
||||
step="1"
|
||||
placeholder={$i18n.t('No limit')}
|
||||
bind:value={webConfig.EXA_MAX_CONTENT_LENGTH}
|
||||
/>
|
||||
</AdminSettingField>
|
||||
</div>
|
||||
{:else if webConfig.WEB_SEARCH_ENGINE === 'perplexity'}
|
||||
<div class="mb-2.5 flex w-full flex-col">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue