Skip to content

Commit 07d8460

Browse files
authored
Merge pull request open-webui#12809 from open-webui/dev
0.6.5
2 parents aca37f5 + e4c7417 commit 07d8460

File tree

72 files changed

+1409
-895
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1409
-895
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.6.5] - 2025-04-14
9+
10+
### Added
11+
12+
- 🛂 **Granular Voice Feature Permissions Per User Group**: Admins can now separately manage access to Speech-to-Text (record voice), Text-to-Speech (read aloud), and Tool Calls for each user group—giving teams tighter control over voice features and enhanced governance across roles.
13+
- 🗣️ **Toggle Voice Activity Detection (VAD) for Whisper STT**: New environment variable lets you enable/disable VAD filtering with built-in Whisper speech-to-text, giving you flexibility to optimize for different audio quality and response accuracy levels.
14+
- 📋 **Copy Formatted Response Mode**: You can now enable “Copy Formatted” in Settings > Interface to copy AI responses exactly as styled (with rich formatting, links, and structure preserved), making it faster and cleaner to paste into documents, emails, or reports.
15+
- ⚙️ **Backend Stability and Performance Enhancements**: General backend refactoring improves system resilience, consistency, and overall reliability—offering smoother performance across workflows whether chatting, generating media, or using external tools.
16+
- 🌎 **Translation Refinements Across Multiple Languages**: Updated translations deliver smoother language localization, clearer labels, and improved international usability throughout the UI—ensuring a better experience for non-English speakers.
17+
18+
### Fixed
19+
20+
- 🛠️ **LDAP Login Reliability Restored**: Resolved a critical issue where some LDAP setups failed due to attribute parsing—ensuring consistent, secure, and seamless user authentication across enterprise deployments.
21+
- 🖼️ **Image Generation in Temporary Chats Now Works Properly**: Fixed a bug where image outputs weren’t generated during temporary chats—visual content can now be used reliably in all chat modes without interruptions.
22+
823
## [0.6.4] - 2025-04-12
924

1025
### Fixed

backend/open_webui/config.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,18 @@ def oidc_oauth_register(client):
10621062
os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true"
10631063
)
10641064

1065+
USER_PERMISSIONS_CHAT_STT = (
1066+
os.environ.get("USER_PERMISSIONS_CHAT_STT", "True").lower() == "true"
1067+
)
1068+
1069+
USER_PERMISSIONS_CHAT_TTS = (
1070+
os.environ.get("USER_PERMISSIONS_CHAT_TTS", "True").lower() == "true"
1071+
)
1072+
1073+
USER_PERMISSIONS_CHAT_CALL = (
1074+
os.environ.get("USER_PERMISSIONS_CHAT_CALL", "True").lower() == "true"
1075+
)
1076+
10651077
USER_PERMISSIONS_CHAT_MULTIPLE_MODELS = (
10661078
os.environ.get("USER_PERMISSIONS_CHAT_MULTIPLE_MODELS", "True").lower() == "true"
10671079
)
@@ -1114,6 +1126,9 @@ def oidc_oauth_register(client):
11141126
"file_upload": USER_PERMISSIONS_CHAT_FILE_UPLOAD,
11151127
"delete": USER_PERMISSIONS_CHAT_DELETE,
11161128
"edit": USER_PERMISSIONS_CHAT_EDIT,
1129+
"stt": USER_PERMISSIONS_CHAT_STT,
1130+
"tts": USER_PERMISSIONS_CHAT_TTS,
1131+
"call": USER_PERMISSIONS_CHAT_CALL,
11171132
"multiple_models": USER_PERMISSIONS_CHAT_MULTIPLE_MODELS,
11181133
"temporary": USER_PERMISSIONS_CHAT_TEMPORARY,
11191134
"temporary_enforced": USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED,
@@ -2489,13 +2504,21 @@ class BannerModel(BaseModel):
24892504
and os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true"
24902505
)
24912506

2507+
WHISPER_VAD_FILTER = PersistentConfig(
2508+
"WHISPER_VAD_FILTER",
2509+
"audio.stt.whisper_vad_filter",
2510+
os.getenv("WHISPER_VAD_FILTER", "False").lower() == "true",
2511+
)
2512+
2513+
24922514
# Add Deepgram configuration
24932515
DEEPGRAM_API_KEY = PersistentConfig(
24942516
"DEEPGRAM_API_KEY",
24952517
"audio.stt.deepgram.api_key",
24962518
os.getenv("DEEPGRAM_API_KEY", ""),
24972519
)
24982520

