olipericles commited on
Commit
f74d20b
·
1 Parent(s): df79f19

Open WebUI

Browse files
.env DELETED
@@ -1,24 +0,0 @@
1
- # Chave de API do Langchain (Langsmith)
2
- LANGCHAIN_API_KEY=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
3
- LANGCHAIN_PROJECT=ChatBotando
4
-
5
- # Chave de API do Langwatch
6
- LANGWATCH_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3MjE0OTEzMDUxMzcsInJhbmQiOjAuMDc2MDY1MTI5OTgxODExNTksImlhdCI6MTcyMTQ5MTMwNX0.XlFLvpB7O3g976GXNOD3_Bc4L1FgFX-vMDVwTs94DTU
7
-
8
- # Configurações do Langflow
9
- USER_AGENT="ChatBotando"
10
- LANGFLOW_STORE_ENVIRONMENT_VARIABLES = true # Se as variáveis de ambiente devem ser acessíveis no Langflow
11
- LANGFLOW_CONFIG_DIR=langflow # Diretório de configuração do Langflow
12
- LANGFLOW_DATABASE_URL=postgresql://langflow:langflow_password@postgres:5432/langflow # URL do banco de dados do Langflow
13
- LANGFLOW_AUTO_LOGIN=false # Se o usuário deve ser logado automaticamente
14
- LANGFLOW_SUPERUSER=admin # Usuário superuser do Langflow
15
- LANGFLOW_SUPERUSER_PASSWORD=f80b00xXE59NiT895HEs # Senha do usuário superuser do Langflow
16
-
17
- # Configurações do WebUI
18
- WEBUI_NAME="ChatBotando" # Nome do WebUI
19
- DATABASE_URL=postgresql://webui:webui_password@postgres:5432/webui # URL do banco de dados do WebUI
20
-
21
-
22
- # Configurações do banco de dados
23
- POSTGRES_USER=postgres # Usuário do banco de dados
24
- POSTGRES_PASSWORD=1kj2k31nv9@jd # Senha do banco de dados
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore DELETED
@@ -1,2 +0,0 @@
1
- # Chave de API do OpenAI
2
- OPENAI_API_KEY = sk-proj-Vmx1AKmiRm8fOxXE59NiT3BlbkFJiLSiVfdelxqciOpHEsbk
 
 
 
Dockerfile ADDED
@@ -0,0 +1 @@
 
 
1
+ FROM ghcr.io/open-webui/open-webui:main
docker-compose.yaml DELETED
@@ -1,46 +0,0 @@
1
- services:
2
- webui:
3
- image: ghcr.io/open-webui/open-webui:main
4
- pull_policy: always
5
- restart: always
6
- volumes:
7
- - ./open-webui/config/config.py:/app/backend/config.py
8
- - ./open-webui/images/favicon.png:/app/build/static/favicon.png
9
- - ./open-webui/images/favicon.png:/app/build/favicon.png
10
- - ./open-webui/_data:/app/backend/data
11
- ports:
12
- - 8081:8080 # Expondo o Open WebUI em uma porta diferente para evitar conflito com o Langflow
13
- env_file:
14
- - .env
15
- depends_on:
16
- - langflow
17
- - postgres
18
-
19
- langflow:
20
- image: langflowai/langflow:latest
21
- pull_policy: always
22
- restart: always
23
- volumes:
24
- - ./langflow/data:/app/langflow
25
- ports:
26
- - 7860:7860 # Porta principal que o Hugging Face Spaces usará
27
- env_file:
28
- - .env
29
- depends_on:
30
- - postgres
31
- user: "1000:1000"
32
-
33
- postgres:
34
- image: postgres:16
35
- pull_policy: always
36
- restart: always
37
- ports:
38
- - "5432:5432"
39
- volumes:
40
- - ./postgres:/var/lib/postgresql/data
41
- - ./postgres/initdb:/docker-entrypoint-initdb.d
42
- env_file:
43
- - .env
44
- environment:
45
- POSTGRES_USER: ${POSTGRES_USER}
46
- POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
langflow/data/secret_key DELETED
@@ -1 +0,0 @@
1
- mHtk0oRA2hAtSF8y8FAD-J7oPsNNWFbpvFBExdIomgE
 
 
open-webui/_data/vector_db/chroma.sqlite3 DELETED
Binary file (156 kB)
 
