Merge branch 'open-webui:main' into main

This commit is contained in:
Jarrod Lowe
2025-04-17 15:46:24 +12:00
committed by GitHub
118 changed files with 5187 additions and 3201 deletions

View File

@@ -330,7 +330,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
detail = f"External: {e}"
raise HTTPException(
status_code=getattr(r, "status", 500),
status_code=getattr(r, "status", 500) if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)
@@ -384,7 +384,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
detail = f"External: {e}"
raise HTTPException(
status_code=getattr(r, "status", 500),
status_code=getattr(r, "status", 500) if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)
@@ -440,7 +440,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
detail = f"External: {e}"
raise HTTPException(
status_code=getattr(r, "status", 500),
status_code=getattr(r, "status", 500) if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)
@@ -497,7 +497,11 @@ def transcribe(request: Request, file_path):
)
model = request.app.state.faster_whisper_model
segments, info = model.transcribe(file_path, beam_size=5)
segments, info = model.transcribe(
file_path,
beam_size=5,
vad_filter=request.app.state.config.WHISPER_VAD_FILTER,
)
log.info(
"Detected language '%s' with probability %f"
% (info.language, info.language_probability)
@@ -624,10 +628,7 @@ def transcribe(request: Request, file_path):
elif request.app.state.config.STT_ENGINE == "azure":
# Check file exists and size
if not os.path.exists(file_path):
raise HTTPException(
status_code=400,
detail="Audio file not found"
)
raise HTTPException(status_code=400, detail="Audio file not found")
# Check file size (Azure has a larger limit of 200MB)
file_size = os.path.getsize(file_path)
@@ -643,11 +644,22 @@ def transcribe(request: Request, file_path):
# IF NO LOCALES, USE DEFAULTS
if len(locales) < 2:
locales = ['en-US', 'es-ES', 'es-MX', 'fr-FR', 'hi-IN',
'it-IT','de-DE', 'en-GB', 'en-IN', 'ja-JP',
'ko-KR', 'pt-BR', 'zh-CN']
locales = ','.join(locales)
locales = [
"en-US",
"es-ES",
"es-MX",
"fr-FR",
"hi-IN",
"it-IT",
"de-DE",
"en-GB",
"en-IN",
"ja-JP",
"ko-KR",
"pt-BR",
"zh-CN",
]
locales = ",".join(locales)
if not api_key or not region:
raise HTTPException(
@@ -658,22 +670,26 @@ def transcribe(request: Request, file_path):
r = None
try:
# Prepare the request
data = {'definition': json.dumps({
"locales": locales.split(','),
"diarization": {"maxSpeakers": 3,"enabled": True}
} if locales else {}
)
data = {
"definition": json.dumps(
{
"locales": locales.split(","),
"diarization": {"maxSpeakers": 3, "enabled": True},
}
if locales
else {}
)
}
url = f"https://{region}.api.cognitive.microsoft.com/speechtotext/transcriptions:transcribe?api-version=2024-11-15"
# Use context manager to ensure file is properly closed
with open(file_path, 'rb') as audio_file:
with open(file_path, "rb") as audio_file:
r = requests.post(
url=url,
files={'audio': audio_file},
files={"audio": audio_file},
data=data,
headers={
'Ocp-Apim-Subscription-Key': api_key,
"Ocp-Apim-Subscription-Key": api_key,
},
)
@@ -681,11 +697,11 @@ def transcribe(request: Request, file_path):
response = r.json()
# Extract transcript from response
if not response.get('combinedPhrases'):
if not response.get("combinedPhrases"):
raise ValueError("No transcription found in response")
# Get the full transcript from combinedPhrases
transcript = response['combinedPhrases'][0].get('text', '').strip()
transcript = response["combinedPhrases"][0].get("text", "").strip()
if not transcript:
raise ValueError("Empty transcript in response")
@@ -718,7 +734,7 @@ def transcribe(request: Request, file_path):
detail = f"External: {e}"
raise HTTPException(
status_code=getattr(r, 'status_code', 500) if r else 500,
status_code=getattr(r, "status_code", 500) if r else 500,
detail=detail if detail else "Open WebUI: Server Connection Error",
)

View File

@@ -231,13 +231,15 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
entry = connection_app.entries[0]
username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower()
email = entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]
email = entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"].value # retrive the Attribute value
if not email:
raise HTTPException(400, "User does not have a valid email address.")
elif isinstance(email, str):
email = email.lower()
elif isinstance(email, list):
email = email[0].lower()
else:
email = str(email).lower()
cn = str(entry["cn"])
user_dn = entry.entry_dn

View File

@@ -579,7 +579,12 @@ async def clone_chat_by_id(
@router.post("/{id}/clone/shared", response_model=Optional[ChatResponse])
async def clone_shared_chat_by_id(id: str, user=Depends(get_verified_user)):
chat = Chats.get_chat_by_share_id(id)
if user.role == "admin":
chat = Chats.get_chat_by_id(id)
else:
chat = Chats.get_chat_by_share_id(id)
if chat:
updated_chat = {
**chat.chat,

View File

@@ -159,7 +159,6 @@ async def create_new_knowledge(
status_code=status.HTTP_400_BAD_REQUEST,
detail=ERROR_MESSAGES.FILE_EXISTS,
)
############################
@@ -168,20 +167,17 @@ async def create_new_knowledge(
@router.post("/reindex", response_model=bool)
async def reindex_knowledge_files(
request: Request,
user=Depends(get_verified_user)
):
async def reindex_knowledge_files(request: Request, user=Depends(get_verified_user)):
if user.role != "admin":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.UNAUTHORIZED,
)
knowledge_bases = Knowledges.get_knowledge_bases()
log.info(f"Starting reindexing for {len(knowledge_bases)} knowledge bases")
for knowledge_base in knowledge_bases:
try:
files = Files.get_files_by_ids(knowledge_base.data.get("file_ids", []))
@@ -195,34 +191,40 @@ async def reindex_knowledge_files(
log.error(f"Error deleting collection {knowledge_base.id}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error deleting vector DB collection"
detail=f"Error deleting vector DB collection",
)
failed_files = []
for file in files:
try:
process_file(
request,
ProcessFileForm(file_id=file.id, collection_name=knowledge_base.id),
ProcessFileForm(
file_id=file.id, collection_name=knowledge_base.id
),
user=user,
)
except Exception as e:
log.error(f"Error processing file {file.filename} (ID: {file.id}): {str(e)}")
log.error(
f"Error processing file {file.filename} (ID: {file.id}): {str(e)}"
)
failed_files.append({"file_id": file.id, "error": str(e)})
continue
except Exception as e:
log.error(f"Error processing knowledge base {knowledge_base.id}: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error processing knowledge base"
detail=f"Error processing knowledge base",
)
if failed_files:
log.warning(f"Failed to process {len(failed_files)} files in knowledge base {knowledge_base.id}")
log.warning(
f"Failed to process {len(failed_files)} files in knowledge base {knowledge_base.id}"
)
for failed in failed_files:
log.warning(f"File ID: {failed['file_id']}, Error: {failed['error']}")
log.info("Reindexing completed successfully")
return True
@@ -742,6 +744,3 @@ def add_files_to_knowledge_batch(
return KnowledgeFilesResponse(
**knowledge.model_dump(), files=Files.get_files_by_ids(existing_file_ids)
)

View File

@@ -153,7 +153,9 @@ async def update_memory_by_id(
form_data: MemoryUpdateModel,
user=Depends(get_verified_user),
):
memory = Memories.update_memory_by_id(memory_id, form_data.content)
memory = Memories.update_memory_by_id_and_user_id(
memory_id, user.id, form_data.content
)
if memory is None:
raise HTTPException(status_code=404, detail="Memory not found")

File diff suppressed because it is too large Load Diff

View File

@@ -88,6 +88,10 @@ class ChatPermissions(BaseModel):
file_upload: bool = True
delete: bool = True
edit: bool = True
stt: bool = True
tts: bool = True
call: bool = True
multiple_models: bool = True
temporary: bool = True
temporary_enforced: bool = False