2521+
24992522
AUDIO_STT_OPENAI_API_BASE_URL = PersistentConfig(
25002523
"AUDIO_STT_OPENAI_API_BASE_URL",
25012524
"audio.stt.openai.api_base_url",

backend/open_webui/main.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@
166166
FIRECRAWL_API_KEY,
167167
WEB_LOADER_ENGINE,
168168
WHISPER_MODEL,
169+
WHISPER_VAD_FILTER,
169170
DEEPGRAM_API_KEY,
170171
WHISPER_MODEL_AUTO_UPDATE,
171172
WHISPER_MODEL_DIR,
@@ -789,6 +790,7 @@ async def lifespan(app: FastAPI):
789790
app.state.config.STT_MODEL = AUDIO_STT_MODEL
790791

791792
app.state.config.WHISPER_MODEL = WHISPER_MODEL
793+
app.state.config.WHISPER_VAD_FILTER = WHISPER_VAD_FILTER
792794
app.state.config.DEEPGRAM_API_KEY = DEEPGRAM_API_KEY
793795

794796
app.state.config.AUDIO_STT_AZURE_API_KEY = AUDIO_STT_AZURE_API_KEY
@@ -1023,14 +1025,19 @@ def get_filtered_models(models, user):
10231025
if "pipeline" in model and model["pipeline"].get("type", None) == "filter":
10241026
continue
10251027

1026-
model_tags = [
1027-
tag.get("name")
1028-
for tag in model.get("info", {}).get("meta", {}).get("tags", [])
1029-
]
1030-
tags = [tag.get("name") for tag in model.get("tags", [])]
1031-
1032-
tags = list(set(model_tags + tags))
1033-
model["tags"] = [{"name": tag} for tag in tags]
1028+
try:
1029+
model_tags = [
1030+
tag.get("name")
1031+
for tag in model.get("info", {}).get("meta", {}).get("tags", [])
1032+
]
1033+
tags = [tag.get("name") for tag in model.get("tags", [])]
1034+
1035+
tags = list(set(model_tags + tags))
1036+
model["tags"] = [{"name": tag} for tag in tags]
1037+
except Exception as e:
1038+
log.debug(f"Error processing model tags: {e}")
1039+
model["tags"] = []
1040+
pass
10341041

10351042
models.append(model)
10361043

backend/open_webui/routers/audio.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,11 @@ def transcribe(request: Request, file_path):
497497
)
498498

499499
model = request.app.state.faster_whisper_model
500-
segments, info = model.transcribe(file_path, beam_size=5)
500+
segments, info = model.transcribe(
501+
file_path,
502+
beam_size=5,
503+
vad_filter=request.app.state.config.WHISPER_VAD_FILTER,
504+
)
501505
log.info(
502506
"Detected language '%s' with probability %f"
503507
% (info.language, info.language_probability)

backend/open_webui/routers/auths.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
230230

231231
entry = connection_app.entries[0]
232232
username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower()
233-
email = entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]
233+
email = entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"].value # retrive the Attribute value
234234
if not email:
235235
raise HTTPException(400, "User does not have a valid email address.")
236236
elif isinstance(email, str):
237237
email = email.lower()
238238
elif isinstance(email, list):
239239
email = email[0].lower()
240+
else:
241+
email = str(email).lower()
240242

241243
cn = str(entry["cn"])
242244
user_dn = entry.entry_dn

backend/open_webui/routers/retrieval.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,20 +1520,20 @@ async def process_web_search(
15201520
else:
15211521
collection_names = []
15221522
for doc_idx, doc in enumerate(docs):
1523-
collection_name = f"web-search-{calculate_sha256_string(form_data.query + '-' + urls[doc_idx])}"[
1524-
:63
1525-
]
1526-
1527-
collection_names.append(collection_name)
1528-
1529-
await run_in_threadpool(
1530-
save_docs_to_vector_db,
1531-
request,
1532-
[doc],
1533-
collection_name,
1534-
overwrite=True,
1535-
user=user,
1536-
)
1523+
if doc and doc.page_content:
1524+
collection_name = f"web-search-{calculate_sha256_string(form_data.query + '-' + urls[doc_idx])}"[
1525+
:63
1526+
]
1527+
1528+
collection_names.append(collection_name)
1529+
await run_in_threadpool(
1530+
save_docs_to_vector_db,
1531+
request,
1532+
[doc],
1533+
collection_name,
1534+
overwrite=True,
1535+
user=user,
1536+
)
15371537

15381538
return {
15391539
"status": True,

backend/open_webui/routers/users.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ class ChatPermissions(BaseModel):
8888
file_upload: bool = True
8989
delete: bool = True
9090
edit: bool = True
91+
stt: bool = True
92+
tts: bool = True
93+
call: bool = True
9194
multiple_models: bool = True
9295
temporary: bool = True
9396
temporary_enforced: bool = False

backend/open_webui/socket/main.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,16 +339,17 @@ async def __event_emitter__(event_data):
339339
request_info["message_id"],
340340
)
341341

342-
content = message.get("content", "")
343-
content += event_data.get("data", {}).get("content", "")
344-
345-
Chats.upsert_message_to_chat_by_id_and_message_id(
346-
request_info["chat_id"],
347-
request_info["message_id"],
348-
{
349-
"content": content,
350-
},
351-
)
342+
if message:
343+
content = message.get("content", "")
344+
content += event_data.get("data", {}).get("content", "")
345+
346+
Chats.upsert_message_to_chat_by_id_and_message_id(
347+
request_info["chat_id"],
348+
request_info["message_id"],
349+
{
350+
"content": content,
351+
},
352+
)
352353

353354
if "type" in event_data and event_data["type"] == "replace":
354355
content = event_data.get("data", {}).get("content", "")

backend/open_webui/utils/middleware.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,20 @@ async def chat_image_generation_handler(
534534
}
535535
)
536536

537-
for image in images:
538-
await __event_emitter__(
539-
{
540-
"type": "message",
541-
"data": {"content": f"![Generated Image]({image['url']})\n"},
542-
}
543-
)
537+
await __event_emitter__(
538+
{
539+
"type": "files",
540+
"data": {
541+
"files": [
542+
{
543+
"type": "image",
544+
"url": image["url"],
545+
}
546+
for image in images
547+
]
548+
},
549+
}
550+
)
544551

545552
system_message_content = "<context>User is shown the generated image, tell the user that the image has been generated</context>"
546553
except Exception as e:

0 commit comments

Comments
 (0)