Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
0b62bbb5
Unverified
Commit
0b62bbb5
authored
Mar 26, 2024
by
Chris
Committed by
GitHub
Mar 26, 2024
Browse files
Merge branch 'dev' into feat/Teams_Incoming_Webhook
parents
427ca4e3
cb364f0a
Changes
45
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
371 additions
and
172 deletions
+371
-172
.gitignore
.gitignore
+1
-1
CHANGELOG.md
CHANGELOG.md
+18
-0
backend/apps/audio/main.py
backend/apps/audio/main.py
+8
-4
backend/apps/images/main.py
backend/apps/images/main.py
+7
-3
backend/apps/litellm/main.py
backend/apps/litellm/main.py
+7
-2
backend/apps/ollama/main.py
backend/apps/ollama/main.py
+55
-36
backend/apps/openai/main.py
backend/apps/openai/main.py
+13
-8
backend/apps/rag/main.py
backend/apps/rag/main.py
+150
-83
backend/apps/rag/utils.py
backend/apps/rag/utils.py
+9
-3
backend/apps/web/internal/db.py
backend/apps/web/internal/db.py
+5
-2
backend/apps/web/models/auths.py
backend/apps/web/models/auths.py
+7
-2
backend/apps/web/models/documents.py
backend/apps/web/models/documents.py
+7
-2
backend/apps/web/models/tags.py
backend/apps/web/models/tags.py
+9
-4
backend/apps/web/routers/chats.py
backend/apps/web/routers/chats.py
+7
-2
backend/apps/web/routers/users.py
backend/apps/web/routers/users.py
+6
-1
backend/config.py
backend/config.py
+49
-14
backend/constants.py
backend/constants.py
+2
-0
backend/main.py
backend/main.py
+8
-2
kubernetes/manifest/base/webui-deployment.yaml
kubernetes/manifest/base/webui-deployment.yaml
+1
-1
kubernetes/manifest/base/webui-pvc.yaml
kubernetes/manifest/base/webui-pvc.yaml
+2
-2
No files found.
.gitignore
View file @
0b62bbb5
...
...
@@ -166,7 +166,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#
.idea/
.idea/
# Logs
logs
...
...
CHANGELOG.md
View file @
0b62bbb5
...
...
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on
[
Keep a Changelog
](
https://keepachangelog.com/en/1.1.0/
)
,
and this project adheres to
[
Semantic Versioning
](
https://semver.org/spec/v2.0.0.html
)
.
## [0.1.115] - 2024-03-24
### Added
-
**🔍 Custom Model Selector**
: Easily find and select custom models with the new search filter feature.
-
**🛑 Cancel Model Download**
: Added the ability to cancel model downloads.
-
**🎨 Image Generation ComfyUI**
: Image generation now supports ComfyUI.
-
**🌟 Updated Light Theme**
: Updated the light theme for a fresh look.
-
**🌍 Additional Language Support**
: Now supporting Bulgarian, Italian, Portuguese, Japanese, and Dutch.
### Fixed
-
**🔧 Fixed Broken Experimental GGUF Upload**
: Resolved issues with experimental GGUF upload functionality.
### Changed
-
**🔄 Vector Storage Reset Button**
: Moved the reset vector storage button to document settings.
## [0.1.114] - 2024-03-20
### Added
...
...
backend/apps/audio/main.py
View file @
0b62bbb5
import
os
import
logging
from
fastapi
import
(
FastAPI
,
Request
,
...
...
@@ -21,7 +22,10 @@ from utils.utils import (
)
from
utils.misc
import
calculate_sha256
from
config
import
CACHE_DIR
,
UPLOAD_DIR
,
WHISPER_MODEL
,
WHISPER_MODEL_DIR
from
config
import
SRC_LOG_LEVELS
,
CACHE_DIR
,
UPLOAD_DIR
,
WHISPER_MODEL
,
WHISPER_MODEL_DIR
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"AUDIO"
])
app
=
FastAPI
()
app
.
add_middleware
(
...
...
@@ -38,7 +42,7 @@ def transcribe(
file
:
UploadFile
=
File
(...),
user
=
Depends
(
get_current_user
),
):
print
(
file
.
content_type
)
log
.
info
(
f
"file.content_type:
{
file
.
content_type
}
"
)
if
file
.
content_type
not
in
[
"audio/mpeg"
,
"audio/wav"
]:
raise
HTTPException
(
...
...
@@ -62,7 +66,7 @@ def transcribe(
)
segments
,
info
=
model
.
transcribe
(
file_path
,
beam_size
=
5
)
print
(
log
.
info
(
"Detected language '%s' with probability %f"
%
(
info
.
language
,
info
.
language_probability
)
)
...
...
@@ -72,7 +76,7 @@ def transcribe(
return
{
"text"
:
transcript
.
strip
()}
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
...
...
backend/apps/images/main.py
View file @
0b62bbb5
...
...
@@ -27,10 +27,14 @@ from pathlib import Path
import
uuid
import
base64
import
json
import
logging
from
config
import
CACHE_DIR
,
AUTOMATIC1111_BASE_URL
,
COMFYUI_BASE_URL
from
config
import
SRC_LOG_LEVELS
,
CACHE_DIR
,
AUTOMATIC1111_BASE_URL
,
COMFYUI_BASE_URL
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"IMAGES"
])
IMAGE_CACHE_DIR
=
Path
(
CACHE_DIR
).
joinpath
(
"./image/generations/"
)
IMAGE_CACHE_DIR
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
...
...
@@ -304,7 +308,7 @@ def save_b64_image(b64_str):
return
image_id
except
Exception
as
e
:
print
(
f
"Error saving image:
{
e
}
"
)
log
.
error
(
f
"Error saving image:
{
e
}
"
)
return
None
...
...
@@ -431,7 +435,7 @@ def generate_image(
res
=
r
.
json
()
print
(
res
)
log
.
debug
(
f
"res:
{
res
}
"
)
images
=
[]
...
...
backend/apps/litellm/main.py
View file @
0b62bbb5
import
logging
from
litellm.proxy.proxy_server
import
ProxyConfig
,
initialize
from
litellm.proxy.proxy_server
import
app
...
...
@@ -9,7 +11,10 @@ from starlette.responses import StreamingResponse
import
json
from
utils.utils
import
get_http_authorization_cred
,
get_current_user
from
config
import
ENV
from
config
import
SRC_LOG_LEVELS
,
ENV
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"LITELLM"
])
from
config
import
(
...
...
@@ -49,7 +54,7 @@ async def auth_middleware(request: Request, call_next):
try
:
user
=
get_current_user
(
get_http_authorization_cred
(
auth_header
))
print
(
user
)
log
.
debug
(
f
"user:
{
user
}
"
)
request
.
state
.
user
=
user
except
Exception
as
e
:
return
JSONResponse
(
status_code
=
400
,
content
=
{
"detail"
:
str
(
e
)})
...
...
backend/apps/ollama/main.py
View file @
0b62bbb5
...
...
@@ -23,6 +23,7 @@ import json
import
uuid
import
aiohttp
import
asyncio
import
logging
from
urllib.parse
import
urlparse
from
typing
import
Optional
,
List
,
Union
...
...
@@ -30,11 +31,13 @@ from typing import Optional, List, Union
from
apps.web.models.users
import
Users
from
constants
import
ERROR_MESSAGES
from
utils.utils
import
decode_token
,
get_current_user
,
get_admin_user
from
utils.misc
import
calculate_sha256
from
config
import
OLLAMA_BASE_URLS
,
MODEL_FILTER_ENABLED
,
MODEL_FILTER_LIST
,
UPLOAD_DIR
from
config
import
SRC_LOG_LEVELS
,
OLLAMA_BASE_URLS
,
MODEL_FILTER_ENABLED
,
MODEL_FILTER_LIST
,
UPLOAD_DIR
from
utils.misc
import
calculate_sha256
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"OLLAMA"
])
app
=
FastAPI
()
app
.
add_middleware
(
...
...
@@ -85,7 +88,7 @@ class UrlUpdateForm(BaseModel):
async
def
update_ollama_api_url
(
form_data
:
UrlUpdateForm
,
user
=
Depends
(
get_admin_user
)):
app
.
state
.
OLLAMA_BASE_URLS
=
form_data
.
urls
print
(
app
.
state
.
OLLAMA_BASE_URLS
)
log
.
info
(
f
"
app.state.OLLAMA_BASE_URLS
:
{
app
.
state
.
OLLAMA_BASE_URLS
}
"
)
return
{
"OLLAMA_BASE_URLS"
:
app
.
state
.
OLLAMA_BASE_URLS
}
...
...
@@ -106,7 +109,7 @@ async def fetch_url(url):
return
await
response
.
json
()
except
Exception
as
e
:
# Handle connection error here
print
(
f
"Connection error:
{
e
}
"
)
log
.
error
(
f
"Connection error:
{
e
}
"
)
return
None
...
...
@@ -130,7 +133,7 @@ def merge_models_lists(model_lists):
async
def
get_all_models
():
print
(
"get_all_models"
)
log
.
info
(
"get_all_models
()
"
)
tasks
=
[
fetch_url
(
f
"
{
url
}
/api/tags"
)
for
url
in
app
.
state
.
OLLAMA_BASE_URLS
]
responses
=
await
asyncio
.
gather
(
*
tasks
)
...
...
@@ -171,7 +174,7 @@ async def get_ollama_tags(
return
r
.
json
()
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -217,7 +220,7 @@ async def get_ollama_versions(url_idx: Optional[int] = None):
return
r
.
json
()
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -243,18 +246,33 @@ async def pull_model(
form_data
:
ModelNameForm
,
url_idx
:
int
=
0
,
user
=
Depends
(
get_admin_user
)
):
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
r
=
None
def
get_request
():
nonlocal
url
nonlocal
r
request_id
=
str
(
uuid
.
uuid4
())
try
:
REQUEST_POOL
.
append
(
request_id
)
def
stream_content
():
try
:
yield
json
.
dumps
({
"id"
:
request_id
,
"done"
:
False
})
+
"
\n
"
for
chunk
in
r
.
iter_content
(
chunk_size
=
8192
):
if
request_id
in
REQUEST_POOL
:
yield
chunk
else
:
print
(
"User: canceled request"
)
break
finally
:
if
hasattr
(
r
,
"close"
):
r
.
close
()
if
request_id
in
REQUEST_POOL
:
REQUEST_POOL
.
remove
(
request_id
)
r
=
requests
.
request
(
method
=
"POST"
,
...
...
@@ -275,8 +293,9 @@ async def pull_model(
try
:
return
await
run_in_threadpool
(
get_request
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -315,7 +334,7 @@ async def push_model(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
debug
(
f
"url:
{
url
}
"
)
r
=
None
...
...
@@ -347,7 +366,7 @@ async def push_model(
try
:
return
await
run_in_threadpool
(
get_request
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -375,9 +394,9 @@ class CreateModelForm(BaseModel):
async
def
create_model
(
form_data
:
CreateModelForm
,
url_idx
:
int
=
0
,
user
=
Depends
(
get_admin_user
)
):
print
(
form_data
)
log
.
debug
(
f
"form_data:
{
form_data
}
"
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
r
=
None
...
...
@@ -399,7 +418,7 @@ async def create_model(
r
.
raise_for_status
()
print
(
r
)
log
.
debug
(
f
"r:
{
r
}
"
)
return
StreamingResponse
(
stream_content
(),
...
...
@@ -412,7 +431,7 @@ async def create_model(
try
:
return
await
run_in_threadpool
(
get_request
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -450,7 +469,7 @@ async def copy_model(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
try
:
r
=
requests
.
request
(
...
...
@@ -460,11 +479,11 @@ async def copy_model(
)
r
.
raise_for_status
()
print
(
r
.
text
)
log
.
debug
(
f
"r.text:
{
r
.
text
}
"
)
return
True
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -497,7 +516,7 @@ async def delete_model(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
try
:
r
=
requests
.
request
(
...
...
@@ -507,11 +526,11 @@ async def delete_model(
)
r
.
raise_for_status
()
print
(
r
.
text
)
log
.
debug
(
f
"r.text:
{
r
.
text
}
"
)
return
True
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -537,7 +556,7 @@ async def show_model_info(form_data: ModelNameForm, user=Depends(get_current_use
url_idx
=
random
.
choice
(
app
.
state
.
MODELS
[
form_data
.
name
][
"urls"
])
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
try
:
r
=
requests
.
request
(
...
...
@@ -549,7 +568,7 @@ async def show_model_info(form_data: ModelNameForm, user=Depends(get_current_use
return
r
.
json
()
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -589,7 +608,7 @@ async def generate_embeddings(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
try
:
r
=
requests
.
request
(
...
...
@@ -601,7 +620,7 @@ async def generate_embeddings(
return
r
.
json
()
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -649,7 +668,7 @@ async def generate_completion(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
r
=
None
...
...
@@ -670,7 +689,7 @@ async def generate_completion(
if
request_id
in
REQUEST_POOL
:
yield
chunk
else
:
pr
in
t
(
"User: canceled request"
)
log
.
warn
in
g
(
"User: canceled request"
)
break
finally
:
if
hasattr
(
r
,
"close"
):
...
...
@@ -747,11 +766,11 @@ async def generate_chat_completion(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
r
=
None
prin
t
(
form_data
.
model_dump_json
(
exclude_none
=
True
).
encode
())
log
.
debug
(
"form_data.model_dump_json(exclude_none=True).encode(): {0} "
.
forma
t
(
form_data
.
model_dump_json
(
exclude_none
=
True
).
encode
())
)
def
get_request
():
nonlocal
form_data
...
...
@@ -770,7 +789,7 @@ async def generate_chat_completion(
if
request_id
in
REQUEST_POOL
:
yield
chunk
else
:
pr
in
t
(
"User: canceled request"
)
log
.
warn
in
g
(
"User: canceled request"
)
break
finally
:
if
hasattr
(
r
,
"close"
):
...
...
@@ -793,7 +812,7 @@ async def generate_chat_completion(
headers
=
dict
(
r
.
headers
),
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
e
try
:
...
...
@@ -847,7 +866,7 @@ async def generate_openai_chat_completion(
)
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
url_idx
]
print
(
url
)
log
.
info
(
f
"url:
{
url
}
"
)
r
=
None
...
...
@@ -870,7 +889,7 @@ async def generate_openai_chat_completion(
if
request_id
in
REQUEST_POOL
:
yield
chunk
else
:
pr
in
t
(
"User: canceled request"
)
log
.
warn
in
g
(
"User: canceled request"
)
break
finally
:
if
hasattr
(
r
,
"close"
):
...
...
@@ -1168,7 +1187,7 @@ async def deprecated_proxy(path: str, request: Request, user=Depends(get_current
if
request_id
in
REQUEST_POOL
:
yield
chunk
else
:
pr
in
t
(
"User: canceled request"
)
log
.
warn
in
g
(
"User: canceled request"
)
break
finally
:
if
hasattr
(
r
,
"close"
):
...
...
backend/apps/openai/main.py
View file @
0b62bbb5
...
...
@@ -6,6 +6,7 @@ import requests
import
aiohttp
import
asyncio
import
json
import
logging
from
pydantic
import
BaseModel
...
...
@@ -19,6 +20,7 @@ from utils.utils import (
get_admin_user
,
)
from
config
import
(
SRC_LOG_LEVELS
,
OPENAI_API_BASE_URLS
,
OPENAI_API_KEYS
,
CACHE_DIR
,
...
...
@@ -31,6 +33,9 @@ from typing import List, Optional
import
hashlib
from
pathlib
import
Path
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"OPENAI"
])
app
=
FastAPI
()
app
.
add_middleware
(
CORSMiddleware
,
...
...
@@ -134,7 +139,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
return
FileResponse
(
file_path
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -160,7 +165,7 @@ async def fetch_url(url, key):
return
await
response
.
json
()
except
Exception
as
e
:
# Handle connection error here
print
(
f
"Connection error:
{
e
}
"
)
log
.
error
(
f
"Connection error:
{
e
}
"
)
return
None
...
...
@@ -182,7 +187,7 @@ def merge_models_lists(model_lists):
async
def
get_all_models
():
print
(
"get_all_models"
)
log
.
info
(
"get_all_models
()
"
)
if
len
(
app
.
state
.
OPENAI_API_KEYS
)
==
1
and
app
.
state
.
OPENAI_API_KEYS
[
0
]
==
""
:
models
=
{
"data"
:
[]}
...
...
@@ -208,7 +213,7 @@ async def get_all_models():
)
}
print
(
models
)
log
.
info
(
f
"models:
{
models
}
"
)
app
.
state
.
MODELS
=
{
model
[
"id"
]:
model
for
model
in
models
[
"data"
]}
return
models
...
...
@@ -246,7 +251,7 @@ async def get_models(url_idx: Optional[int] = None, user=Depends(get_current_use
return
response_data
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
@@ -280,7 +285,7 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
if
body
.
get
(
"model"
)
==
"gpt-4-vision-preview"
:
if
"max_tokens"
not
in
body
:
body
[
"max_tokens"
]
=
4000
print
(
"Modified body_dict:"
,
body
)
log
.
debug
(
"Modified body_dict:"
,
body
)
# Fix for ChatGPT calls failing because the num_ctx key is in body
if
"num_ctx"
in
body
:
...
...
@@ -292,7 +297,7 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
# Convert the modified body back to JSON
body
=
json
.
dumps
(
body
)
except
json
.
JSONDecodeError
as
e
:
print
(
"Error loading request body into a dictionary:"
,
e
)
log
.
error
(
"Error loading request body into a dictionary:"
,
e
)
url
=
app
.
state
.
OPENAI_API_BASE_URLS
[
idx
]
key
=
app
.
state
.
OPENAI_API_KEYS
[
idx
]
...
...
@@ -330,7 +335,7 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
response_data
=
r
.
json
()
return
response_data
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
error_detail
=
"Open WebUI: Server Connection Error"
if
r
is
not
None
:
try
:
...
...
backend/apps/rag/main.py
View file @
0b62bbb5
...
...
@@ -8,7 +8,7 @@ from fastapi import (
Form
,
)
from
fastapi.middleware.cors
import
CORSMiddleware
import
os
,
shutil
import
os
,
shutil
,
logging
from
pathlib
import
Path
from
typing
import
List
...
...
@@ -21,6 +21,7 @@ from langchain_community.document_loaders import (
TextLoader
,
PyPDFLoader
,
CSVLoader
,
BSHTMLLoader
,
Docx2txtLoader
,
UnstructuredEPubLoader
,
UnstructuredWordDocumentLoader
,
...
...
@@ -54,6 +55,7 @@ from utils.misc import (
)
from
utils.utils
import
get_current_user
,
get_admin_user
from
config
import
(
SRC_LOG_LEVELS
,
UPLOAD_DIR
,
DOCS_DIR
,
RAG_EMBEDDING_MODEL
,
...
...
@@ -66,6 +68,9 @@ from config import (
from
constants
import
ERROR_MESSAGES
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"RAG"
])
#
# if RAG_EMBEDDING_MODEL:
# sentence_transformer_ef = SentenceTransformer(
...
...
@@ -111,39 +116,6 @@ class StoreWebForm(CollectionNameForm):
url
:
str
def
store_data_in_vector_db
(
data
,
collection_name
,
overwrite
:
bool
=
False
)
->
bool
:
text_splitter
=
RecursiveCharacterTextSplitter
(
chunk_size
=
app
.
state
.
CHUNK_SIZE
,
chunk_overlap
=
app
.
state
.
CHUNK_OVERLAP
)
docs
=
text_splitter
.
split_documents
(
data
)
texts
=
[
doc
.
page_content
for
doc
in
docs
]
metadatas
=
[
doc
.
metadata
for
doc
in
docs
]
try
:
if
overwrite
:
for
collection
in
CHROMA_CLIENT
.
list_collections
():
if
collection_name
==
collection
.
name
:
print
(
f
"deleting existing collection
{
collection_name
}
"
)
CHROMA_CLIENT
.
delete_collection
(
name
=
collection_name
)
collection
=
CHROMA_CLIENT
.
create_collection
(
name
=
collection_name
,
embedding_function
=
app
.
state
.
sentence_transformer_ef
,
)
collection
.
add
(
documents
=
texts
,
metadatas
=
metadatas
,
ids
=
[
str
(
uuid
.
uuid1
())
for
_
in
texts
]
)
return
True
except
Exception
as
e
:
print
(
e
)
if
e
.
__class__
.
__name__
==
"UniqueConstraintError"
:
return
True
return
False
@
app
.
get
(
"/"
)
async
def
get_status
():
return
{
...
...
@@ -274,7 +246,7 @@ def query_doc_handler(
embedding_function
=
app
.
state
.
sentence_transformer_ef
,
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
),
...
...
@@ -318,13 +290,69 @@ def store_web(form_data: StoreWebForm, user=Depends(get_current_user)):
"filename"
:
form_data
.
url
,
}
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
e
),
)
def
store_data_in_vector_db
(
data
,
collection_name
,
overwrite
:
bool
=
False
)
->
bool
:
text_splitter
=
RecursiveCharacterTextSplitter
(
chunk_size
=
app
.
state
.
CHUNK_SIZE
,
chunk_overlap
=
app
.
state
.
CHUNK_OVERLAP
,
add_start_index
=
True
,
)
docs
=
text_splitter
.
split_documents
(
data
)
if
len
(
docs
)
>
0
:
return
store_docs_in_vector_db
(
docs
,
collection_name
,
overwrite
),
None
else
:
raise
ValueError
(
ERROR_MESSAGES
.
EMPTY_CONTENT
)
def
store_text_in_vector_db
(
text
,
metadata
,
collection_name
,
overwrite
:
bool
=
False
)
->
bool
:
text_splitter
=
RecursiveCharacterTextSplitter
(
chunk_size
=
app
.
state
.
CHUNK_SIZE
,
chunk_overlap
=
app
.
state
.
CHUNK_OVERLAP
,
add_start_index
=
True
,
)
docs
=
text_splitter
.
create_documents
([
text
],
metadatas
=
[
metadata
])
return
store_docs_in_vector_db
(
docs
,
collection_name
,
overwrite
)
def
store_docs_in_vector_db
(
docs
,
collection_name
,
overwrite
:
bool
=
False
)
->
bool
:
texts
=
[
doc
.
page_content
for
doc
in
docs
]
metadatas
=
[
doc
.
metadata
for
doc
in
docs
]
try
:
if
overwrite
:
for
collection
in
CHROMA_CLIENT
.
list_collections
():
if
collection_name
==
collection
.
name
:
print
(
f
"deleting existing collection
{
collection_name
}
"
)
CHROMA_CLIENT
.
delete_collection
(
name
=
collection_name
)
collection
=
CHROMA_CLIENT
.
create_collection
(
name
=
collection_name
,
embedding_function
=
app
.
state
.
sentence_transformer_ef
,
)
collection
.
add
(
documents
=
texts
,
metadatas
=
metadatas
,
ids
=
[
str
(
uuid
.
uuid1
())
for
_
in
texts
]
)
return
True
except
Exception
as
e
:
print
(
e
)
if
e
.
__class__
.
__name__
==
"UniqueConstraintError"
:
return
True
return
False
def
get_loader
(
filename
:
str
,
file_content_type
:
str
,
file_path
:
str
):
file_ext
=
filename
.
split
(
"."
)[
-
1
].
lower
()
known_type
=
True
...
...
@@ -382,6 +410,8 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
loader
=
UnstructuredRSTLoader
(
file_path
,
mode
=
"elements"
)
elif
file_ext
==
"xml"
:
loader
=
UnstructuredXMLLoader
(
file_path
)
elif
file_ext
in
[
"htm"
,
"html"
]:
loader
=
BSHTMLLoader
(
file_path
,
open_encoding
=
"unicode_escape"
)
elif
file_ext
==
"md"
:
loader
=
UnstructuredMarkdownLoader
(
file_path
)
elif
file_content_type
==
"application/epub+zip"
:
...
...
@@ -416,7 +446,7 @@ def store_doc(
):
# "https://www.gutenberg.org/files/1727/1727-h/1727-h.htm"
print
(
file
.
content_type
)
log
.
info
(
f
"file.content_type:
{
file
.
content_type
}
"
)
try
:
filename
=
file
.
filename
file_path
=
f
"
{
UPLOAD_DIR
}
/
{
filename
}
"
...
...
@@ -432,6 +462,8 @@ def store_doc(
loader
,
known_type
=
get_loader
(
file
.
filename
,
file
.
content_type
,
file_path
)
data
=
loader
.
load
()
try
:
result
=
store_data_in_vector_db
(
data
,
collection_name
)
if
result
:
...
...
@@ -441,13 +473,13 @@ def store_doc(
"filename"
:
filename
,
"known_type"
:
known_type
,
}
e
ls
e
:
e
xcept
Exception
as
e
:
raise
HTTPException
(
status_code
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
,
detail
=
ERROR_MESSAGES
.
DEFAULT
()
,
detail
=
e
,
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
if
"No pandoc was found"
in
str
(
e
):
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
...
...
@@ -460,6 +492,37 @@ def store_doc(
)
class
TextRAGForm
(
BaseModel
):
name
:
str
content
:
str
collection_name
:
Optional
[
str
]
=
None
@
app
.
post
(
"/text"
)
def
store_text
(
form_data
:
TextRAGForm
,
user
=
Depends
(
get_current_user
),
):
collection_name
=
form_data
.
collection_name
if
collection_name
==
None
:
collection_name
=
calculate_sha256_string
(
form_data
.
content
)
result
=
store_text_in_vector_db
(
form_data
.
content
,
metadata
=
{
"name"
:
form_data
.
name
,
"created_by"
:
user
.
id
},
collection_name
=
collection_name
,
)
if
result
:
return
{
"status"
:
True
,
"collection_name"
:
collection_name
}
else
:
raise
HTTPException
(
status_code
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(),
)
@
app
.
get
(
"/scan"
)
def
scan_docs_dir
(
user
=
Depends
(
get_admin_user
)):
for
path
in
Path
(
DOCS_DIR
).
rglob
(
"./**/*"
):
...
...
@@ -478,6 +541,7 @@ def scan_docs_dir(user=Depends(get_admin_user)):
)
data
=
loader
.
load
()
try
:
result
=
store_data_in_vector_db
(
data
,
collection_name
)
if
result
:
...
...
@@ -510,9 +574,12 @@ def scan_docs_dir(user=Depends(get_admin_user)):
}
),
)
except
Exception
as
e
:
print
(
e
)
pass
except
Exception
as
e
:
log
.
exception
(
e
)
return
True
...
...
@@ -533,11 +600,11 @@ def reset(user=Depends(get_admin_user)) -> bool:
elif
os
.
path
.
isdir
(
file_path
):
shutil
.
rmtree
(
file_path
)
except
Exception
as
e
:
print
(
"Failed to delete %s. Reason: %s"
%
(
file_path
,
e
))
log
.
error
(
"Failed to delete %s. Reason: %s"
%
(
file_path
,
e
))
try
:
CHROMA_CLIENT
.
reset
()
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
return
True
backend/apps/rag/utils.py
View file @
0b62bbb5
import
re
import
logging
from
typing
import
List
from
config
import
CHROMA_CLIENT
from
config
import
SRC_LOG_LEVELS
,
CHROMA_CLIENT
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"RAG"
])
def
query_doc
(
collection_name
:
str
,
query
:
str
,
k
:
int
,
embedding_function
):
...
...
@@ -97,7 +101,7 @@ def rag_template(template: str, context: str, query: str):
def
rag_messages
(
docs
,
messages
,
template
,
k
,
embedding_function
):
print
(
docs
)
log
.
debug
(
f
"docs:
{
docs
}
"
)
last_user_message_idx
=
None
for
i
in
range
(
len
(
messages
)
-
1
,
-
1
,
-
1
):
...
...
@@ -137,6 +141,8 @@ def rag_messages(docs, messages, template, k, embedding_function):
k
=
k
,
embedding_function
=
embedding_function
,
)
elif
doc
[
"type"
]
==
"text"
:
context
=
doc
[
"content"
]
else
:
context
=
query_doc
(
collection_name
=
doc
[
"collection_name"
],
...
...
@@ -145,7 +151,7 @@ def rag_messages(docs, messages, template, k, embedding_function):
embedding_function
=
embedding_function
,
)
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
context
=
None
relevant_contexts
.
append
(
context
)
...
...
backend/apps/web/internal/db.py
View file @
0b62bbb5
from
peewee
import
*
from
config
import
DATA_DIR
from
config
import
SRC_LOG_LEVELS
,
DATA_DIR
import
os
import
logging
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"DB"
])
# Check if the file exists
if
os
.
path
.
exists
(
f
"
{
DATA_DIR
}
/ollama.db"
):
# Rename the file
os
.
rename
(
f
"
{
DATA_DIR
}
/ollama.db"
,
f
"
{
DATA_DIR
}
/webui.db"
)
print
(
"File renamed successfully."
)
log
.
info
(
"File renamed successfully."
)
else
:
pass
...
...
backend/apps/web/models/auths.py
View file @
0b62bbb5
...
...
@@ -2,6 +2,7 @@ from pydantic import BaseModel
from
typing
import
List
,
Union
,
Optional
import
time
import
uuid
import
logging
from
peewee
import
*
from
apps.web.models.users
import
UserModel
,
Users
...
...
@@ -9,6 +10,10 @@ from utils.utils import verify_password
from
apps.web.internal.db
import
DB
from
config
import
SRC_LOG_LEVELS
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MODELS"
])
####################
# DB MODEL
####################
...
...
@@ -86,7 +91,7 @@ class AuthsTable:
def
insert_new_auth
(
self
,
email
:
str
,
password
:
str
,
name
:
str
,
role
:
str
=
"pending"
)
->
Optional
[
UserModel
]:
print
(
"insert_new_auth"
)
log
.
info
(
"insert_new_auth"
)
id
=
str
(
uuid
.
uuid4
())
...
...
@@ -103,7 +108,7 @@ class AuthsTable:
return
None
def
authenticate_user
(
self
,
email
:
str
,
password
:
str
)
->
Optional
[
UserModel
]:
print
(
"authenticate_user
"
,
email
)
log
.
info
(
f
"authenticate_user
:
{
email
}
"
)
try
:
auth
=
Auth
.
get
(
Auth
.
email
==
email
,
Auth
.
active
==
True
)
if
auth
:
...
...
backend/apps/web/models/documents.py
View file @
0b62bbb5
...
...
@@ -3,6 +3,7 @@ from peewee import *
from
playhouse.shortcuts
import
model_to_dict
from
typing
import
List
,
Union
,
Optional
import
time
import
logging
from
utils.utils
import
decode_token
from
utils.misc
import
get_gravatar_url
...
...
@@ -11,6 +12,10 @@ from apps.web.internal.db import DB
import
json
from
config
import
SRC_LOG_LEVELS
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MODELS"
])
####################
# Documents DB Schema
####################
...
...
@@ -118,7 +123,7 @@ class DocumentsTable:
doc
=
Document
.
get
(
Document
.
name
==
form_data
.
name
)
return
DocumentModel
(
**
model_to_dict
(
doc
))
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
return
None
def
update_doc_content_by_name
(
...
...
@@ -138,7 +143,7 @@ class DocumentsTable:
doc
=
Document
.
get
(
Document
.
name
==
name
)
return
DocumentModel
(
**
model_to_dict
(
doc
))
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
return
None
def
delete_doc_by_name
(
self
,
name
:
str
)
->
bool
:
...
...
backend/apps/web/models/tags.py
View file @
0b62bbb5
...
...
@@ -6,9 +6,14 @@ from playhouse.shortcuts import model_to_dict
import
json
import
uuid
import
time
import
logging
from
apps.web.internal.db
import
DB
from
config
import
SRC_LOG_LEVELS
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MODELS"
])
####################
# Tag DB Schema
####################
...
...
@@ -173,7 +178,7 @@ class TagTable:
(
ChatIdTag
.
tag_name
==
tag_name
)
&
(
ChatIdTag
.
user_id
==
user_id
)
)
res
=
query
.
execute
()
# Remove the rows, return number of rows removed.
print
(
res
)
log
.
debug
(
f
"res:
{
res
}
"
)
tag_count
=
self
.
count_chat_ids_by_tag_name_and_user_id
(
tag_name
,
user_id
)
if
tag_count
==
0
:
...
...
@@ -185,7 +190,7 @@ class TagTable:
return
True
except
Exception
as
e
:
print
(
"delete_tag
"
,
e
)
log
.
error
(
f
"delete_tag
:
{
e
}
"
)
return
False
def
delete_tag_by_tag_name_and_chat_id_and_user_id
(
...
...
@@ -198,7 +203,7 @@ class TagTable:
&
(
ChatIdTag
.
user_id
==
user_id
)
)
res
=
query
.
execute
()
# Remove the rows, return number of rows removed.
print
(
res
)
log
.
debug
(
f
"res:
{
res
}
"
)
tag_count
=
self
.
count_chat_ids_by_tag_name_and_user_id
(
tag_name
,
user_id
)
if
tag_count
==
0
:
...
...
@@ -210,7 +215,7 @@ class TagTable:
return
True
except
Exception
as
e
:
print
(
"delete_tag
"
,
e
)
log
.
error
(
f
"delete_tag
:
{
e
}
"
)
return
False
def
delete_tags_by_chat_id_and_user_id
(
self
,
chat_id
:
str
,
user_id
:
str
)
->
bool
:
...
...
backend/apps/web/routers/chats.py
View file @
0b62bbb5
...
...
@@ -5,6 +5,7 @@ from utils.utils import get_current_user, get_admin_user
from
fastapi
import
APIRouter
from
pydantic
import
BaseModel
import
json
import
logging
from
apps.web.models.users
import
Users
from
apps.web.models.chats
import
(
...
...
@@ -27,6 +28,10 @@ from apps.web.models.tags import (
from
constants
import
ERROR_MESSAGES
from
config
import
SRC_LOG_LEVELS
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MODELS"
])
router
=
APIRouter
()
############################
...
...
@@ -78,7 +83,7 @@ async def create_new_chat(form_data: ChatForm, user=Depends(get_current_user)):
chat
=
Chats
.
insert_new_chat
(
user
.
id
,
form_data
)
return
ChatResponse
(
**
{
**
chat
.
model_dump
(),
"chat"
:
json
.
loads
(
chat
.
chat
)})
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
()
)
...
...
@@ -95,7 +100,7 @@ async def get_all_tags(user=Depends(get_current_user)):
tags
=
Tags
.
get_tags_by_user_id
(
user
.
id
)
return
tags
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
()
)
...
...
backend/apps/web/routers/users.py
View file @
0b62bbb5
...
...
@@ -7,6 +7,7 @@ from fastapi import APIRouter
from
pydantic
import
BaseModel
import
time
import
uuid
import
logging
from
apps.web.models.users
import
UserModel
,
UserUpdateForm
,
UserRoleUpdateForm
,
Users
from
apps.web.models.auths
import
Auths
...
...
@@ -14,6 +15,10 @@ from apps.web.models.auths import Auths
from
utils.utils
import
get_current_user
,
get_password_hash
,
get_admin_user
from
constants
import
ERROR_MESSAGES
from
config
import
SRC_LOG_LEVELS
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MODELS"
])
router
=
APIRouter
()
############################
...
...
@@ -83,7 +88,7 @@ async def update_user_by_id(
if
form_data
.
password
:
hashed
=
get_password_hash
(
form_data
.
password
)
print
(
hashed
)
log
.
debug
(
f
"hashed:
{
hashed
}
"
)
Auths
.
update_user_password_by_id
(
user_id
,
hashed
)
Auths
.
update_email_by_id
(
user_id
,
form_data
.
email
.
lower
())
...
...
backend/config.py
View file @
0b62bbb5
import
json
import
os
import
shutil
import
sys
import
logging
import
chromadb
from
chromadb
import
Settings
from
base64
import
b64encode
from
bs4
import
BeautifulSoup
from
pathlib
import
Path
from
secrets
import
token_bytes
import
json
import
yaml
import
chromadb
import
markdown
import
requests
import
yam
l
from
bs4
import
BeautifulSoup
from
chromadb
import
Setting
s
import
shuti
l
from
secrets
import
token_byte
s
from
constants
import
ERROR_MESSAGES
try
:
from
dotenv
import
fin
d_dotenv
,
loa
d_dotenv
from
dotenv
import
loa
d_dotenv
,
fin
d_dotenv
load_dotenv
(
find_dotenv
(
"../.env"
))
except
ImportError
:
pr
in
t
(
"dotenv not installed, skipping..."
)
log
.
warn
in
g
(
"dotenv not installed, skipping..."
)
WEBUI_NAME
=
"Open WebUI"
WEBUI_FAVICON_URL
=
"https://openwebui.com/favicon.png"
...
...
@@ -98,6 +103,34 @@ for version in soup.find_all("h2"):
CHANGELOG
=
changelog_json
####################################
# LOGGING
####################################
log_levels
=
[
"CRITICAL"
,
"ERROR"
,
"WARNING"
,
"INFO"
,
"DEBUG"
]
GLOBAL_LOG_LEVEL
=
os
.
environ
.
get
(
"GLOBAL_LOG_LEVEL"
,
""
).
upper
()
if
GLOBAL_LOG_LEVEL
in
log_levels
:
logging
.
basicConfig
(
stream
=
sys
.
stdout
,
level
=
GLOBAL_LOG_LEVEL
,
force
=
True
)
else
:
GLOBAL_LOG_LEVEL
=
"INFO"
log
=
logging
.
getLogger
(
__name__
)
log
.
info
(
f
"GLOBAL_LOG_LEVEL:
{
GLOBAL_LOG_LEVEL
}
"
)
log_sources
=
[
"AUDIO"
,
"CONFIG"
,
"DB"
,
"IMAGES"
,
"LITELLM"
,
"MAIN"
,
"MODELS"
,
"OLLAMA"
,
"OPENAI"
,
"RAG"
]
SRC_LOG_LEVELS
=
{}
for
source
in
log_sources
:
log_env_var
=
source
+
"_LOG_LEVEL"
SRC_LOG_LEVELS
[
source
]
=
os
.
environ
.
get
(
log_env_var
,
""
).
upper
()
if
SRC_LOG_LEVELS
[
source
]
not
in
log_levels
:
SRC_LOG_LEVELS
[
source
]
=
GLOBAL_LOG_LEVEL
log
.
info
(
f
"
{
log_env_var
}
:
{
SRC_LOG_LEVELS
[
source
]
}
"
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"CONFIG"
])
####################################
# CUSTOM_NAME
####################################
...
...
@@ -123,7 +156,7 @@ if CUSTOM_NAME:
WEBUI_NAME
=
data
[
"name"
]
except
Exception
as
e
:
print
(
e
)
log
.
exception
(
e
)
pass
...
...
@@ -192,9 +225,9 @@ def create_config_file(file_path):
LITELLM_CONFIG_PATH
=
f
"
{
DATA_DIR
}
/litellm/config.yaml"
if
not
os
.
path
.
exists
(
LITELLM_CONFIG_PATH
):
print
(
"Config file doesn't exist. Creating..."
)
log
.
info
(
"Config file doesn't exist. Creating..."
)
create_config_file
(
LITELLM_CONFIG_PATH
)
print
(
"Config file created successfully."
)
log
.
info
(
"Config file created successfully."
)
####################################
...
...
@@ -206,7 +239,7 @@ OLLAMA_API_BASE_URL = os.environ.get(
)
OLLAMA_BASE_URL
=
os
.
environ
.
get
(
"OLLAMA_BASE_URL"
,
""
)
KUBERNETES_SERVICE_HOST
=
os
.
environ
.
get
(
"KUBERNETES_SERVICE_HOST"
,
""
)
if
OLLAMA_BASE_URL
==
""
and
OLLAMA_API_BASE_URL
!=
""
:
OLLAMA_BASE_URL
=
(
...
...
@@ -216,8 +249,10 @@ if OLLAMA_BASE_URL == "" and OLLAMA_API_BASE_URL != "":
)
if
ENV
==
"prod"
:
if
OLLAMA_BASE_URL
==
"/ollama"
:
if
OLLAMA_BASE_URL
==
"/ollama"
and
KUBERNETES_SERVICE_HOST
==
""
:
OLLAMA_BASE_URL
=
"http://host.docker.internal:11434"
else
:
OLLAMA_BASE_URL
=
"http://ollama-service.open-webui.svc.cluster.local:11434"
OLLAMA_BASE_URLS
=
os
.
environ
.
get
(
"OLLAMA_BASE_URLS"
,
""
)
...
...
backend/constants.py
View file @
0b62bbb5
...
...
@@ -60,3 +60,5 @@ class ERROR_MESSAGES(str, Enum):
MODEL_NOT_FOUND
=
lambda
name
=
""
:
f
"Model '
{
name
}
' was not found"
OPENAI_NOT_FOUND
=
lambda
name
=
""
:
f
"OpenAI API was not found"
OLLAMA_NOT_FOUND
=
"WebUI could not connect to Ollama"
EMPTY_CONTENT
=
"The content provided is empty. Please ensure that there is text or data present before proceeding."
backend/main.py
View file @
0b62bbb5
...
...
@@ -4,6 +4,7 @@ import markdown
import
time
import
os
import
sys
import
logging
import
requests
from
fastapi
import
FastAPI
,
Request
,
Depends
,
status
...
...
@@ -38,10 +39,15 @@ from config import (
FRONTEND_BUILD_DIR
,
MODEL_FILTER_ENABLED
,
MODEL_FILTER_LIST
,
GLOBAL_LOG_LEVEL
,
SRC_LOG_LEVELS
,
WEBHOOK_URL
,
)
from
constants
import
ERROR_MESSAGES
logging
.
basicConfig
(
stream
=
sys
.
stdout
,
level
=
GLOBAL_LOG_LEVEL
)
log
=
logging
.
getLogger
(
__name__
)
log
.
setLevel
(
SRC_LOG_LEVELS
[
"MAIN"
])
class
SPAStaticFiles
(
StaticFiles
):
async
def
get_response
(
self
,
path
:
str
,
scope
):
...
...
@@ -70,7 +76,7 @@ class RAGMiddleware(BaseHTTPMiddleware):
if
request
.
method
==
"POST"
and
(
"/api/chat"
in
request
.
url
.
path
or
"/chat/completions"
in
request
.
url
.
path
):
print
(
request
.
url
.
path
)
log
.
debug
(
f
"request.url.path:
{
request
.
url
.
path
}
"
)
# Read the original request body
body
=
await
request
.
body
()
...
...
@@ -93,7 +99,7 @@ class RAGMiddleware(BaseHTTPMiddleware):
)
del
data
[
"docs"
]
print
(
data
[
"
messages"
]
)
log
.
debug
(
f
"data['messages']:
{
data
[
'
messages
'
]
}
"
)
modified_body_bytes
=
json
.
dumps
(
data
).
encode
(
"utf-8"
)
...
...
kubernetes/manifest/base/webui-deployment.yaml
View file @
0b62bbb5
...
...
@@ -35,4 +35,4 @@ spec:
volumes
:
-
name
:
webui-volume
persistentVolumeClaim
:
claimName
:
ollama-webui-pvc
\ No newline at end of file
claimName
:
open-webui-pvc
\ No newline at end of file
kubernetes/manifest/base/webui-pvc.yaml
View file @
0b62bbb5
...
...
@@ -2,8 +2,8 @@ apiVersion: v1
kind
:
PersistentVolumeClaim
metadata
:
labels
:
app
:
o
llama
-webui
name
:
o
llama
-webui-pvc
app
:
o
pen
-webui
name
:
o
pen
-webui-pvc
namespace
:
open-webui
spec
:
accessModes
:
[
"
ReadWriteOnce"
]
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment