Skip to content

Commit

Permalink
Merge pull request open-webui#997 from open-webui/dev
Browse files Browse the repository at this point in the history
0.1.108
  • Loading branch information
tjbck authored Mar 3, 2024
2 parents 6c70d0f + 65804e6 commit eb51ad1
Show file tree
Hide file tree
Showing 28 changed files with 1,184 additions and 193 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ 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.108] - 2024-03-02

### Added

- **🎮 Playground Feature (Beta)**: Explore the full potential of the raw API through an intuitive UI with our new playground feature, accessible to admins. Simply click on the bottom name area of the sidebar to access it. The playground feature offers two modes text completion (notebook) and chat completion. As it's in beta, please report any issues you encounter.
- **🛠️ Direct Database Download for Admins**: Admins can now download the database directly from the WebUI via the admin settings.
- **🎨 Additional RAG Settings**: Customize your RAG process with the ability to edit the TOP K value. Navigate to Documents > Settings > General to make changes.
- **🖥️ UI Improvements**: Tooltips now available in the input area and sidebar handle. More tooltips will be added across other parts of the UI.

### Fixed

- Resolved input autofocus issue on mobile when the sidebar is open, making it easier to use.
- Corrected numbered list display issue in Safari (#963).
- Restricted user ability to delete chats without proper permissions (#993).

### Changed

- **Simplified Ollama Settings**: Ollama settings now don't require the `/api` suffix. You can now utilize the Ollama base URL directly, e.g., `http://localhost:11434`. Also, an `OLLAMA_BASE_URL` environment variable has been added.
- **Database Renaming**: Starting from this release, `ollama.db` will be automatically renamed to `webui.db`.

## [0.1.107] - 2024-03-01

### Added
Expand Down
23 changes: 15 additions & 8 deletions backend/apps/ollama/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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 config import OLLAMA_API_BASE_URL, WEBUI_AUTH
from config import OLLAMA_BASE_URL, WEBUI_AUTH

app = FastAPI()
app.add_middleware(
Expand All @@ -22,7 +22,7 @@
allow_headers=["*"],
)

app.state.OLLAMA_API_BASE_URL = OLLAMA_API_BASE_URL
app.state.OLLAMA_BASE_URL = OLLAMA_BASE_URL

# TARGET_SERVER_URL = OLLAMA_API_BASE_URL

Expand All @@ -32,7 +32,7 @@

@app.get("/url")
async def get_ollama_api_url(user=Depends(get_admin_user)):
return {"OLLAMA_API_BASE_URL": app.state.OLLAMA_API_BASE_URL}
return {"OLLAMA_BASE_URL": app.state.OLLAMA_BASE_URL}


class UrlUpdateForm(BaseModel):
Expand All @@ -41,8 +41,8 @@ class UrlUpdateForm(BaseModel):

@app.post("/url/update")
async def update_ollama_api_url(form_data: UrlUpdateForm, user=Depends(get_admin_user)):
app.state.OLLAMA_API_BASE_URL = form_data.url
return {"OLLAMA_API_BASE_URL": app.state.OLLAMA_API_BASE_URL}
app.state.OLLAMA_BASE_URL = form_data.url
return {"OLLAMA_BASE_URL": app.state.OLLAMA_BASE_URL}


@app.get("/cancel/{request_id}")
Expand All @@ -57,7 +57,7 @@ async def cancel_ollama_request(request_id: str, user=Depends(get_current_user))

@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy(path: str, request: Request, user=Depends(get_current_user)):
target_url = f"{app.state.OLLAMA_API_BASE_URL}/{path}"
target_url = f"{app.state.OLLAMA_BASE_URL}/{path}"

body = await request.body()
headers = dict(request.headers)
Expand Down Expand Up @@ -91,7 +91,13 @@ def get_request():

def stream_content():
try:
if path in ["chat"]:
if path == "generate":
data = json.loads(body.decode("utf-8"))

if not ("stream" in data and data["stream"] == False):
yield json.dumps({"id": request_id, "done": False}) + "\n"

elif path == "chat":
yield json.dumps({"id": request_id, "done": False}) + "\n"

for chunk in r.iter_content(chunk_size=8192):
Expand All @@ -103,7 +109,8 @@ def stream_content():
finally:
if hasattr(r, "close"):
r.close()
REQUEST_POOL.remove(request_id)
if request_id in REQUEST_POOL:
REQUEST_POOL.remove(request_id)

r = requests.request(
method=request.method,
Expand Down
48 changes: 34 additions & 14 deletions backend/apps/rag/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
app.state.CHUNK_OVERLAP = CHUNK_OVERLAP
app.state.RAG_TEMPLATE = RAG_TEMPLATE
app.state.RAG_EMBEDDING_MODEL = RAG_EMBEDDING_MODEL
app.state.TOP_K = 4

app.state.sentence_transformer_ef = (
embedding_functions.SentenceTransformerEmbeddingFunction(
model_name=app.state.RAG_EMBEDDING_MODEL,
Expand Down Expand Up @@ -210,23 +212,33 @@ async def get_rag_template(user=Depends(get_current_user)):
}


class RAGTemplateForm(BaseModel):
template: str
@app.get("/query/settings")
async def get_query_settings(user=Depends(get_admin_user)):
return {
"status": True,
"template": app.state.RAG_TEMPLATE,
"k": app.state.TOP_K,
}


@app.post("/template/update")
async def update_rag_template(form_data: RAGTemplateForm, user=Depends(get_admin_user)):
# TODO: check template requirements
app.state.RAG_TEMPLATE = (
form_data.template if form_data.template != "" else RAG_TEMPLATE
)
class QuerySettingsForm(BaseModel):
k: Optional[int] = None
template: Optional[str] = None


@app.post("/query/settings/update")
async def update_query_settings(
form_data: QuerySettingsForm, user=Depends(get_admin_user)
):
app.state.RAG_TEMPLATE = form_data.template if form_data.template else RAG_TEMPLATE
app.state.TOP_K = form_data.k if form_data.k else 4
return {"status": True, "template": app.state.RAG_TEMPLATE}


class QueryDocForm(BaseModel):
collection_name: str
query: str
k: Optional[int] = 4
k: Optional[int] = None


@app.post("/query/doc")
Expand All @@ -240,7 +252,10 @@ def query_doc(
name=form_data.collection_name,
embedding_function=app.state.sentence_transformer_ef,
)
result = collection.query(query_texts=[form_data.query], n_results=form_data.k)
result = collection.query(
query_texts=[form_data.query],
n_results=form_data.k if form_data.k else app.state.TOP_K,
)
return result
except Exception as e:
print(e)
Expand All @@ -253,7 +268,7 @@ def query_doc(
class QueryCollectionsForm(BaseModel):
collection_names: List[str]
query: str
k: Optional[int] = 4
k: Optional[int] = None


def merge_and_sort_query_results(query_results, k):
Expand Down Expand Up @@ -317,13 +332,16 @@ def query_collection(
)

result = collection.query(
query_texts=[form_data.query], n_results=form_data.k
query_texts=[form_data.query],
n_results=form_data.k if form_data.k else app.state.TOP_K,
)
results.append(result)
except:
pass

return merge_and_sort_query_results(results, form_data.k)
return merge_and_sort_query_results(
results, form_data.k if form_data.k else app.state.TOP_K
)


@app.post("/web")
Expand Down Expand Up @@ -423,7 +441,9 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
] or file_ext in ["xls", "xlsx"]:
loader = UnstructuredExcelLoader(file_path)
elif file_ext in known_source_ext or (file_content_type and file_content_type.find("text/") >= 0):
elif file_ext in known_source_ext or (
file_content_type and file_content_type.find("text/") >= 0
):
loader = TextLoader(file_path)
else:
loader = TextLoader(file_path)
Expand Down
12 changes: 11 additions & 1 deletion backend/apps/web/internal/db.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from peewee import *
from config import DATA_DIR
import os


DB = SqliteDatabase(f"{DATA_DIR}/ollama.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.")
else:
pass


DB = SqliteDatabase(f"{DATA_DIR}/webui.db")
DB.connect()
12 changes: 11 additions & 1 deletion backend/apps/web/routers/chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ async def delete_all_chat_tags_by_id(id: str, user=Depends(get_current_user)):


@router.delete("/", response_model=bool)
async def delete_all_user_chats(user=Depends(get_current_user)):
async def delete_all_user_chats(request: Request, user=Depends(get_current_user)):

if (
user.role == "user"
and not request.app.state.USER_PERMISSIONS["chat"]["deletion"]
):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
)

result = Chats.delete_chats_by_user_id(user.id)
return result
15 changes: 14 additions & 1 deletion backend/apps/web/routers/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from fastapi import APIRouter, UploadFile, File, BackgroundTasks
from fastapi import Depends, HTTPException, status
from starlette.responses import StreamingResponse
from starlette.responses import StreamingResponse, FileResponse


from pydantic import BaseModel

Expand All @@ -9,6 +10,8 @@
import aiohttp
import json


from utils.utils import get_admin_user
from utils.misc import calculate_sha256, get_gravatar_url

from config import OLLAMA_API_BASE_URL, DATA_DIR, UPLOAD_DIR
Expand Down Expand Up @@ -172,3 +175,13 @@ async def get_gravatar(
email: str,
):
return get_gravatar_url(email)


@router.get("/db/download")
async def download_db(user=Depends(get_admin_user)):

return FileResponse(
f"{DATA_DIR}/webui.db",
media_type="application/octet-stream",
filename="webui.db",
)
13 changes: 12 additions & 1 deletion backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ def create_config_file(file_path):
if OLLAMA_API_BASE_URL == "/ollama/api":
OLLAMA_API_BASE_URL = "http://host.docker.internal:11434/api"


OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "")

if OLLAMA_BASE_URL == "":
OLLAMA_BASE_URL = (
OLLAMA_API_BASE_URL[:-4]
if OLLAMA_API_BASE_URL.endswith("/api")
else OLLAMA_API_BASE_URL
)


####################################
# OPENAI_API
####################################
Expand All @@ -226,7 +237,7 @@ def create_config_file(file_path):
# WEBUI
####################################

ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", True)
ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "True").lower() == "true"
DEFAULT_MODELS = os.environ.get("DEFAULT_MODELS", None)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "open-webui",
"version": "0.1.107",
"version": "0.1.108",
"private": true,
"scripts": {
"dev": "vite dev --host",
Expand Down
15 changes: 15 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ math {
@apply rounded-lg;
}

ol > li {
counter-increment: list-number;
display: block;
margin-bottom: 0;
margin-top: 0;
min-height: 28px;
}

.prose ol > li::before {
content: counters(list-number, '.') '.';
padding-right: 0.5rem;
color: var(--tw-prose-counters);
font-weight: 400;
}

::-webkit-scrollbar-thumb {
--tw-border-opacity: 1;
background-color: rgba(217, 217, 227, 0.8);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/apis/chats/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ export const deleteAllChats = async (token: string) => {
return json;
})
.catch((err) => {
error = err;
error = err.detail;

console.log(err);
return null;
Expand Down
Loading

0 comments on commit eb51ad1

Please sign in to comment.