open-webui/config/config.py DELETED
@@ -1,1431 +0,0 @@
1
- import os
2
- import sys
3
- import logging
4
- import importlib.metadata
5
- import pkgutil
6
- import chromadb
7
- from chromadb import Settings
8
- from bs4 import BeautifulSoup
9
- from typing import TypeVar, Generic
10
- from pydantic import BaseModel
11
- from typing import Optional
12
-
13
- from pathlib import Path
14
- import json
15
- import yaml
16
-
17
- import markdown
18
- import requests
19
- import shutil
20
-
21
- from constants import ERROR_MESSAGES
22
-
23
- ####################################
24
- # Load .env file
25
- ####################################
26
-
27
- BACKEND_DIR = Path(__file__).parent # the path containing this file
28
- BASE_DIR = BACKEND_DIR.parent # the path containing the backend/
29
-
30
- print(BASE_DIR)
31
-
32
- try:
33
- from dotenv import load_dotenv, find_dotenv
34
-
35
- load_dotenv(find_dotenv(str(BASE_DIR / ".env")))
36
- except ImportError:
37
- print("dotenv not installed, skipping...")
38
-
39
-
40
- ####################################
41
- # LOGGING
42
- ####################################
43
-
44
- log_levels = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
45
-
46
- GLOBAL_LOG_LEVEL = os.environ.get("GLOBAL_LOG_LEVEL", "").upper()
47
- if GLOBAL_LOG_LEVEL in log_levels:
48
- logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL, force=True)
49
- else:
50
- GLOBAL_LOG_LEVEL = "INFO"
51
-
52
- log = logging.getLogger(__name__)
53
- log.info(f"GLOBAL_LOG_LEVEL: {GLOBAL_LOG_LEVEL}")
54
-
55
- log_sources = [
56
- "AUDIO",
57
- "COMFYUI",
58
- "CONFIG",
59
- "DB",
60
- "IMAGES",
61
- "MAIN",
62
- "MODELS",
63
- "OLLAMA",
64
- "OPENAI",
65
- "RAG",
66
- "WEBHOOK",
67
- ]
68
-
69
- SRC_LOG_LEVELS = {}
70
-
71
- for source in log_sources:
72
- log_env_var = source + "_LOG_LEVEL"
73
- SRC_LOG_LEVELS[source] = os.environ.get(log_env_var, "").upper()
74
- if SRC_LOG_LEVELS[source] not in log_levels:
75
- SRC_LOG_LEVELS[source] = GLOBAL_LOG_LEVEL
76
- log.info(f"{log_env_var}: {SRC_LOG_LEVELS[source]}")
77
-
78
- log.setLevel(SRC_LOG_LEVELS["CONFIG"])
79
-
80
-
81
- class EndpointFilter(logging.Filter):
82
- def filter(self, record: logging.LogRecord) -> bool:
83
- return record.getMessage().find("/health") == -1
84
-
85
-
86
- # Filter out /endpoint
87
- logging.getLogger("uvicorn.access").addFilter(EndpointFilter())
88
-
89
-
90
- WEBUI_NAME = os.environ.get("WEBUI_NAME", "Open WebUI")
91
- if WEBUI_NAME != "Open WebUI":
92
- WEBUI_NAME += " (Open WebUI)"
93
-
94
- WEBUI_URL = os.environ.get("WEBUI_URL", "http://localhost:3000")
95
- WEBUI_NAME = "ChatBotando"
96
- WEBUI_FAVICON_URL = "/app/build/favicon.png"
97
-
98
-
99
- ####################################
100
- # ENV (dev,test,prod)
101
- ####################################
102
-
103
- ENV = os.environ.get("ENV", "dev")
104
-
105
- try:
106
- PACKAGE_DATA = json.loads((BASE_DIR / "package.json").read_text())
107
- except Exception:
108
- try:
109
- PACKAGE_DATA = {"version": importlib.metadata.version("open-webui")}
110
- except importlib.metadata.PackageNotFoundError:
111
- PACKAGE_DATA = {"version": "0.0.0"}
112
-
113
- VERSION = PACKAGE_DATA["version"]
114
-
115
-
116
- # Function to parse each section
117
- def parse_section(section):
118
- items = []
119
- for li in section.find_all("li"):
120
- # Extract raw HTML string
121
- raw_html = str(li)
122
-
123
- # Extract text without HTML tags
124
- text = li.get_text(separator=" ", strip=True)
125
-
126
- # Split into title and content
127
- parts = text.split(": ", 1)
128
- title = parts[0].strip() if len(parts) > 1 else ""
129
- content = parts[1].strip() if len(parts) > 1 else text
130
-
131
- items.append({"title": title, "content": content, "raw": raw_html})
132
- return items
133
-
134
-
135
- try:
136
- changelog_path = BASE_DIR / "CHANGELOG.md"
137
- with open(str(changelog_path.absolute()), "r", encoding="utf8") as file:
138
- changelog_content = file.read()
139
-
140
- except Exception:
141
- changelog_content = (pkgutil.get_data("open_webui", "CHANGELOG.md") or b"").decode()
142
-
143
-
144
- # Convert markdown content to HTML
145
- html_content = markdown.markdown(changelog_content)
146
-
147
- # Parse the HTML content
148
- soup = BeautifulSoup(html_content, "html.parser")
149
-
150
- # Initialize JSON structure
151
- changelog_json = {}
152
-
153
- # Iterate over each version
154
- for version in soup.find_all("h2"):
155
- version_number = version.get_text().strip().split(" - ")[0][1:-1] # Remove brackets
156
- date = version.get_text().strip().split(" - ")[1]
157
-
158
- version_data = {"date": date}
159
-
160
- # Find the next sibling that is a h3 tag (section title)
161
- current = version.find_next_sibling()
162
-
163
- while current and current.name != "h2":
164
- if current.name == "h3":
165
- section_title = current.get_text().lower() # e.g., "added", "fixed"
166
- section_items = parse_section(current.find_next_sibling("ul"))
167
- version_data[section_title] = section_items
168
-
169
- # Move to the next element
170
- current = current.find_next_sibling()
171
-
172
- changelog_json[version_number] = version_data
173
-
174
-
175
- CHANGELOG = changelog_json
176
-
177
-
178
- ####################################
179
- # SAFE_MODE
180
- ####################################
181
-
182
- SAFE_MODE = os.environ.get("SAFE_MODE", "false").lower() == "true"
183
-
184
- ####################################
185
- # WEBUI_BUILD_HASH
186
- ####################################
187
-
188
- WEBUI_BUILD_HASH = os.environ.get("WEBUI_BUILD_HASH", "dev-build")
189
-
190
- ####################################
191
- # DATA/FRONTEND BUILD DIR
192
- ####################################
193
-
194
- DATA_DIR = Path(os.getenv("DATA_DIR", BACKEND_DIR / "data")).resolve()
195
- FRONTEND_BUILD_DIR = Path(os.getenv("FRONTEND_BUILD_DIR", BASE_DIR / "build")).resolve()
196
-
197
- RESET_CONFIG_ON_START = (
198
- os.environ.get("RESET_CONFIG_ON_START", "False").lower() == "true"
199
- )
200
- if RESET_CONFIG_ON_START:
201
- try:
202
- os.remove(f"{DATA_DIR}/config.json")
203
- with open(f"{DATA_DIR}/config.json", "w") as f:
204
- f.write("{}")
205
- except Exception:
206
- pass
207
-
208
- try:
209
- CONFIG_DATA = json.loads((DATA_DIR / "config.json").read_text())
210
- except Exception:
211
- CONFIG_DATA = {}
212
-
213
-
214
- ####################################
215
- # Config helpers
216
- ####################################
217
-
218
-
219
- def save_config():
220
- try:
221
- with open(f"{DATA_DIR}/config.json", "w") as f:
222
- json.dump(CONFIG_DATA, f, indent="\t")
223
- except Exception as e:
224
- log.exception(e)
225
-
226
-
227
- def get_config_value(config_path: str):
228
- path_parts = config_path.split(".")
229
- cur_config = CONFIG_DATA
230
- for key in path_parts:
231
- if key in cur_config:
232
- cur_config = cur_config[key]
233
- else:
234
- return None
235
- return cur_config
236
-
237
-
238
- T = TypeVar("T")
239
-
240
-
241
- class PersistentConfig(Generic[T]):
242
- def __init__(self, env_name: str, config_path: str, env_value: T):
243
- self.env_name = env_name
244
- self.config_path = config_path
245
- self.env_value = env_value
246
- self.config_value = get_config_value(config_path)
247
- if self.config_value is not None:
248
- log.info(f"'{env_name}' loaded from config.json")
249
- self.value = self.config_value
250
- else:
251
- self.value = env_value
252
-
253
- def __str__(self):
254
- return str(self.value)
255
-
256
- @property
257
- def __dict__(self):
258
- raise TypeError(
259
- "PersistentConfig object cannot be converted to dict, use config_get or .value instead."
260
- )
261
-
262
- def __getattribute__(self, item):
263
- if item == "__dict__":
264
- raise TypeError(
265
- "PersistentConfig object cannot be converted to dict, use config_get or .value instead."
266
- )
267
- return super().__getattribute__(item)
268
-
269
- def save(self):
270
- # Don't save if the value is the same as the env value and the config value
271
- if self.env_value == self.value:
272
- if self.config_value == self.value:
273
- return
274
- log.info(f"Saving '{self.env_name}' to config.json")
275
- path_parts = self.config_path.split(".")
276
- config = CONFIG_DATA
277
- for key in path_parts[:-1]:
278
- if key not in config:
279
- config[key] = {}
280
- config = config[key]
281
- config[path_parts[-1]] = self.value
282
- save_config()
283
- self.config_value = self.value
284
-
285
-
286
- class AppConfig:
287
- _state: dict[str, PersistentConfig]
288
-
289
- def __init__(self):
290
- super().__setattr__("_state", {})
291
-
292
- def __setattr__(self, key, value):
293
- if isinstance(value, PersistentConfig):
294
- self._state[key] = value
295
- else:
296
- self._state[key].value = value
297
- self._state[key].save()
298
-
299
- def __getattr__(self, key):
300
- return self._state[key].value
301
-
302
-
303
- ####################################
304
- # WEBUI_AUTH (Required for security)
305
- ####################################
306
-
307
- WEBUI_AUTH = os.environ.get("WEBUI_AUTH", "True").lower() == "true"
308
- WEBUI_AUTH_TRUSTED_EMAIL_HEADER = os.environ.get(
309
- "WEBUI_AUTH_TRUSTED_EMAIL_HEADER", None
310
- )
311
- WEBUI_AUTH_TRUSTED_NAME_HEADER = os.environ.get("WEBUI_AUTH_TRUSTED_NAME_HEADER", None)
312
- JWT_EXPIRES_IN = PersistentConfig(
313
- "JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "-1")
314
- )
315
-
316
- ####################################
317
- # OAuth config
318
- ####################################
319
-
320
- ENABLE_OAUTH_SIGNUP = PersistentConfig(
321
- "ENABLE_OAUTH_SIGNUP",
322
- "oauth.enable_signup",
323
- os.environ.get("ENABLE_OAUTH_SIGNUP", "False").lower() == "true",
324
- )
325
-
326
- OAUTH_MERGE_ACCOUNTS_BY_EMAIL = PersistentConfig(
327
- "OAUTH_MERGE_ACCOUNTS_BY_EMAIL",
328
- "oauth.merge_accounts_by_email",
329
- os.environ.get("OAUTH_MERGE_ACCOUNTS_BY_EMAIL", "False").lower() == "true",
330
- )
331
-
332
- OAUTH_PROVIDERS = {}
333
-
334
- GOOGLE_CLIENT_ID = PersistentConfig(
335
- "GOOGLE_CLIENT_ID",
336
- "oauth.google.client_id",
337
- os.environ.get("GOOGLE_CLIENT_ID", ""),
338
- )
339
-
340
- GOOGLE_CLIENT_SECRET = PersistentConfig(
341
- "GOOGLE_CLIENT_SECRET",
342
- "oauth.google.client_secret",
343
- os.environ.get("GOOGLE_CLIENT_SECRET", ""),
344
- )
345
-
346
- GOOGLE_OAUTH_SCOPE = PersistentConfig(
347
- "GOOGLE_OAUTH_SCOPE",
348
- "oauth.google.scope",
349
- os.environ.get("GOOGLE_OAUTH_SCOPE", "openid email profile"),
350
- )
351
-
352
- GOOGLE_REDIRECT_URI = PersistentConfig(
353
- "GOOGLE_REDIRECT_URI",
354
- "oauth.google.redirect_uri",
355
- os.environ.get("GOOGLE_REDIRECT_URI", ""),
356
- )
357
-
358
- MICROSOFT_CLIENT_ID = PersistentConfig(
359
- "MICROSOFT_CLIENT_ID",
360
- "oauth.microsoft.client_id",
361
- os.environ.get("MICROSOFT_CLIENT_ID", ""),
362
- )
363
-
364
- MICROSOFT_CLIENT_SECRET = PersistentConfig(
365
- "MICROSOFT_CLIENT_SECRET",
366
- "oauth.microsoft.client_secret",
367
- os.environ.get("MICROSOFT_CLIENT_SECRET", ""),
368
- )
369
-
370
- MICROSOFT_CLIENT_TENANT_ID = PersistentConfig(
371
- "MICROSOFT_CLIENT_TENANT_ID",
372
- "oauth.microsoft.tenant_id",
373
- os.environ.get("MICROSOFT_CLIENT_TENANT_ID", ""),
374
- )
375
-
376
- MICROSOFT_OAUTH_SCOPE = PersistentConfig(
377
- "MICROSOFT_OAUTH_SCOPE",
378
- "oauth.microsoft.scope",
379
- os.environ.get("MICROSOFT_OAUTH_SCOPE", "openid email profile"),
380
- )
381
-
382
- MICROSOFT_REDIRECT_URI = PersistentConfig(
383
- "MICROSOFT_REDIRECT_URI",
384
- "oauth.microsoft.redirect_uri",
385
- os.environ.get("MICROSOFT_REDIRECT_URI", ""),
386
- )
387
-
388
- OAUTH_CLIENT_ID = PersistentConfig(
389
- "OAUTH_CLIENT_ID",
390
- "oauth.oidc.client_id",
391
- os.environ.get("OAUTH_CLIENT_ID", ""),
392
- )
393
-
394
- OAUTH_CLIENT_SECRET = PersistentConfig(
395
- "OAUTH_CLIENT_SECRET",
396
- "oauth.oidc.client_secret",
397
- os.environ.get("OAUTH_CLIENT_SECRET", ""),
398
- )
399
-
400
- OPENID_PROVIDER_URL = PersistentConfig(
401
- "OPENID_PROVIDER_URL",
402
- "oauth.oidc.provider_url",
403
- os.environ.get("OPENID_PROVIDER_URL", ""),
404
- )
405
-
406
- OPENID_REDIRECT_URI = PersistentConfig(
407
- "OPENID_REDIRECT_URI",
408
- "oauth.oidc.redirect_uri",
409
- os.environ.get("OPENID_REDIRECT_URI", ""),
410
- )
411
-
412
- OAUTH_SCOPES = PersistentConfig(
413
- "OAUTH_SCOPES",
414
- "oauth.oidc.scopes",
415
- os.environ.get("OAUTH_SCOPES", "openid email profile"),
416
- )
417
-
418
- OAUTH_PROVIDER_NAME = PersistentConfig(
419
- "OAUTH_PROVIDER_NAME",
420
- "oauth.oidc.provider_name",
421
- os.environ.get("OAUTH_PROVIDER_NAME", "SSO"),
422
- )
423
-
424
- OAUTH_USERNAME_CLAIM = PersistentConfig(
425
- "OAUTH_USERNAME_CLAIM",
426
- "oauth.oidc.username_claim",
427
- os.environ.get("OAUTH_USERNAME_CLAIM", "name"),
428
- )
429
-
430
- OAUTH_PICTURE_CLAIM = PersistentConfig(
431
- "OAUTH_USERNAME_CLAIM",
432
- "oauth.oidc.avatar_claim",
433
- os.environ.get("OAUTH_PICTURE_CLAIM", "picture"),
434
- )
435
-
436
- OAUTH_EMAIL_CLAIM = PersistentConfig(
437
- "OAUTH_EMAIL_CLAIM",
438
- "oauth.oidc.email_claim",
439
- os.environ.get("OAUTH_EMAIL_CLAIM", "email"),
440
- )
441
-
442
-
443
- def load_oauth_providers():
444
- OAUTH_PROVIDERS.clear()
445
- if GOOGLE_CLIENT_ID.value and GOOGLE_CLIENT_SECRET.value:
446
- OAUTH_PROVIDERS["google"] = {
447
- "client_id": GOOGLE_CLIENT_ID.value,
448
- "client_secret": GOOGLE_CLIENT_SECRET.value,
449
- "server_metadata_url": "https://accounts.google.com/.well-known/openid-configuration",
450
- "scope": GOOGLE_OAUTH_SCOPE.value,
451
- "redirect_uri": GOOGLE_REDIRECT_URI.value,
452
- }
453
-
454
- if (
455
- MICROSOFT_CLIENT_ID.value
456
- and MICROSOFT_CLIENT_SECRET.value
457
- and MICROSOFT_CLIENT_TENANT_ID.value
458
- ):
459
- OAUTH_PROVIDERS["microsoft"] = {
460
- "client_id": MICROSOFT_CLIENT_ID.value,
461
- "client_secret": MICROSOFT_CLIENT_SECRET.value,
462
- "server_metadata_url": f"https://login.microsoftonline.com/{MICROSOFT_CLIENT_TENANT_ID.value}/v2.0/.well-known/openid-configuration",
463
- "scope": MICROSOFT_OAUTH_SCOPE.value,
464
- "redirect_uri": MICROSOFT_REDIRECT_URI.value,
465
- }
466
-
467
- if (
468
- OAUTH_CLIENT_ID.value
469
- and OAUTH_CLIENT_SECRET.value
470
- and OPENID_PROVIDER_URL.value
471
- ):
472
- OAUTH_PROVIDERS["oidc"] = {
473
- "client_id": OAUTH_CLIENT_ID.value,
474
- "client_secret": OAUTH_CLIENT_SECRET.value,
475
- "server_metadata_url": OPENID_PROVIDER_URL.value,
476
- "scope": OAUTH_SCOPES.value,
477
- "name": OAUTH_PROVIDER_NAME.value,
478
- "redirect_uri": OPENID_REDIRECT_URI.value,
479
- }
480
-
481
-
482
- load_oauth_providers()
483
-
484
- ####################################
485
- # Static DIR
486
- ####################################
487
-
488
- STATIC_DIR = Path(os.getenv("STATIC_DIR", BACKEND_DIR / "static")).resolve()
489
-
490
- frontend_favicon = FRONTEND_BUILD_DIR / "static" / "favicon.png"
491
-
492
- if frontend_favicon.exists():
493
- try:
494
- shutil.copyfile(frontend_favicon, STATIC_DIR / "favicon.png")
495
- except Exception as e:
496
- logging.error(f"An error occurred: {e}")
497
- else:
498
- logging.warning(f"Frontend favicon not found at {frontend_favicon}")
499
-
500
- frontend_splash = FRONTEND_BUILD_DIR / "static" / "splash.png"
501
-
502
- if frontend_splash.exists():
503
- try:
504
- shutil.copyfile(frontend_splash, STATIC_DIR / "splash.png")
505
- except Exception as e:
506
- logging.error(f"An error occurred: {e}")
507
- else:
508
- logging.warning(f"Frontend splash not found at {frontend_splash}")
509
-
510
-
511
- ####################################
512
- # CUSTOM_NAME
513
- ####################################
514
-
515
- CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "")
516
-
517
- if CUSTOM_NAME:
518
- try:
519
- r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}")
520
- data = r.json()
521
- if r.ok:
522
- if "logo" in data:
523
- WEBUI_FAVICON_URL = url = (
524
- f"https://api.openwebui.com{data['logo']}"
525
- if data["logo"][0] == "/"
526
- else data["logo"]
527
- )
528
-
529
- r = requests.get(url, stream=True)
530
- if r.status_code == 200:
531
- with open(f"{STATIC_DIR}/favicon.png", "wb") as f:
532
- r.raw.decode_content = True
533
- shutil.copyfileobj(r.raw, f)
534
-
535
- if "splash" in data:
536
- url = (
537
- f"https://api.openwebui.com{data['splash']}"
538
- if data["splash"][0] == "/"
539
- else data["splash"]
540
- )
541
-
542
- r = requests.get(url, stream=True)
543
- if r.status_code == 200:
544
- with open(f"{STATIC_DIR}/splash.png", "wb") as f:
545
- r.raw.decode_content = True
546
- shutil.copyfileobj(r.raw, f)
547
-
548
- WEBUI_NAME = data["name"]
549
- except Exception as e:
550
- log.exception(e)
551
- pass
552
-
553
-
554
- ####################################
555
- # File Upload DIR
556
- ####################################
557
-
558
- UPLOAD_DIR = f"{DATA_DIR}/uploads"
559
- Path(UPLOAD_DIR).mkdir(parents=True, exist_ok=True)
560
-
561
-
562
- ####################################
563
- # Cache DIR
564
- ####################################
565
-
566
- CACHE_DIR = f"{DATA_DIR}/cache"
567
- Path(CACHE_DIR).mkdir(parents=True, exist_ok=True)
568
-
569
-
570
- ####################################
571
- # Docs DIR
572
- ####################################
573
-
574
- DOCS_DIR = os.getenv("DOCS_DIR", f"{DATA_DIR}/docs")
575
- Path(DOCS_DIR).mkdir(parents=True, exist_ok=True)
576
-
577
-
578
- ####################################
579
- # Tools DIR
580
- ####################################
581
-
582
- TOOLS_DIR = os.getenv("TOOLS_DIR", f"{DATA_DIR}/tools")
583
- Path(TOOLS_DIR).mkdir(parents=True, exist_ok=True)
584
-
585
-
586
- ####################################
587
- # Functions DIR
588
- ####################################
589
-
590
- FUNCTIONS_DIR = os.getenv("FUNCTIONS_DIR", f"{DATA_DIR}/functions")
591
- Path(FUNCTIONS_DIR).mkdir(parents=True, exist_ok=True)
592
-
593
-
594
- ####################################
595
- # LITELLM_CONFIG
596
- ####################################
597
-
598
-
599
- def create_config_file(file_path):
600
- directory = os.path.dirname(file_path)
601
-
602
- # Check if directory exists, if not, create it
603
- if not os.path.exists(directory):
604
- os.makedirs(directory)
605
-
606
- # Data to write into the YAML file
607
- config_data = {
608
- "general_settings": {},
609
- "litellm_settings": {},
610
- "model_list": [],
611
- "router_settings": {},
612
- }
613
-
614
- # Write data to YAML file
615
- with open(file_path, "w") as file:
616
- yaml.dump(config_data, file)
617
-
618
-
619
- LITELLM_CONFIG_PATH = f"{DATA_DIR}/litellm/config.yaml"
620
-
621
- # if not os.path.exists(LITELLM_CONFIG_PATH):
622
- # log.info("Config file doesn't exist. Creating...")
623
- # create_config_file(LITELLM_CONFIG_PATH)
624
- # log.info("Config file created successfully.")
625
-
626
-
627
- ####################################
628
- # OLLAMA_BASE_URL
629
- ####################################
630
-
631
-
632
- ENABLE_OLLAMA_API = PersistentConfig(
633
- "ENABLE_OLLAMA_API",
634
- "ollama.enable",
635
- os.environ.get("ENABLE_OLLAMA_API", "True").lower() == "true",
636
- )
637
-
638
- OLLAMA_API_BASE_URL = os.environ.get(
639
- "OLLAMA_API_BASE_URL", "http://localhost:11434/api"
640
- )
641
-
642
- OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "")
643
- AIOHTTP_CLIENT_TIMEOUT = os.environ.get("AIOHTTP_CLIENT_TIMEOUT", "")
644
-
645
- if AIOHTTP_CLIENT_TIMEOUT == "":
646
- AIOHTTP_CLIENT_TIMEOUT = None
647
- else:
648
- try:
649
- AIOHTTP_CLIENT_TIMEOUT = int(AIOHTTP_CLIENT_TIMEOUT)
650
- except Exception:
651
- AIOHTTP_CLIENT_TIMEOUT = 300
652
-
653
-
654
- K8S_FLAG = os.environ.get("K8S_FLAG", "")
655
- USE_OLLAMA_DOCKER = os.environ.get("USE_OLLAMA_DOCKER", "false")
656
-
657
- if OLLAMA_BASE_URL == "" and OLLAMA_API_BASE_URL != "":
658
- OLLAMA_BASE_URL = (
659
- OLLAMA_API_BASE_URL[:-4]
660
- if OLLAMA_API_BASE_URL.endswith("/api")
661
- else OLLAMA_API_BASE_URL
662
- )
663
-
664
- if ENV == "prod":
665
- if OLLAMA_BASE_URL == "/ollama" and not K8S_FLAG:
666
- if USE_OLLAMA_DOCKER.lower() == "true":
667
- # if you use all-in-one docker container (Open WebUI + Ollama)
668
- # with the docker build arg USE_OLLAMA=true (--build-arg="USE_OLLAMA=true") this only works with http://localhost:11434
669
- OLLAMA_BASE_URL = "http://localhost:11434"
670
- else:
671
- OLLAMA_BASE_URL = "http://host.docker.internal:11434"
672
- elif K8S_FLAG:
673
- OLLAMA_BASE_URL = "http://ollama-service.open-webui.svc.cluster.local:11434"
674
-
675
-
676
- OLLAMA_BASE_URLS = os.environ.get("OLLAMA_BASE_URLS", "")
677
- OLLAMA_BASE_URLS = OLLAMA_BASE_URLS if OLLAMA_BASE_URLS != "" else OLLAMA_BASE_URL
678
-
679
- OLLAMA_BASE_URLS = [url.strip() for url in OLLAMA_BASE_URLS.split(";")]
680
- OLLAMA_BASE_URLS = PersistentConfig(
681
- "OLLAMA_BASE_URLS", "ollama.base_urls", OLLAMA_BASE_URLS
682
- )
683
-
684
- ####################################
685
- # OPENAI_API
686
- ####################################
687
-
688
-
689
- ENABLE_OPENAI_API = PersistentConfig(
690
- "ENABLE_OPENAI_API",
691
- "openai.enable",
692
- os.environ.get("ENABLE_OPENAI_API", "True").lower() == "true",
693
- )
694
-
695
-
696
- OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
697
- OPENAI_API_BASE_URL = os.environ.get("OPENAI_API_BASE_URL", "")
698
-
699
-
700
- if OPENAI_API_BASE_URL == "":
701
- OPENAI_API_BASE_URL = "https://api.openai.com/v1"
702
-
703
- OPENAI_API_KEYS = os.environ.get("OPENAI_API_KEYS", "")
704
- OPENAI_API_KEYS = OPENAI_API_KEYS if OPENAI_API_KEYS != "" else OPENAI_API_KEY
705
-
706
- OPENAI_API_KEYS = [url.strip() for url in OPENAI_API_KEYS.split(";")]
707
- OPENAI_API_KEYS = PersistentConfig(
708
- "OPENAI_API_KEYS", "openai.api_keys", OPENAI_API_KEYS
709
- )
710
-
711
- OPENAI_API_BASE_URLS = os.environ.get("OPENAI_API_BASE_URLS", "")
712
- OPENAI_API_BASE_URLS = (
713
- OPENAI_API_BASE_URLS if OPENAI_API_BASE_URLS != "" else OPENAI_API_BASE_URL
714
- )
715
-
716
- OPENAI_API_BASE_URLS = [
717
- url.strip() if url != "" else "https://api.openai.com/v1"
718
- for url in OPENAI_API_BASE_URLS.split(";")
719
- ]
720
- OPENAI_API_BASE_URLS = PersistentConfig(
721
- "OPENAI_API_BASE_URLS", "openai.api_base_urls", OPENAI_API_BASE_URLS
722
- )
723
-
724
- OPENAI_API_KEY = ""
725
-
726
- try:
727
- OPENAI_API_KEY = OPENAI_API_KEYS.value[
728
- OPENAI_API_BASE_URLS.value.index("https://api.openai.com/v1")
729
- ]
730
- except Exception:
731
- pass
732
-
733
- OPENAI_API_BASE_URL = "https://api.openai.com/v1"
734
-
735
- ####################################
736
- # WEBUI
737
- ####################################
738
-
739
- ENABLE_SIGNUP = PersistentConfig(
740
- "ENABLE_SIGNUP",
741
- "ui.enable_signup",
742
- (
743
- False
744
- if not WEBUI_AUTH
745
- else os.environ.get("ENABLE_SIGNUP", "True").lower() == "true"
746
- ),
747
- )
748
-
749
- ENABLE_LOGIN_FORM = PersistentConfig(
750
- "ENABLE_LOGIN_FORM",
751
- "ui.ENABLE_LOGIN_FORM",
752
- os.environ.get("ENABLE_LOGIN_FORM", "True").lower() == "true",
753
- )
754
-
755
- DEFAULT_LOCALE = PersistentConfig(
756
- "DEFAULT_LOCALE",
757
- "ui.default_locale",
758
- os.environ.get("DEFAULT_LOCALE", ""),
759
- )
760
-
761
- DEFAULT_MODELS = PersistentConfig(
762
- "DEFAULT_MODELS", "ui.default_models", os.environ.get("DEFAULT_MODELS", None)
763
- )
764
-
765
- DEFAULT_PROMPT_SUGGESTIONS = PersistentConfig(
766
- "DEFAULT_PROMPT_SUGGESTIONS",
767
- "ui.prompt_suggestions",
768
- [
769
- {
770
- "title": ["Help me study", "vocabulary for a college entrance exam"],
771
- "content": "Help me study vocabulary: write a sentence for me to fill in the blank, and I'll try to pick the correct option.",
772
- },
773
- {
774
- "title": ["Give me ideas", "for what to do with my kids' art"],
775
- "content": "What are 5 creative things I could do with my kids' art? I don't want to throw them away, but it's also so much clutter.",
776
- },
777
- {
778
- "title": ["Tell me a fun fact", "about the Roman Empire"],
779
- "content": "Tell me a random fun fact about the Roman Empire",
780
- },
781
- {
782
- "title": ["Show me a code snippet", "of a website's sticky header"],
783
- "content": "Show me a code snippet of a website's sticky header in CSS and JavaScript.",
784
- },
785
- {
786
- "title": [
787
- "Explain options trading",
788
- "if I'm familiar with buying and selling stocks",
789
- ],
790
- "content": "Explain options trading in simple terms if I'm familiar with buying and selling stocks.",
791
- },
792
- {
793
- "title": ["Overcome procrastination", "give me tips"],
794
- "content": "Could you start by asking me about instances when I procrastinate the most and then give me some suggestions to overcome it?",
795
- },
796
- ],
797
- )
798
-
799
- DEFAULT_USER_ROLE = PersistentConfig(
800
- "DEFAULT_USER_ROLE",
801
- "ui.default_user_role",
802
- os.getenv("DEFAULT_USER_ROLE", "pending"),
803
- )
804
-
805
- USER_PERMISSIONS_CHAT_DELETION = (
806
- os.environ.get("USER_PERMISSIONS_CHAT_DELETION", "True").lower() == "true"
807
- )
808
-
809
- USER_PERMISSIONS = PersistentConfig(
810
- "USER_PERMISSIONS",
811
- "ui.user_permissions",
812
- {"chat": {"deletion": USER_PERMISSIONS_CHAT_DELETION}},
813
- )
814
-
815
- ENABLE_MODEL_FILTER = PersistentConfig(
816
- "ENABLE_MODEL_FILTER",
817
- "model_filter.enable",
818
- os.environ.get("ENABLE_MODEL_FILTER", "False").lower() == "true",
819
- )
820
- MODEL_FILTER_LIST = os.environ.get("MODEL_FILTER_LIST", "")
821
- MODEL_FILTER_LIST = PersistentConfig(
822
- "MODEL_FILTER_LIST",
823
- "model_filter.list",
824
- [model.strip() for model in MODEL_FILTER_LIST.split(";")],
825
- )
826
-
827
- WEBHOOK_URL = PersistentConfig(
828
- "WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "")
829
- )
830
-
831
- ENABLE_ADMIN_EXPORT = os.environ.get("ENABLE_ADMIN_EXPORT", "True").lower() == "true"
832
-
833
- ENABLE_ADMIN_CHAT_ACCESS = (
834
- os.environ.get("ENABLE_ADMIN_CHAT_ACCESS", "True").lower() == "true"
835
- )
836
-
837
- ENABLE_COMMUNITY_SHARING = PersistentConfig(
838
- "ENABLE_COMMUNITY_SHARING",
839
- "ui.enable_community_sharing",
840
- os.environ.get("ENABLE_COMMUNITY_SHARING", "True").lower() == "true",
841
- )
842
-
843
-
844
- class BannerModel(BaseModel):
845
- id: str
846
- type: str
847
- title: Optional[str] = None
848
- content: str
849
- dismissible: bool
850
- timestamp: int
851
-
852
-
853
- try:
854
- banners = json.loads(os.environ.get("WEBUI_BANNERS", "[]"))
855
- banners = [BannerModel(**banner) for banner in banners]
856
- except Exception as e:
857
- print(f"Error loading WEBUI_BANNERS: {e}")
858
- banners = []
859
-
860
- WEBUI_BANNERS = PersistentConfig("WEBUI_BANNERS", "ui.banners", banners)
861
-
862
-
863
- SHOW_ADMIN_DETAILS = PersistentConfig(
864
- "SHOW_ADMIN_DETAILS",
865
- "auth.admin.show",
866
- os.environ.get("SHOW_ADMIN_DETAILS", "true").lower() == "true",
867
- )
868
-
869
- ADMIN_EMAIL = PersistentConfig(
870
- "ADMIN_EMAIL",
871
- "auth.admin.email",
872
- os.environ.get("ADMIN_EMAIL", None),
873
- )
874
-
875
-
876
- ####################################
877
- # TASKS
878
- ####################################
879
-
880
-
881
- TASK_MODEL = PersistentConfig(
882
- "TASK_MODEL",
883
- "task.model.default",
884
- os.environ.get("TASK_MODEL", ""),
885
- )
886
-
887
- TASK_MODEL_EXTERNAL = PersistentConfig(
888
- "TASK_MODEL_EXTERNAL",
889
- "task.model.external",
890
- os.environ.get("TASK_MODEL_EXTERNAL", ""),
891
- )
892
-
893
- TITLE_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
894
- "TITLE_GENERATION_PROMPT_TEMPLATE",
895
- "task.title.prompt_template",
896
- os.environ.get(
897
- "TITLE_GENERATION_PROMPT_TEMPLATE",
898
- """Here is the query:
899
- {{prompt:middletruncate:8000}}
900
-
901
- Create a concise, 3-5 word phrase with an emoji as a title for the previous query. Suitable Emojis for the summary can be used to enhance understanding but avoid quotation marks or special formatting. RESPOND ONLY WITH THE TITLE TEXT.
902
-
903
- Examples of titles:
904
- 📉 Stock Market Trends
905
- 🍪 Perfect Chocolate Chip Recipe
906
- Evolution of Music Streaming
907
- Remote Work Productivity Tips
908
- Artificial Intelligence in Healthcare
909
- 🎮 Video Game Development Insights""",
910
- ),
911
- )
912
-
913
-
914
- SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
915
- "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE",
916
- "task.search.prompt_template",
917
- os.environ.get(
918
- "SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE",
919
- """You are tasked with generating web search queries. Give me an appropriate query to answer my question for google search. Answer with only the query. Today is {{CURRENT_DATE}}.
920
-
921
- Question:
922
- {{prompt:end:4000}}""",
923
- ),
924
- )
925
-
926
- SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD = PersistentConfig(
927
- "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD",
928
- "task.search.prompt_length_threshold",
929
- int(
930
- os.environ.get(
931
- "SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD",
932
- 100,
933
- )
934
- ),
935
- )
936
-
937
- TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = PersistentConfig(
938
- "TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE",
939
- "task.tools.prompt_template",
940
- os.environ.get(
941
- "TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE",
942
- """Tools: {{TOOLS}}
943
- If a function tool doesn't match the query, return an empty string. Else, pick a function tool, fill in the parameters from the function tool's schema, and return it in the format { "name": \"functionName\", "parameters": { "key": "value" } }. Only pick a function if the user asks. Only return the object. Do not return any other text.""",
944
- ),
945
- )
946
-
947
-
948
- ####################################
949
- # WEBUI_SECRET_KEY
950
- ####################################
951
-
952
- WEBUI_SECRET_KEY = os.environ.get(
953
- "WEBUI_SECRET_KEY",
954
- os.environ.get(
955
- "WEBUI_JWT_SECRET_KEY", "t0p-s3cr3t"
956
- ), # DEPRECATED: remove at next major version
957
- )
958
-
959
- WEBUI_SESSION_COOKIE_SAME_SITE = os.environ.get(
960
- "WEBUI_SESSION_COOKIE_SAME_SITE",
961
- os.environ.get("WEBUI_SESSION_COOKIE_SAME_SITE", "lax"),
962
- )
963
-
964
- WEBUI_SESSION_COOKIE_SECURE = os.environ.get(
965
- "WEBUI_SESSION_COOKIE_SECURE",
966
- os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false").lower() == "true",
967
- )
968
-
969
- if WEBUI_AUTH and WEBUI_SECRET_KEY == "":
970
- raise ValueError(ERROR_MESSAGES.ENV_VAR_NOT_FOUND)
971
-
972
- ####################################
973
- # RAG document content extraction
974
- ####################################
975
-
976
- CONTENT_EXTRACTION_ENGINE = PersistentConfig(
977
- "CONTENT_EXTRACTION_ENGINE",
978
- "rag.CONTENT_EXTRACTION_ENGINE",
979
- os.environ.get("CONTENT_EXTRACTION_ENGINE", "").lower(),
980
- )
981
-
982
- TIKA_SERVER_URL = PersistentConfig(
983
- "TIKA_SERVER_URL",
984
- "rag.tika_server_url",
985
- os.getenv("TIKA_SERVER_URL", "http://tika:9998"), # Default for sidecar deployment
986
- )
987
-
988
- ####################################
989
- # RAG
990
- ####################################
991
-
992
- CHROMA_DATA_PATH = f"{DATA_DIR}/vector_db"
993
- CHROMA_TENANT = os.environ.get("CHROMA_TENANT", chromadb.DEFAULT_TENANT)
994
- CHROMA_DATABASE = os.environ.get("CHROMA_DATABASE", chromadb.DEFAULT_DATABASE)
995
- CHROMA_HTTP_HOST = os.environ.get("CHROMA_HTTP_HOST", "")
996
- CHROMA_HTTP_PORT = int(os.environ.get("CHROMA_HTTP_PORT", "8000"))
997
- # Comma-separated list of header=value pairs
998
- CHROMA_HTTP_HEADERS = os.environ.get("CHROMA_HTTP_HEADERS", "")
999
- if CHROMA_HTTP_HEADERS:
1000
- CHROMA_HTTP_HEADERS = dict(
1001
- [pair.split("=") for pair in CHROMA_HTTP_HEADERS.split(",")]
1002
- )
1003
- else:
1004
- CHROMA_HTTP_HEADERS = None
1005
- CHROMA_HTTP_SSL = os.environ.get("CHROMA_HTTP_SSL", "false").lower() == "true"
1006
- # this uses the model defined in the Dockerfile ENV variable. If you dont use docker or docker based deployments such as k8s, the default embedding model will be used (sentence-transformers/all-MiniLM-L6-v2)
1007
-
1008
- RAG_TOP_K = PersistentConfig(
1009
- "RAG_TOP_K", "rag.top_k", int(os.environ.get("RAG_TOP_K", "5"))
1010
- )
1011
- RAG_RELEVANCE_THRESHOLD = PersistentConfig(
1012
- "RAG_RELEVANCE_THRESHOLD",
1013
- "rag.relevance_threshold",
1014
- float(os.environ.get("RAG_RELEVANCE_THRESHOLD", "0.0")),
1015
- )
1016
-
1017
- ENABLE_RAG_HYBRID_SEARCH = PersistentConfig(
1018
- "ENABLE_RAG_HYBRID_SEARCH",
1019
- "rag.enable_hybrid_search",
1020
- os.environ.get("ENABLE_RAG_HYBRID_SEARCH", "").lower() == "true",
1021
- )
1022
-
1023
- ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = PersistentConfig(
1024
- "ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION",
1025
- "rag.enable_web_loader_ssl_verification",
1026
- os.environ.get("ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION", "True").lower() == "true",
1027
- )
1028
-
1029
- RAG_EMBEDDING_ENGINE = PersistentConfig(
1030
- "RAG_EMBEDDING_ENGINE",
1031
- "rag.embedding_engine",
1032
- os.environ.get("RAG_EMBEDDING_ENGINE", ""),
1033
- )
1034
-
1035
- PDF_EXTRACT_IMAGES = PersistentConfig(
1036
- "PDF_EXTRACT_IMAGES",
1037
- "rag.pdf_extract_images",
1038
- os.environ.get("PDF_EXTRACT_IMAGES", "False").lower() == "true",
1039
- )
1040
-
1041
- RAG_EMBEDDING_MODEL = PersistentConfig(
1042
- "RAG_EMBEDDING_MODEL",
1043
- "rag.embedding_model",
1044
- os.environ.get("RAG_EMBEDDING_MODEL", "sentence-transformers/all-MiniLM-L6-v2"),
1045
- )
1046
- log.info(f"Embedding model set: {RAG_EMBEDDING_MODEL.value}")
1047
-
1048
- RAG_EMBEDDING_MODEL_AUTO_UPDATE = (
1049
- os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "").lower() == "true"
1050
- )
1051
-
1052
- RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE = (
1053
- os.environ.get("RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE", "").lower() == "true"
1054
- )
1055
-
1056
- RAG_EMBEDDING_OPENAI_BATCH_SIZE = PersistentConfig(
1057
- "RAG_EMBEDDING_OPENAI_BATCH_SIZE",
1058
- "rag.embedding_openai_batch_size",
1059
- os.environ.get("RAG_EMBEDDING_OPENAI_BATCH_SIZE", 1),
1060
- )
1061
-
1062
- RAG_RERANKING_MODEL = PersistentConfig(
1063
- "RAG_RERANKING_MODEL",
1064
- "rag.reranking_model",
1065
- os.environ.get("RAG_RERANKING_MODEL", ""),
1066
- )
1067
- if RAG_RERANKING_MODEL.value != "":
1068
- log.info(f"Reranking model set: {RAG_RERANKING_MODEL.value}")
1069
-
1070
- RAG_RERANKING_MODEL_AUTO_UPDATE = (
1071
- os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "").lower() == "true"
1072
- )
1073
-
1074
- RAG_RERANKING_MODEL_TRUST_REMOTE_CODE = (
1075
- os.environ.get("RAG_RERANKING_MODEL_TRUST_REMOTE_CODE", "").lower() == "true"
1076
- )
1077
-
1078
-
1079
- if CHROMA_HTTP_HOST != "":
1080
- CHROMA_CLIENT = chromadb.HttpClient(
1081
- host=CHROMA_HTTP_HOST,
1082
- port=CHROMA_HTTP_PORT,
1083
- headers=CHROMA_HTTP_HEADERS,
1084
- ssl=CHROMA_HTTP_SSL,
1085
- tenant=CHROMA_TENANT,
1086
- database=CHROMA_DATABASE,
1087
- settings=Settings(allow_reset=True, anonymized_telemetry=False),
1088
- )
1089
- else:
1090
- CHROMA_CLIENT = chromadb.PersistentClient(
1091
- path=CHROMA_DATA_PATH,
1092
- settings=Settings(allow_reset=True, anonymized_telemetry=False),
1093
- tenant=CHROMA_TENANT,
1094
- database=CHROMA_DATABASE,
1095
- )
1096
-
1097
-
1098
- # device type embedding models - "cpu" (default), "cuda" (nvidia gpu required) or "mps" (apple silicon) - choosing this right can lead to better performance
1099
- USE_CUDA = os.environ.get("USE_CUDA_DOCKER", "false")
1100
-
1101
- if USE_CUDA.lower() == "true":
1102
- DEVICE_TYPE = "cuda"
1103
- else:
1104
- DEVICE_TYPE = "cpu"
1105
-
1106
- CHUNK_SIZE = PersistentConfig(
1107
- "CHUNK_SIZE", "rag.chunk_size", int(os.environ.get("CHUNK_SIZE", "1500"))
1108
- )
1109
- CHUNK_OVERLAP = PersistentConfig(
1110
- "CHUNK_OVERLAP",
1111
- "rag.chunk_overlap",
1112
- int(os.environ.get("CHUNK_OVERLAP", "100")),
1113
- )
1114
-
1115
- DEFAULT_RAG_TEMPLATE = """Use the following context as your learned knowledge, inside <context></context> XML tags.
1116
- <context>
1117
- [context]
1118
- </context>
1119
-
1120
- When answer to user:
1121
- - If you don't know, just say that you don't know.
1122
- - If you don't know when you are not sure, ask for clarification.
1123
- Avoid mentioning that you obtained the information from the context.
1124
- And answer according to the language of the user's question.
1125
-
1126
- Given the context information, answer the query.
1127
- Query: [query]"""
1128
-
1129
- RAG_TEMPLATE = PersistentConfig(
1130
- "RAG_TEMPLATE",
1131
- "rag.template",
1132
- os.environ.get("RAG_TEMPLATE", DEFAULT_RAG_TEMPLATE),
1133
- )
1134
-
1135
- RAG_OPENAI_API_BASE_URL = PersistentConfig(
1136
- "RAG_OPENAI_API_BASE_URL",
1137
- "rag.openai_api_base_url",
1138
- os.getenv("RAG_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
1139
- )
1140
- RAG_OPENAI_API_KEY = PersistentConfig(
1141
- "RAG_OPENAI_API_KEY",
1142
- "rag.openai_api_key",
1143
- os.getenv("RAG_OPENAI_API_KEY", OPENAI_API_KEY),
1144
- )
1145
-
1146
- ENABLE_RAG_LOCAL_WEB_FETCH = (
1147
- os.getenv("ENABLE_RAG_LOCAL_WEB_FETCH", "False").lower() == "true"
1148
- )
1149
-
1150
- YOUTUBE_LOADER_LANGUAGE = PersistentConfig(
1151
- "YOUTUBE_LOADER_LANGUAGE",
1152
- "rag.youtube_loader_language",
1153
- os.getenv("YOUTUBE_LOADER_LANGUAGE", "en").split(","),
1154
- )
1155
-
1156
-
1157
- ENABLE_RAG_WEB_SEARCH = PersistentConfig(
1158
- "ENABLE_RAG_WEB_SEARCH",
1159
- "rag.web.search.enable",
1160
- os.getenv("ENABLE_RAG_WEB_SEARCH", "False").lower() == "true",
1161
- )
1162
-
1163
- RAG_WEB_SEARCH_ENGINE = PersistentConfig(
1164
- "RAG_WEB_SEARCH_ENGINE",
1165
- "rag.web.search.engine",
1166
- os.getenv("RAG_WEB_SEARCH_ENGINE", ""),
1167
- )
1168
-
1169
- # You can provide a list of your own websites to filter after performing a web search.
1170
- # This ensures the highest level of safety and reliability of the information sources.
1171
- RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = PersistentConfig(
1172
- "RAG_WEB_SEARCH_DOMAIN_FILTER_LIST",
1173
- "rag.rag.web.search.domain.filter_list",
1174
- [
1175
- # "wikipedia.com",
1176
- # "wikimedia.org",
1177
- # "wikidata.org",
1178
- ],
1179
- )
1180
-
1181
- SEARXNG_QUERY_URL = PersistentConfig(
1182
- "SEARXNG_QUERY_URL",
1183
- "rag.web.search.searxng_query_url",
1184
- os.getenv("SEARXNG_QUERY_URL", ""),
1185
- )
1186
-
1187
- GOOGLE_PSE_API_KEY = PersistentConfig(
1188
- "GOOGLE_PSE_API_KEY",
1189
- "rag.web.search.google_pse_api_key",
1190
- os.getenv("GOOGLE_PSE_API_KEY", ""),
1191
- )
1192
-
1193
- GOOGLE_PSE_ENGINE_ID = PersistentConfig(
1194
- "GOOGLE_PSE_ENGINE_ID",
1195
- "rag.web.search.google_pse_engine_id",
1196
- os.getenv("GOOGLE_PSE_ENGINE_ID", ""),
1197
- )
1198
-
1199
- BRAVE_SEARCH_API_KEY = PersistentConfig(
1200
- "BRAVE_SEARCH_API_KEY",
1201
- "rag.web.search.brave_search_api_key",
1202
- os.getenv("BRAVE_SEARCH_API_KEY", ""),
1203
- )
1204
-
1205
- SERPSTACK_API_KEY = PersistentConfig(
1206
- "SERPSTACK_API_KEY",
1207
- "rag.web.search.serpstack_api_key",
1208
- os.getenv("SERPSTACK_API_KEY", ""),
1209
- )
1210
-
1211
- SERPSTACK_HTTPS = PersistentConfig(
1212
- "SERPSTACK_HTTPS",
1213
- "rag.web.search.serpstack_https",
1214
- os.getenv("SERPSTACK_HTTPS", "True").lower() == "true",
1215
- )
1216
-
1217
- SERPER_API_KEY = PersistentConfig(
1218
- "SERPER_API_KEY",
1219
- "rag.web.search.serper_api_key",
1220
- os.getenv("SERPER_API_KEY", ""),
1221
- )
1222
-
1223
- SERPLY_API_KEY = PersistentConfig(
1224
- "SERPLY_API_KEY",
1225
- "rag.web.search.serply_api_key",
1226
- os.getenv("SERPLY_API_KEY", ""),
1227
- )
1228
-
1229
- TAVILY_API_KEY = PersistentConfig(
1230
- "TAVILY_API_KEY",
1231
- "rag.web.search.tavily_api_key",
1232
- os.getenv("TAVILY_API_KEY", ""),
1233
- )
1234
-
1235
- RAG_WEB_SEARCH_RESULT_COUNT = PersistentConfig(
1236
- "RAG_WEB_SEARCH_RESULT_COUNT",
1237
- "rag.web.search.result_count",
1238
- int(os.getenv("RAG_WEB_SEARCH_RESULT_COUNT", "3")),
1239
- )
1240
-
1241
- RAG_WEB_SEARCH_CONCURRENT_REQUESTS = PersistentConfig(
1242
- "RAG_WEB_SEARCH_CONCURRENT_REQUESTS",
1243
- "rag.web.search.concurrent_requests",
1244
- int(os.getenv("RAG_WEB_SEARCH_CONCURRENT_REQUESTS", "10")),
1245
- )
1246
-
1247
-
1248
- ####################################
1249
- # Transcribe
1250
- ####################################
1251
-
1252
- WHISPER_MODEL = os.getenv("WHISPER_MODEL", "base")
1253
- WHISPER_MODEL_DIR = os.getenv("WHISPER_MODEL_DIR", f"{CACHE_DIR}/whisper/models")
1254
- WHISPER_MODEL_AUTO_UPDATE = (
1255
- os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true"
1256
- )
1257
-
1258
-
1259
- ####################################
1260
- # Images
1261
- ####################################
1262
-
1263
- IMAGE_GENERATION_ENGINE = PersistentConfig(
1264
- "IMAGE_GENERATION_ENGINE",
1265
- "image_generation.engine",
1266
- os.getenv("IMAGE_GENERATION_ENGINE", ""),
1267
- )
1268
-
1269
- ENABLE_IMAGE_GENERATION = PersistentConfig(
1270
- "ENABLE_IMAGE_GENERATION",
1271
- "image_generation.enable",
1272
- os.environ.get("ENABLE_IMAGE_GENERATION", "").lower() == "true",
1273
- )
1274
- AUTOMATIC1111_BASE_URL = PersistentConfig(
1275
- "AUTOMATIC1111_BASE_URL",
1276
- "image_generation.automatic1111.base_url",
1277
- os.getenv("AUTOMATIC1111_BASE_URL", ""),
1278
- )
1279
- AUTOMATIC1111_API_AUTH = PersistentConfig(
1280
- "AUTOMATIC1111_API_AUTH",
1281
- "image_generation.automatic1111.api_auth",
1282
- os.getenv("AUTOMATIC1111_API_AUTH", ""),
1283
- )
1284
-
1285
- COMFYUI_BASE_URL = PersistentConfig(
1286
- "COMFYUI_BASE_URL",
1287
- "image_generation.comfyui.base_url",
1288
- os.getenv("COMFYUI_BASE_URL", ""),
1289
- )
1290
-
1291
- COMFYUI_CFG_SCALE = PersistentConfig(
1292
- "COMFYUI_CFG_SCALE",
1293
- "image_generation.comfyui.cfg_scale",
1294
- os.getenv("COMFYUI_CFG_SCALE", ""),
1295
- )
1296
-
1297
- COMFYUI_SAMPLER = PersistentConfig(
1298
- "COMFYUI_SAMPLER",
1299
- "image_generation.comfyui.sampler",
1300
- os.getenv("COMFYUI_SAMPLER", ""),
1301
- )
1302
-
1303
- COMFYUI_SCHEDULER = PersistentConfig(
1304
- "COMFYUI_SCHEDULER",
1305
- "image_generation.comfyui.scheduler",
1306
- os.getenv("COMFYUI_SCHEDULER", ""),
1307
- )
1308
-
1309
- COMFYUI_SD3 = PersistentConfig(
1310
- "COMFYUI_SD3",
1311
- "image_generation.comfyui.sd3",
1312
- os.environ.get("COMFYUI_SD3", "").lower() == "true",
1313
- )
1314
-
1315
- COMFYUI_FLUX = PersistentConfig(
1316
- "COMFYUI_FLUX",
1317
- "image_generation.comfyui.flux",
1318
- os.environ.get("COMFYUI_FLUX", "").lower() == "true",
1319
- )
1320
-
1321
- COMFYUI_FLUX_WEIGHT_DTYPE = PersistentConfig(
1322
- "COMFYUI_FLUX_WEIGHT_DTYPE",
1323
- "image_generation.comfyui.flux_weight_dtype",
1324
- os.getenv("COMFYUI_FLUX_WEIGHT_DTYPE", ""),
1325
- )
1326
-
1327
- COMFYUI_FLUX_FP8_CLIP = PersistentConfig(
1328
- "COMFYUI_FLUX_FP8_CLIP",
1329
- "image_generation.comfyui.flux_fp8_clip",
1330
- os.environ.get("COMFYUI_FLUX_FP8_CLIP", "").lower() == "true",
1331
- )
1332
-
1333
- IMAGES_OPENAI_API_BASE_URL = PersistentConfig(
1334
- "IMAGES_OPENAI_API_BASE_URL",
1335
- "image_generation.openai.api_base_url",
1336
- os.getenv("IMAGES_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
1337
- )
1338
- IMAGES_OPENAI_API_KEY = PersistentConfig(
1339
- "IMAGES_OPENAI_API_KEY",
1340
- "image_generation.openai.api_key",
1341
- os.getenv("IMAGES_OPENAI_API_KEY", OPENAI_API_KEY),
1342
- )
1343
-
1344
- IMAGE_SIZE = PersistentConfig(
1345
- "IMAGE_SIZE", "image_generation.size", os.getenv("IMAGE_SIZE", "512x512")
1346
- )
1347
-
1348
- IMAGE_STEPS = PersistentConfig(
1349
- "IMAGE_STEPS", "image_generation.steps", int(os.getenv("IMAGE_STEPS", 50))
1350
- )
1351
-
1352
- IMAGE_GENERATION_MODEL = PersistentConfig(
1353
- "IMAGE_GENERATION_MODEL",
1354
- "image_generation.model",
1355
- os.getenv("IMAGE_GENERATION_MODEL", ""),
1356
- )
1357
-
1358
- ####################################
1359
- # Audio
1360
- ####################################
1361
-
1362
- AUDIO_STT_OPENAI_API_BASE_URL = PersistentConfig(
1363
- "AUDIO_STT_OPENAI_API_BASE_URL",
1364
- "audio.stt.openai.api_base_url",
1365
- os.getenv("AUDIO_STT_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
1366
- )
1367
-
1368
- AUDIO_STT_OPENAI_API_KEY = PersistentConfig(
1369
- "AUDIO_STT_OPENAI_API_KEY",
1370
- "audio.stt.openai.api_key",
1371
- os.getenv("AUDIO_STT_OPENAI_API_KEY", OPENAI_API_KEY),
1372
- )
1373
-
1374
- AUDIO_STT_ENGINE = PersistentConfig(
1375
- "AUDIO_STT_ENGINE",
1376
- "audio.stt.engine",
1377
- os.getenv("AUDIO_STT_ENGINE", ""),
1378
- )
1379
-
1380
- AUDIO_STT_MODEL = PersistentConfig(
1381
- "AUDIO_STT_MODEL",
1382
- "audio.stt.model",
1383
- os.getenv("AUDIO_STT_MODEL", "whisper-1"),
1384
- )
1385
-
1386
- AUDIO_TTS_OPENAI_API_BASE_URL = PersistentConfig(
1387
- "AUDIO_TTS_OPENAI_API_BASE_URL",
1388
- "audio.tts.openai.api_base_url",
1389
- os.getenv("AUDIO_TTS_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL),
1390
- )
1391
- AUDIO_TTS_OPENAI_API_KEY = PersistentConfig(
1392
- "AUDIO_TTS_OPENAI_API_KEY",
1393
- "audio.tts.openai.api_key",
1394
- os.getenv("AUDIO_TTS_OPENAI_API_KEY", OPENAI_API_KEY),
1395
- )
1396
-
1397
- AUDIO_TTS_API_KEY = PersistentConfig(
1398
- "AUDIO_TTS_API_KEY",
1399
- "audio.tts.api_key",
1400
- os.getenv("AUDIO_TTS_API_KEY", ""),
1401
- )
1402
-
1403
- AUDIO_TTS_ENGINE = PersistentConfig(
1404
- "AUDIO_TTS_ENGINE",
1405
- "audio.tts.engine",
1406
- os.getenv("AUDIO_TTS_ENGINE", ""),
1407
- )
1408
-
1409
-
1410
- AUDIO_TTS_MODEL = PersistentConfig(
1411
- "AUDIO_TTS_MODEL",
1412
- "audio.tts.model",
1413
- os.getenv("AUDIO_TTS_MODEL", "tts-1"),
1414
- )
1415
-
1416
- AUDIO_TTS_VOICE = PersistentConfig(
1417
- "AUDIO_TTS_VOICE",
1418
- "audio.tts.voice",
1419
- os.getenv("AUDIO_TTS_VOICE", "alloy"),
1420
- )
1421
-
1422
-
1423
- ####################################
1424
- # Database
1425
- ####################################
1426
-
1427
- DATABASE_URL = os.environ.get("DATABASE_URL", f"sqlite:///{DATA_DIR}/webui.db")
1428
-
1429
- # Replace the postgres:// with postgresql://
1430
- if "postgres://" in DATABASE_URL:
1431
- DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
open-webui/images/favicon.png DELETED

Git LFS Details

  • SHA256: 70bee1365949c7a80a69ad704296a0a38bd3480bfc78019032ffd973a000d62a
  • Pointer size: 132 Bytes
  • Size of remote file: 1.33 MB
postgres/tes.txt DELETED
File without changes