Merge branch 'dev' of https://github.com/open-webui/open-webui
# Conflicts: # src/lib/i18n/locales/sr-RS/translation.json
This commit is contained in:
@@ -1283,7 +1283,28 @@ TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = PersistentConfig(
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = """Available Tools: {{TOOLS}}\nReturn an empty string if no tools match the query. If a function tool matches, construct and return a JSON object in the format {\"name\": \"functionName\", \"parameters\": {\"requiredFunctionParamKey\": \"requiredFunctionParamValue\"}} using the appropriate tool and its parameters. Only return the object and limit the response to the JSON object without additional text."""
|
||||
DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = """Available Tools: {{TOOLS}}
|
||||
|
||||
Your task is to choose and return the correct tool(s) from the list of available tools based on the query. Follow these guidelines:
|
||||
|
||||
- Return only the JSON object, without any additional text or explanation.
|
||||
|
||||
- If no tools match the query, return an empty array:
|
||||
{
|
||||
"tool_calls": []
|
||||
}
|
||||
|
||||
- If one or more tools match the query, construct a JSON response containing a "tool_calls" array with objects that include:
|
||||
- "name": The tool's name.
|
||||
- "parameters": A dictionary of required parameters and their corresponding values.
|
||||
|
||||
The format for the JSON response is strictly:
|
||||
{
|
||||
"tool_calls": [
|
||||
{"name": "toolName1", "parameters": {"key1": "value1"}},
|
||||
{"name": "toolName2", "parameters": {"key2": "value2"}}
|
||||
]
|
||||
}"""
|
||||
|
||||
|
||||
DEFAULT_EMOJI_GENERATION_PROMPT_TEMPLATE = """Your task is to reflect the speaker's likely facial expression through a fitting emoji. Interpret emotions from the message and reflect their facial expression using fitting, diverse emojis (e.g., 😊, 😢, 😡, 😱).
|
||||
@@ -1325,6 +1346,7 @@ CHROMA_HTTP_SSL = os.environ.get("CHROMA_HTTP_SSL", "false").lower() == "true"
|
||||
|
||||
MILVUS_URI = os.environ.get("MILVUS_URI", f"{DATA_DIR}/vector_db/milvus.db")
|
||||
MILVUS_DB = os.environ.get("MILVUS_DB", "default")
|
||||
MILVUS_TOKEN = os.environ.get("MILVUS_TOKEN", None)
|
||||
|
||||
# Qdrant
|
||||
QDRANT_URI = os.environ.get("QDRANT_URI", None)
|
||||
|
||||
@@ -8,13 +8,17 @@ from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult
|
||||
from open_webui.config import (
|
||||
MILVUS_URI,
|
||||
MILVUS_DB,
|
||||
MILVUS_TOKEN,
|
||||
)
|
||||
|
||||
|
||||
class MilvusClient:
|
||||
def __init__(self):
|
||||
self.collection_prefix = "open_webui"
|
||||
self.client = Client(uri=MILVUS_URI, database=MILVUS_DB)
|
||||
if MILVUS_TOKEN is None:
|
||||
self.client = Client(uri=MILVUS_URI, database=MILVUS_DB)
|
||||
else:
|
||||
self.client = Client(uri=MILVUS_URI, database=MILVUS_DB, token=MILVUS_TOKEN)
|
||||
|
||||
def _result_to_get_result(self, result) -> GetResult:
|
||||
ids = []
|
||||
|
||||
@@ -90,6 +90,10 @@ async def update_task_config(
|
||||
form_data.TITLE_GENERATION_PROMPT_TEMPLATE
|
||||
)
|
||||
|
||||
request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = (
|
||||
form_data.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
|
||||
)
|
||||
|
||||
request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION = (
|
||||
form_data.ENABLE_AUTOCOMPLETE_GENERATION
|
||||
)
|
||||
|
||||
@@ -270,60 +270,70 @@ async def chat_completion_tools_handler(
|
||||
|
||||
result = json.loads(content)
|
||||
|
||||
tool_function_name = result.get("name", None)
|
||||
if tool_function_name not in tools:
|
||||
return body, {}
|
||||
async def tool_call_handler(tool_call):
|
||||
log.debug(f"{tool_call=}")
|
||||
|
||||
tool_function_params = result.get("parameters", {})
|
||||
tool_function_name = tool_call.get("name", None)
|
||||
if tool_function_name not in tools:
|
||||
return body, {}
|
||||
|
||||
try:
|
||||
required_params = (
|
||||
tools[tool_function_name]
|
||||
.get("spec", {})
|
||||
.get("parameters", {})
|
||||
.get("required", [])
|
||||
)
|
||||
tool_function = tools[tool_function_name]["callable"]
|
||||
tool_function_params = {
|
||||
k: v
|
||||
for k, v in tool_function_params.items()
|
||||
if k in required_params
|
||||
}
|
||||
tool_output = await tool_function(**tool_function_params)
|
||||
tool_function_params = tool_call.get("parameters", {})
|
||||
|
||||
except Exception as e:
|
||||
tool_output = str(e)
|
||||
|
||||
if isinstance(tool_output, str):
|
||||
if tools[tool_function_name]["citation"]:
|
||||
sources.append(
|
||||
{
|
||||
"source": {
|
||||
"name": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
else:
|
||||
sources.append(
|
||||
{
|
||||
"source": {},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
try:
|
||||
required_params = (
|
||||
tools[tool_function_name]
|
||||
.get("spec", {})
|
||||
.get("parameters", {})
|
||||
.get("required", [])
|
||||
)
|
||||
tool_function = tools[tool_function_name]["callable"]
|
||||
tool_function_params = {
|
||||
k: v
|
||||
for k, v in tool_function_params.items()
|
||||
if k in required_params
|
||||
}
|
||||
tool_output = await tool_function(**tool_function_params)
|
||||
|
||||
if tools[tool_function_name]["file_handler"]:
|
||||
skip_files = True
|
||||
except Exception as e:
|
||||
tool_output = str(e)
|
||||
|
||||
if isinstance(tool_output, str):
|
||||
if tools[tool_function_name]["citation"]:
|
||||
sources.append(
|
||||
{
|
||||
"source": {
|
||||
"name": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
else:
|
||||
sources.append(
|
||||
{
|
||||
"source": {},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
if tools[tool_function_name]["file_handler"]:
|
||||
skip_files = True
|
||||
|
||||
# check if "tool_calls" in result
|
||||
if result.get("tool_calls"):
|
||||
for tool_call in result.get("tool_calls"):
|
||||
await tool_call_handler(tool_call)
|
||||
else:
|
||||
await tool_call_handler(result)
|
||||
|
||||
except Exception as e:
|
||||
log.exception(f"Error: {e}")
|
||||
|
||||
@@ -131,6 +131,25 @@ def add_or_update_system_message(content: str, messages: list[dict]):
|
||||
return messages
|
||||
|
||||
|
||||
def append_or_update_assistant_message(content: str, messages: list[dict]):
|
||||
"""
|
||||
Adds a new assistant message at the end of the messages list
|
||||
or updates the existing assistant message at the end.
|
||||
|
||||
:param msg: The message to be added or appended.
|
||||
:param messages: The list of message dictionaries.
|
||||
:return: The updated list of message dictionaries.
|
||||
"""
|
||||
|
||||
if messages and messages[-1].get("role") == "assistant":
|
||||
messages[-1]["content"] = f"{messages[-1]['content']}\n{content}"
|
||||
else:
|
||||
# Insert at the end
|
||||
messages.append({"role": "assistant", "content": content})
|
||||
|
||||
return messages
|
||||
|
||||
|
||||
def openai_chat_message_template(model: str):
|
||||
return {
|
||||
"id": f"{model}-{str(uuid.uuid4())}",
|
||||
|
||||
@@ -82,7 +82,8 @@ class OAuthManager:
|
||||
oauth_allowed_roles = auth_manager_config.OAUTH_ALLOWED_ROLES
|
||||
oauth_admin_roles = auth_manager_config.OAUTH_ADMIN_ROLES
|
||||
oauth_roles = None
|
||||
role = "pending" # Default/fallback role if no matching roles are found
|
||||
# Default/fallback role if no matching roles are found
|
||||
role = auth_manager_config.DEFAULT_USER_ROLE
|
||||
|
||||
# Next block extracts the roles from the user data, accepting nested claims of any depth
|
||||
if oauth_claim and oauth_allowed_roles and oauth_admin_roles:
|
||||
@@ -273,7 +274,7 @@ class OAuthManager:
|
||||
log.error(
|
||||
f"Error downloading profile image '{picture_url}': {e}"
|
||||
)
|
||||
picture_url = ""
|
||||
picture_url = "/user.png"
|
||||
if not picture_url:
|
||||
picture_url = "/user.png"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ python-jose==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
|
||||
requests==2.32.3
|
||||
aiohttp==3.11.8
|
||||
aiohttp==3.11.11
|
||||
async-timeout
|
||||
aiocache
|
||||
aiofiles
|
||||
@@ -57,7 +57,7 @@ einops==0.8.0
|
||||
ftfy==6.2.3
|
||||
pypdf==4.3.1
|
||||
fpdf2==2.8.2
|
||||
pymdown-extensions==10.11.2
|
||||
pymdown-extensions==10.14.2
|
||||
docx2txt==0.8
|
||||
python-pptx==1.0.0
|
||||
unstructured==0.16.17
|
||||
@@ -71,16 +71,16 @@ xlrd==2.0.1
|
||||
validators==0.34.0
|
||||
psutil
|
||||
sentencepiece
|
||||
soundfile==0.12.1
|
||||
soundfile==0.13.1
|
||||
|
||||
opencv-python-headless==4.10.0.84
|
||||
opencv-python-headless==4.11.0.86
|
||||
rapidocr-onnxruntime==1.3.24
|
||||
rank-bm25==0.2.2
|
||||
|
||||
faster-whisper==1.0.3
|
||||
|
||||
PyJWT[crypto]==2.10.1
|
||||
authlib==1.3.2
|
||||
authlib==1.4.1
|
||||
|
||||
black==24.8.0
|
||||
langfuse==2.44.0
|
||||
@@ -89,7 +89,7 @@ pytube==15.0.0
|
||||
|
||||
extract_msg
|
||||
pydub
|
||||
duckduckgo-search~=7.2.1
|
||||
duckduckgo-search~=7.3.0
|
||||
|
||||
## Google Drive
|
||||
google-api-python-client
|
||||
|
||||
Reference in New Issue
Block a user