This commit is contained in:
Timothy Jaeryang Baek
2026-06-29 04:42:59 -05:00
parent a3b487422d
commit 67c9de8efd
3 changed files with 123 additions and 75 deletions

View File

@@ -38,6 +38,7 @@ from open_webui.models.config import Config
async def seed_registered_defaults():
await Config.rename_prefix('rag.web', 'web')
await Config.repair_flattened_dict_configs()
await Config.seed_defaults(DEFAULT_CONFIG)
@@ -1063,11 +1064,18 @@ YOUTUBE_LOADER_PROXY_URL = os.getenv('YOUTUBE_LOADER_PROXY_URL', '')
####################################
# Web Search (RAG)
# Web Search
####################################
ENABLE_WEB_SEARCH = os.getenv('ENABLE_WEB_SEARCH', 'False').lower() == 'true'
ENABLE_WEB_SEARCH_CONFIRMATION = os.getenv('ENABLE_WEB_SEARCH_CONFIRMATION', 'False').lower() == 'true'
WEB_SEARCH_CONFIRMATION_CONTENT = os.getenv(
'WEB_SEARCH_CONFIRMATION_CONTENT',
'Web Search may send your query and retrieved page content to external services.',
)
WEB_SEARCH_ENGINE = os.getenv('WEB_SEARCH_ENGINE', '')
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = os.getenv('BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL', 'False').lower() == 'true'
@@ -2764,77 +2772,79 @@ DEFAULT_CONFIG = {
'rag.ollama.api_key': RAG_OLLAMA_API_KEY,
'rag.youtube_loader_language': YOUTUBE_LOADER_LANGUAGE,
'rag.youtube_loader_proxy_url': YOUTUBE_LOADER_PROXY_URL,
'rag.web.search.enable': ENABLE_WEB_SEARCH,
'rag.web.search.engine': WEB_SEARCH_ENGINE,
'rag.web.search.bypass_embedding_and_retrieval': BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL,
'rag.web.search.bypass_web_loader': BYPASS_WEB_SEARCH_WEB_LOADER,
'rag.web.search.result_count': WEB_SEARCH_RESULT_COUNT,
'rag.web.search.domain.filter_list': WEB_SEARCH_DOMAIN_FILTER_LIST,
'rag.web.search.concurrent_requests': WEB_SEARCH_CONCURRENT_REQUESTS,
'rag.web.fetch.max_content_length': WEB_FETCH_MAX_CONTENT_LENGTH,
'rag.web.loader.engine': WEB_LOADER_ENGINE,
'rag.web.loader.concurrent_requests': WEB_LOADER_CONCURRENT_REQUESTS,
'rag.web.loader.timeout': WEB_LOADER_TIMEOUT,
'rag.web.loader.ssl_verification': ENABLE_WEB_LOADER_SSL_VERIFICATION,
'rag.web.search.trust_env': WEB_SEARCH_TRUST_ENV,
'rag.web.search.ollama_cloud_api_key': OLLAMA_CLOUD_WEB_SEARCH_API_KEY,
'rag.web.search.searxng_query_url': SEARXNG_QUERY_URL,
'rag.web.search.searxng_language': SEARXNG_LANGUAGE,
'rag.web.search.yacy_query_url': YACY_QUERY_URL,
'rag.web.search.yacy_username': YACY_USERNAME,
'rag.web.search.yacy_password': YACY_PASSWORD,
'rag.web.search.google_pse_api_key': GOOGLE_PSE_API_KEY,
'rag.web.search.google_pse_engine_id': GOOGLE_PSE_ENGINE_ID,
'rag.web.search.brave_search_api_key': BRAVE_SEARCH_API_KEY,
'rag.web.search.brave_search_context_tokens': BRAVE_SEARCH_CONTEXT_TOKENS,
'rag.web.search.kagi_search_api_key': KAGI_SEARCH_API_KEY,
'rag.web.search.mojeek_search_api_key': MOJEEK_SEARCH_API_KEY,
'rag.web.search.bocha_search_api_key': BOCHA_SEARCH_API_KEY,
'rag.web.search.serpstack_api_key': SERPSTACK_API_KEY,
'rag.web.search.serpstack_https': SERPSTACK_HTTPS,
'rag.web.search.serper_api_key': SERPER_API_KEY,
'rag.web.search.serply_api_key': SERPLY_API_KEY,
'rag.web.search.serphouse_api_key': SERPHOUSE_API_KEY,
'rag.web.search.serphouse_domain': SERPHOUSE_DOMAIN,
'rag.web.search.ddgs_backend': DDGS_BACKEND,
'rag.web.search.jina_api_key': JINA_API_KEY,
'rag.web.search.jina_api_base_url': JINA_API_BASE_URL,
'rag.web.search.searchapi_api_key': SEARCHAPI_API_KEY,
'rag.web.search.searchapi_engine': SEARCHAPI_ENGINE,
'rag.web.search.serpapi_api_key': SERPAPI_API_KEY,
'rag.web.search.serpapi_engine': SERPAPI_ENGINE,
'rag.web.search.bing_search_v7_endpoint': BING_SEARCH_V7_ENDPOINT,
'rag.web.search.bing_search_v7_subscription_key': BING_SEARCH_V7_SUBSCRIPTION_KEY,
'rag.web.search.azure_ai_search_api_key': AZURE_AI_SEARCH_API_KEY,
'rag.web.search.azure_ai_search_endpoint': AZURE_AI_SEARCH_ENDPOINT,
'rag.web.search.azure_ai_search_index_name': AZURE_AI_SEARCH_INDEX_NAME,
'rag.web.search.exa_api_key': EXA_API_KEY,
'rag.web.search.perplexity_api_key': PERPLEXITY_API_KEY,
'rag.web.search.perplexity_model': PERPLEXITY_MODEL,
'rag.web.search.perplexity_search_context_usage': PERPLEXITY_SEARCH_CONTEXT_USAGE,
'rag.web.search.perplexity_search_api_url': PERPLEXITY_SEARCH_API_URL,
'rag.web.search.microsoft_web_iq_api_base_url': MICROSOFT_WEB_IQ_API_BASE_URL,
'rag.web.search.microsoft_web_iq_api_key': MICROSOFT_WEB_IQ_API_KEY,
'rag.web.search.microsoft_web_iq_language': MICROSOFT_WEB_IQ_LANGUAGE,
'rag.web.search.sougou_api_sid': SOUGOU_API_SID,
'rag.web.search.sougou_api_sk': SOUGOU_API_SK,
'rag.web.search.tavily_api_key': TAVILY_API_KEY,
'rag.web.search.tavily_extract_depth': TAVILY_EXTRACT_DEPTH,
'rag.web.loader.playwright_ws_url': PLAYWRIGHT_WS_URL,
'rag.web.loader.playwright_timeout': PLAYWRIGHT_TIMEOUT,
'rag.web.loader.firecrawl_api_key': FIRECRAWL_API_KEY,
'rag.web.loader.firecrawl_api_url': FIRECRAWL_API_BASE_URL,
'rag.web.loader.firecrawl_timeout': FIRECRAWL_TIMEOUT,
'rag.web.search.external_web_search_url': EXTERNAL_WEB_SEARCH_URL,
'rag.web.search.external_web_search_api_key': EXTERNAL_WEB_SEARCH_API_KEY,
'rag.web.loader.external_web_loader_url': EXTERNAL_WEB_LOADER_URL,
'rag.web.loader.external_web_loader_api_key': EXTERNAL_WEB_LOADER_API_KEY,
'rag.web.search.yandex_web_search_url': YANDEX_WEB_SEARCH_URL,
'rag.web.search.yandex_web_search_api_key': YANDEX_WEB_SEARCH_API_KEY,
'rag.web.search.yandex_web_search_config': YANDEX_WEB_SEARCH_CONFIG,
'rag.web.search.youcom_api_key': YOUCOM_API_KEY,
'rag.web.search.linkup_api_key': LINKUP_API_KEY,
'rag.web.search.linkup_search_params': LINKUP_SEARCH_PARAMS,
'web.search.enable': ENABLE_WEB_SEARCH,
'web.search.confirmation.enable': ENABLE_WEB_SEARCH_CONFIRMATION,
'web.search.confirmation.content': WEB_SEARCH_CONFIRMATION_CONTENT,
'web.search.engine': WEB_SEARCH_ENGINE,
'web.search.bypass_embedding_and_retrieval': BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL,
'web.search.bypass_web_loader': BYPASS_WEB_SEARCH_WEB_LOADER,
'web.search.result_count': WEB_SEARCH_RESULT_COUNT,
'web.search.domain.filter_list': WEB_SEARCH_DOMAIN_FILTER_LIST,
'web.search.concurrent_requests': WEB_SEARCH_CONCURRENT_REQUESTS,
'web.fetch.max_content_length': WEB_FETCH_MAX_CONTENT_LENGTH,
'web.loader.engine': WEB_LOADER_ENGINE,
'web.loader.concurrent_requests': WEB_LOADER_CONCURRENT_REQUESTS,
'web.loader.timeout': WEB_LOADER_TIMEOUT,
'web.loader.ssl_verification': ENABLE_WEB_LOADER_SSL_VERIFICATION,
'web.search.trust_env': WEB_SEARCH_TRUST_ENV,
'web.search.ollama_cloud_api_key': OLLAMA_CLOUD_WEB_SEARCH_API_KEY,
'web.search.searxng_query_url': SEARXNG_QUERY_URL,
'web.search.searxng_language': SEARXNG_LANGUAGE,
'web.search.yacy_query_url': YACY_QUERY_URL,
'web.search.yacy_username': YACY_USERNAME,
'web.search.yacy_password': YACY_PASSWORD,
'web.search.google_pse_api_key': GOOGLE_PSE_API_KEY,
'web.search.google_pse_engine_id': GOOGLE_PSE_ENGINE_ID,
'web.search.brave_search_api_key': BRAVE_SEARCH_API_KEY,
'web.search.brave_search_context_tokens': BRAVE_SEARCH_CONTEXT_TOKENS,
'web.search.kagi_search_api_key': KAGI_SEARCH_API_KEY,
'web.search.mojeek_search_api_key': MOJEEK_SEARCH_API_KEY,
'web.search.bocha_search_api_key': BOCHA_SEARCH_API_KEY,
'web.search.serpstack_api_key': SERPSTACK_API_KEY,
'web.search.serpstack_https': SERPSTACK_HTTPS,
'web.search.serper_api_key': SERPER_API_KEY,
'web.search.serply_api_key': SERPLY_API_KEY,
'web.search.serphouse_api_key': SERPHOUSE_API_KEY,
'web.search.serphouse_domain': SERPHOUSE_DOMAIN,
'web.search.ddgs_backend': DDGS_BACKEND,
'web.search.jina_api_key': JINA_API_KEY,
'web.search.jina_api_base_url': JINA_API_BASE_URL,
'web.search.searchapi_api_key': SEARCHAPI_API_KEY,
'web.search.searchapi_engine': SEARCHAPI_ENGINE,
'web.search.serpapi_api_key': SERPAPI_API_KEY,
'web.search.serpapi_engine': SERPAPI_ENGINE,
'web.search.bing_search_v7_endpoint': BING_SEARCH_V7_ENDPOINT,
'web.search.bing_search_v7_subscription_key': BING_SEARCH_V7_SUBSCRIPTION_KEY,
'web.search.azure_ai_search_api_key': AZURE_AI_SEARCH_API_KEY,
'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.perplexity_api_key': PERPLEXITY_API_KEY,
'web.search.perplexity_model': PERPLEXITY_MODEL,
'web.search.perplexity_search_context_usage': PERPLEXITY_SEARCH_CONTEXT_USAGE,
'web.search.perplexity_search_api_url': PERPLEXITY_SEARCH_API_URL,
'web.search.microsoft_web_iq_api_base_url': MICROSOFT_WEB_IQ_API_BASE_URL,
'web.search.microsoft_web_iq_api_key': MICROSOFT_WEB_IQ_API_KEY,
'web.search.microsoft_web_iq_language': MICROSOFT_WEB_IQ_LANGUAGE,
'web.search.sougou_api_sid': SOUGOU_API_SID,
'web.search.sougou_api_sk': SOUGOU_API_SK,
'web.search.tavily_api_key': TAVILY_API_KEY,
'web.search.tavily_extract_depth': TAVILY_EXTRACT_DEPTH,
'web.loader.playwright_ws_url': PLAYWRIGHT_WS_URL,
'web.loader.playwright_timeout': PLAYWRIGHT_TIMEOUT,
'web.loader.firecrawl_api_key': FIRECRAWL_API_KEY,
'web.loader.firecrawl_api_url': FIRECRAWL_API_BASE_URL,
'web.loader.firecrawl_timeout': FIRECRAWL_TIMEOUT,
'web.search.external_web_search_url': EXTERNAL_WEB_SEARCH_URL,
'web.search.external_web_search_api_key': EXTERNAL_WEB_SEARCH_API_KEY,
'web.loader.external_web_loader_url': EXTERNAL_WEB_LOADER_URL,
'web.loader.external_web_loader_api_key': EXTERNAL_WEB_LOADER_API_KEY,
'web.search.yandex_web_search_url': YANDEX_WEB_SEARCH_URL,
'web.search.yandex_web_search_api_key': YANDEX_WEB_SEARCH_API_KEY,
'web.search.yandex_web_search_config': YANDEX_WEB_SEARCH_CONFIG,
'web.search.youcom_api_key': YOUCOM_API_KEY,
'web.search.linkup_api_key': LINKUP_API_KEY,
'web.search.linkup_search_params': LINKUP_SEARCH_PARAMS,
'image_generation.enable': ENABLE_IMAGE_GENERATION,
'image_generation.engine': IMAGE_GENERATION_ENGINE,
'image_generation.model': IMAGE_GENERATION_MODEL,

View File

@@ -1867,7 +1867,9 @@ async def get_app_config(request: Request):
'calendar.enable',
'automations.enable',
'notes.enable',
'rag.web.search.enable',
'web.search.enable',
'web.search.confirmation.enable',
'web.search.confirmation.content',
'code_execution.enable',
'code_interpreter.enable',
'image_generation.enable',
@@ -1933,7 +1935,9 @@ async def get_app_config(request: Request):
'enable_calendar': config.get('calendar.enable'),
'enable_automations': config.get('automations.enable'),
'enable_notes': config.get('notes.enable'),
'enable_web_search': config.get('rag.web.search.enable'),
'enable_web_search': config.get('web.search.enable'),
'enable_web_search_confirmation': config.get('web.search.confirmation.enable'),
'web_search_confirmation_content': config.get('web.search.confirmation.content'),
'enable_code_execution': config.get('code_execution.enable'),
'enable_code_interpreter': config.get('code_interpreter.enable'),
'enable_image_generation': config.get('image_generation.enable'),

View File

@@ -25,7 +25,7 @@ DICT_CONFIG_KEY_ALIASES = {
'ollama.api_configs': ('OLLAMA_API_CONFIGS',),
'rag.mineru_params': ('MINERU_PARAMS',),
'rag.docling_params': ('DOCLING_PARAMS',),
'rag.web.search.linkup_search_params': ('LINKUP_SEARCH_PARAMS',),
'web.search.linkup_search_params': ('LINKUP_SEARCH_PARAMS',),
'image_generation.automatic1111.api_params': ('AUTOMATIC1111_PARAMS',),
'image_generation.openai.params': ('IMAGES_OPENAI_API_PARAMS',),
'audio.tts.openai.params': ('AUDIO_TTS_OPENAI_PARAMS',),
@@ -240,6 +240,40 @@ class Config(Base):
await db.commit()
log.info('Seeded %d new config defaults', new_count)
@staticmethod
async def rename_prefix(old_prefix: str, new_prefix: str) -> None:
"""Move persisted config keys from one dotted prefix to another."""
if not Config.PERSISTENT_ENABLED:
return
async with get_async_db() as db:
result = await db.execute(select(Config).where(Config.key.like(f'{old_prefix}.%')))
rows = result.scalars().all()
if not rows:
return
now = int(time.time())
moved_count = 0
deleted_count = 0
for row in rows:
new_key = f'{new_prefix}.{row.key.removeprefix(f"{old_prefix}.")}'
existing = await db.get(Config, new_key)
if existing is None:
db.add(Config(key=new_key, value=row.value, updated_at=now))
moved_count += 1
else:
deleted_count += 1
await db.delete(row)
await db.commit()
log.info(
'Renamed %d config keys from %s.* to %s.*; deleted %d old duplicates',
moved_count,
old_prefix,
new_prefix,
deleted_count,
)
@staticmethod
async def repair_flattened_dict_configs() -> None:
"""Reassemble dict config values flattened by the per-key migration."""