From 9a638b3ad58995bfe7a28c11ae6a5ec7b91f22f6 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 20 Aug 2026 22:06:20 +0200 Subject: [PATCH] refactor: drop the unused synchronous batch embedding helpers Every batch embedding provider in the retrieval layer exists twice, once synchronous and once asynchronous. Only the asynchronous versions are reachable: the single entry point that all embedding paths go through awaits those. The synchronous copies have no caller anywhere in the tree and were kept looking alive only by their own log lines. This removes around 110 lines of duplicated request handling for OpenAI, Azure OpenAI and Ollama, so there is one implementation per provider instead of two that can silently drift apart. Nothing called the removed code, so behaviour is unchanged. Two log lines in the Ollama router named functions that no longer exist and now name the endpoints they sit in. One thing worth knowing before this lands: the removed Azure helper was the only code in the tree that backed off on a 429 with Retry-After. The live asynchronous path raises instead. That gap is not new, but the deletion takes away the last worked example of it. --- backend/open_webui/retrieval/utils.py | 112 -------------------------- backend/open_webui/routers/ollama.py | 4 +- 2 files changed, 2 insertions(+), 114 deletions(-) diff --git a/backend/open_webui/retrieval/utils.py b/backend/open_webui/retrieval/utils.py index ed53c35db5..31de9aa5bc 100644 --- a/backend/open_webui/retrieval/utils.py +++ b/backend/open_webui/retrieval/utils.py @@ -5,7 +5,6 @@ import hashlib import logging import os import re -import time from typing import Awaitable, Optional, Union from urllib.parse import quote @@ -856,39 +855,6 @@ async def query_collection_with_hybrid_search( return merge_and_sort_query_results(results, k=k) -def generate_openai_batch_embeddings( - model: str, - texts: list[str], - url: str = 'https://api.openai.com/v1', - key: str = '', - prefix: str = None, - user: UserModel = None, -) -> list[list[float]]: - log.debug('generate_openai_batch_embeddings:model %s batch size: %s', model, len(texts)) - json_data = {'input': texts, 'model': model} - if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str): - json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix - - headers = { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {key}', - } - if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) - - r = requests.post( - f'{url}/embeddings', - headers=headers, - json=json_data, - ) - r.raise_for_status() - data = r.json() - if 'data' in data: - return [elem['embedding'] for elem in data['data']] - else: - raise ValueError("Unexpected OpenAI embeddings response: missing 'data' key") - - async def agenerate_openai_batch_embeddings( model: str, texts: list[str], @@ -926,48 +892,6 @@ async def agenerate_openai_batch_embeddings( raise ValueError("Unexpected OpenAI embeddings response: missing 'data' key") -def generate_azure_openai_batch_embeddings( - model: str, - texts: list[str], - url: str, - key: str = '', - version: str = '', - prefix: str = None, - user: UserModel = None, -) -> list[list[float]]: - log.debug('generate_azure_openai_batch_embeddings:deployment %s batch size: %s', model, len(texts)) - json_data = {'input': texts} - if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str): - json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix - - url = f'{url}/openai/deployments/{model}/embeddings?api-version={version}' - - for _ in range(5): - headers = { - 'Content-Type': 'application/json', - 'api-key': key, - } - if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) - - r = requests.post( - url, - headers=headers, - json=json_data, - ) - if r.status_code == 429: - retry = float(r.headers.get('Retry-After', '1')) - time.sleep(retry) - continue - r.raise_for_status() - data = r.json() - if 'data' in data: - return [elem['embedding'] for elem in data['data']] - else: - raise ValueError("Unexpected Azure OpenAI embeddings response: missing 'data' key") - raise Exception('Azure OpenAI embedding request failed: max retries (429) exceeded') - - async def agenerate_azure_openai_batch_embeddings( model: str, texts: list[str], @@ -1008,42 +932,6 @@ async def agenerate_azure_openai_batch_embeddings( raise ValueError("Unexpected Azure OpenAI embeddings response: missing 'data' key") -def generate_ollama_batch_embeddings( - model: str, - texts: list[str], - url: str, - key: str = '', - prefix: str = None, - user: UserModel = None, -) -> list[list[float]]: - log.debug('generate_ollama_batch_embeddings:model %s batch size: %s', model, len(texts)) - json_data = {'input': texts, 'model': model, 'truncate': True} - if isinstance(RAG_EMBEDDING_PREFIX_FIELD_NAME, str) and isinstance(prefix, str): - json_data[RAG_EMBEDDING_PREFIX_FIELD_NAME] = prefix - - headers = { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {key}', - } - if ENABLE_FORWARD_USER_INFO_HEADERS and user: - headers = include_user_info_headers(headers, user) - - r = requests.post( - f'{url}/api/embed', - headers=headers, - json=json_data, - ) - if r.status_code != 200: - error_detail = r.json().get('error', r.text) - raise Exception(f'Ollama embed error ({r.status_code}): {error_detail}') - data = r.json() - - if 'embeddings' in data: - return data['embeddings'] - else: - raise ValueError("Unexpected Ollama embeddings response: missing 'embeddings' key") - - async def agenerate_ollama_batch_embeddings( model: str, texts: list[str], diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py index dfb01e4eaf..d592b903c6 100644 --- a/backend/open_webui/routers/ollama.py +++ b/backend/open_webui/routers/ollama.py @@ -881,7 +881,7 @@ async def embed( if not await Config.get('ollama.enable'): raise HTTPException(status_code=503, detail=ERROR_MESSAGES.OLLAMA_API_DISABLED) - log.info('generate_ollama_batch_embeddings %s', form_data) + log.info('embed %s', form_data) await check_model_access(user, await Models.get_model_by_id(form_data.model), BYPASS_MODEL_ACCESS_CONTROL) await validate_ollama_backend_idx(request, form_data.model, url_idx, user) @@ -932,7 +932,7 @@ async def embeddings( if not await Config.get('ollama.enable'): raise HTTPException(status_code=503, detail=ERROR_MESSAGES.OLLAMA_API_DISABLED) - log.info('generate_ollama_embeddings %s', form_data) + log.info('embeddings %s', form_data) await check_model_access(user, await Models.get_model_by_id(form_data.model), BYPASS_MODEL_ACCESS_CONTROL) await validate_ollama_backend_idx(request, form_data.model, url_idx, user)