forked from open-webui/open-webui
Compare commits
223 commits
921a1cf978
...
fd5bf819cc
Author | SHA1 | Date | |
---|---|---|---|
fd5bf819cc | |||
|
331fe04df7 | ||
|
aed4763bfe | ||
|
8d0f3fbde9 | ||
|
318d4d1ce1 | ||
|
5a787ab2c5 | ||
|
81dbc65853 | ||
|
d001d7afb1 | ||
|
183b84beae | ||
|
7d64ada43e | ||
|
802eb3beec | ||
|
f87805b46f | ||
|
7a7d1931d9 | ||
|
e61e1b079f | ||
|
7813c3316f | ||
|
46774aa5cd | ||
|
62392aa88a | ||
|
c32d41b47f | ||
|
9404b6135a | ||
|
8caad59cb4 | ||
|
21132420d8 | ||
|
c89070797c | ||
|
1f85354856 | ||
|
bfd066cc2f | ||
|
000bea84ae | ||
|
944efd2cd8 | ||
|
4a09342a71 | ||
|
aad13607c0 | ||
|
1509c2c2ee | ||
|
d94bc21ac8 | ||
|
947c392f72 | ||
|
15d24a6a11 | ||
|
a3d6343dbe | ||
|
14fcf4d267 | ||
|
83ad488e31 | ||
|
fa61e738c3 | ||
|
0aa4d305c7 | ||
|
1066096b33 | ||
|
398b2076cd | ||
|
fb516ea694 | ||
|
b35cc36e19 | ||
|
6d1ce99537 | ||
|
7c5f6d71b3 | ||
|
e49e04c56a | ||
|
da8646cae9 | ||
|
ba0523cd69 | ||
|
38c34b4444 | ||
|
b11af9ea0e | ||
|
56369fea3a | ||
|
24fb77759e | ||
|
f9106cf394 | ||
|
807a60cccf | ||
|
ac4675900e | ||
|
f7a1fc207a | ||
|
b9b1d64bd5 | ||
|
7e6a00b009 | ||
|
5aad328040 | ||
|
03a7f88dca | ||
|
f61869d90d | ||
|
95505bc4c1 | ||
|
eca59f759d | ||
|
9975cb17a9 | ||
|
0b823f90e6 | ||
|
c0fff4c69f | ||
|
180dd3966b | ||
|
e4d101e550 | ||
|
88c5b7f495 | ||
|
4e9ca31146 | ||
|
48e7376336 | ||
|
488301f150 | ||
|
287c95e72d | ||
|
af5a7a35c0 | ||
|
5faa05a117 | ||
|
e273a99153 | ||
|
151055590d | ||
|
7978adbf45 | ||
|
94976e5ed3 | ||
|
3a1d747677 | ||
|
7121465eda | ||
|
52e83891b4 | ||
|
456a78ada9 | ||
|
cd60dbe08c | ||
|
a0d932b986 | ||
|
10cad60566 | ||
|
c6296e5108 | ||
|
dd9cbd0ab9 | ||
|
865c268312 | ||
|
dcac8a773b | ||
|
96d75dfc1b | ||
|
49428eb7ef | ||
|
6c0e3972dc | ||
|
458c317736 | ||
|
98f68b8b08 | ||
|
b76e934140 | ||
|
0cdcc2deb6 | ||
|
58992d592c | ||
|
04e172deac | ||
|
a363c1f2f1 | ||
|
6425e794f6 | ||
|
f340178bb7 | ||
|
aa6c8b1bfd | ||
|
d1ca6b50d9 | ||
|
57530d87f6 | ||
|
2c030218f8 | ||
|
5558514ff1 | ||
|
83c7633acb | ||
|
6c3f2f8d38 | ||
|
d72653cdea | ||
|
6c96361402 | ||
|
554e56687c | ||
|
77b1edcd0f | ||
|
d667faea33 | ||
|
4cb2cc62d2 | ||
|
698bfcf87f | ||
|
edeff20e1d | ||
|
eda157e303 | ||
|
653a0ff02f | ||
|
8175a323e9 | ||
|
11850b75c8 | ||
|
562e40a7bd | ||
|
0e3b7a11e3 | ||
|
196f91d68c | ||
|
bfbfdae1c5 | ||
|
a6c154d839 | ||
|
7563619e26 | ||
|
1b5c92d66c | ||
|
2f23325c90 | ||
|
cef676429f | ||
|
a0935dec60 | ||
|
587a8c5992 | ||
|
4ddb7e124e | ||
|
68cfdd89c4 | ||
|
144c9059a3 | ||
|
ee38b3c84d | ||
|
86aa2ca6cb | ||
|
1d7ca44017 | ||
|
174c082c69 | ||
|
bbb63104ea | ||
|
43832d165f | ||
|
d630485051 | ||
|
784572590f | ||
|
90a03c331d | ||
|
b391ad12ae | ||
|
6c2eb814ed | ||
|
3b0cb7945f | ||
|
46a181042b | ||
|
5af8d0612a | ||
|
d4fabeee3c | ||
|
e47d6ce1f6 | ||
|
15f4153fda | ||
|
1371e66ed9 | ||
|
2fbb92aceb | ||
|
f96beeee8f | ||
|
0c367412c3 | ||
|
150152ddbd | ||
|
12287f8680 | ||
|
047c9fe82c | ||
|
ce20f05ef1 | ||
|
242311aee1 | ||
|
bbc34d9be5 | ||
|
09da5e71e2 | ||
|
74638bbd6e | ||
|
f34fe49bdd | ||
|
50089710f3 | ||
|
4bf38e5287 | ||
|
50f6addd6f | ||
|
c42cb438f9 | ||
|
b93bdfb222 | ||
|
c85a2e8cd4 | ||
|
46e3208cde | ||
|
c6bb0ded5e | ||
|
d187b1615a | ||
|
5e24e03fe5 | ||
|
2fcc4aec4b | ||
|
67865fc5ad | ||
|
9ad097d265 | ||
|
572eefe181 | ||
|
cf44209730 | ||
|
dfeadf9595 | ||
|
25c71d8ac2 | ||
|
19d2121252 | ||
|
c24d9d3bea | ||
|
976c714063 | ||
|
f87d5d3d9b | ||
|
29f13f34d3 | ||
|
7d45d2762f | ||
|
e5408995d8 | ||
|
d69dfb7c8b | ||
|
addee2f248 | ||
|
0c021e42f5 | ||
|
64e6003627 | ||
|
26121c5d88 | ||
|
d245b756a3 | ||
|
b4b56f9c85 | ||
|
81e928030f | ||
|
0b62bbb52e | ||
|
cb364f0ac7 | ||
|
d12a7247bc | ||
|
941bb7c603 | ||
|
3edc547389 | ||
|
427ca4e3f5 | ||
|
5eac5c54f8 | ||
|
a1fc2f4df0 | ||
|
3688955c77 | ||
|
6307adfba1 | ||
|
4f78acaa5c | ||
|
7f405c74cd | ||
|
5d6cee0c58 | ||
|
af366cf732 | ||
|
32cb5f3ceb | ||
|
eecc7f3529 | ||
|
8962d948cd | ||
|
c91a5d8b1f | ||
|
77f4ffddc1 | ||
|
784a6ec85e | ||
|
eb004ccfc2 | ||
|
c6f9e74477 | ||
|
302bd11b33 | ||
|
c19ea89a1d | ||
|
9560f9196d | ||
|
42bb1ec089 | ||
|
c91c95431d | ||
|
1d64d31275 |
111 changed files with 6483 additions and 2728 deletions
|
@ -9,4 +9,8 @@ OPENAI_API_KEY=''
|
||||||
|
|
||||||
# DO NOT TRACK
|
# DO NOT TRACK
|
||||||
SCARF_NO_ANALYTICS=true
|
SCARF_NO_ANALYTICS=true
|
||||||
DO_NOT_TRACK=true
|
DO_NOT_TRACK=true
|
||||||
|
|
||||||
|
# Use locally bundled version of the LiteLLM cost map json
|
||||||
|
# to avoid repetitive startup connections
|
||||||
|
LITELLM_LOCAL_MODEL_COST_MAP="True"
|
||||||
|
|
7
.github/workflows/docker-build.yaml
vendored
7
.github/workflows/docker-build.yaml
vendored
|
@ -12,16 +12,13 @@ on:
|
||||||
|
|
||||||
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
|
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
|
||||||
env:
|
env:
|
||||||
REGISTRY: git.depeuter.dev
|
REGISTRY: ghcr.io
|
||||||
IMAGE_NAME: ${{ github.repository }}
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
RUNNER_TOOL_CACHE: /toolcache
|
|
||||||
|
|
||||||
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
|
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
|
||||||
jobs:
|
jobs:
|
||||||
build-and-push-image:
|
build-and-push-image:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
|
||||||
image: catthehacker/ubuntu:act-latest
|
|
||||||
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -42,7 +39,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.CI_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Extract metadata for Docker images
|
- name: Extract metadata for Docker images
|
||||||
id: meta
|
id: meta
|
||||||
|
|
32
.github/workflows/format-backend.yaml
vendored
32
.github/workflows/format-backend.yaml
vendored
|
@ -1,31 +1,39 @@
|
||||||
name: Python CI
|
name: Python CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['main']
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
pull_request:
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: 'Format Backend'
|
name: 'Format Backend'
|
||||||
env:
|
|
||||||
PUBLIC_API_BASE_URL: ''
|
|
||||||
RUNNER_TOOL_CACHE: /toolcache
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version:
|
python-version: [3.11]
|
||||||
- latest
|
|
||||||
python-version: [ '3.12.2' ]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Use Python
|
|
||||||
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Use Bun
|
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install yapf
|
pip install black
|
||||||
|
|
||||||
- name: Format backend
|
- name: Format backend
|
||||||
run: bun run format:backend
|
run: npm run format:backend
|
||||||
|
|
||||||
|
- name: Check for changes after format
|
||||||
|
run: git diff --exit-code
|
||||||
|
|
42
.github/workflows/format-build-frontend.yaml
vendored
42
.github/workflows/format-build-frontend.yaml
vendored
|
@ -1,22 +1,36 @@
|
||||||
name: Bun CI
|
name: Frontend Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['main']
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
pull_request:
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: 'Format & Build Frontend'
|
name: 'Format & Build Frontend'
|
||||||
env:
|
|
||||||
PUBLIC_API_BASE_URL: ''
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout Repository
|
||||||
- name: Use Bun
|
uses: actions/checkout@v4
|
||||||
uses: oven-sh/setup-bun@v1
|
|
||||||
- run: bun --version
|
- name: Setup Node.js
|
||||||
- name: Install frontend dependencies
|
uses: actions/setup-node@v3
|
||||||
run: bun install
|
with:
|
||||||
- name: Format frontend
|
node-version: '20' # Or specify any other version you want to use
|
||||||
run: bun run format
|
|
||||||
- name: Build frontend
|
- name: Install Dependencies
|
||||||
run: bun run build
|
run: npm install
|
||||||
|
|
||||||
|
- name: Format Frontend
|
||||||
|
run: npm run format
|
||||||
|
|
||||||
|
- name: Check for Changes After Format
|
||||||
|
run: git diff --exit-code
|
||||||
|
|
||||||
|
- name: Build Frontend
|
||||||
|
run: npm run build
|
||||||
|
|
35
CHANGELOG.md
35
CHANGELOG.md
|
@ -5,6 +5,41 @@ 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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.1.117] - 2024-04-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- 🗨️ **Local Chat Sharing**: Share chat links seamlessly between users.
|
||||||
|
- 🔑 **API Key Generation Support**: Generate secret keys to leverage Open WebUI with OpenAI libraries.
|
||||||
|
- 📄 **Chat Download as PDF**: Easily download chats in PDF format.
|
||||||
|
- 📝 **Improved Logging**: Enhancements to logging functionality.
|
||||||
|
- 📧 **Trusted Email Authentication**: Authenticate using a trusted email header.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- 🌷 **Enhanced Dutch Translation**: Improved translation for Dutch users.
|
||||||
|
- ⚪ **White Theme Styling**: Resolved styling issue with the white theme.
|
||||||
|
- 📜 **LaTeX Chat Screen Overflow**: Fixed screen overflow issue with LaTeX rendering.
|
||||||
|
- 🔒 **Security Patches**: Applied necessary security patches.
|
||||||
|
|
||||||
|
## [0.1.116] - 2024-03-31
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **🔄 Enhanced UI**: Model selector now conveniently located in the navbar, enabling seamless switching between multiple models during conversations.
|
||||||
|
- **🔍 Improved Model Selector**: Directly pull a model from the selector/Models now display detailed information for better understanding.
|
||||||
|
- **💬 Webhook Support**: Now compatible with Google Chat and Microsoft Teams.
|
||||||
|
- **🌐 Localization**: Korean translation (I18n) now available.
|
||||||
|
- **🌑 Dark Theme**: OLED dark theme introduced for reduced strain during prolonged usage.
|
||||||
|
- **🏷️ Tag Autocomplete**: Dropdown feature added for effortless chat tagging.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **🔽 Auto-Scrolling**: Addressed OpenAI auto-scrolling issue.
|
||||||
|
- **🏷️ Tag Validation**: Implemented tag validation to prevent empty string tags.
|
||||||
|
- **🚫 Model Whitelisting**: Resolved LiteLLM model whitelisting issue.
|
||||||
|
- **✅ Spelling**: Corrected various spelling issues for improved readability.
|
||||||
|
|
||||||
## [0.1.115] - 2024-03-24
|
## [0.1.115] - 2024-03-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -26,10 +26,15 @@ ENV OPENAI_API_BASE_URL ""
|
||||||
ENV OPENAI_API_KEY ""
|
ENV OPENAI_API_KEY ""
|
||||||
|
|
||||||
ENV WEBUI_SECRET_KEY ""
|
ENV WEBUI_SECRET_KEY ""
|
||||||
|
ENV WEBUI_AUTH_TRUSTED_EMAIL_HEADER ""
|
||||||
|
|
||||||
ENV SCARF_NO_ANALYTICS true
|
ENV SCARF_NO_ANALYTICS true
|
||||||
ENV DO_NOT_TRACK true
|
ENV DO_NOT_TRACK true
|
||||||
|
|
||||||
|
# Use locally bundled version of the LiteLLM cost map json
|
||||||
|
# to avoid repetitive startup connections
|
||||||
|
ENV LITELLM_LOCAL_MODEL_COST_MAP="True"
|
||||||
|
|
||||||
######## Preloaded models ########
|
######## Preloaded models ########
|
||||||
# whisper TTS Settings
|
# whisper TTS Settings
|
||||||
ENV WHISPER_MODEL="base"
|
ENV WHISPER_MODEL="base"
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -8,6 +8,8 @@ remove:
|
||||||
|
|
||||||
start:
|
start:
|
||||||
@docker-compose start
|
@docker-compose start
|
||||||
|
startAndBuild:
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
stop:
|
stop:
|
||||||
@docker-compose stop
|
@docker-compose stop
|
||||||
|
|
|
@ -22,7 +22,13 @@ from utils.utils import (
|
||||||
)
|
)
|
||||||
from utils.misc import calculate_sha256
|
from utils.misc import calculate_sha256
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS, 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 = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["AUDIO"])
|
log.setLevel(SRC_LOG_LEVELS["AUDIO"])
|
||||||
|
|
|
@ -325,7 +325,7 @@ def save_url_image(url):
|
||||||
|
|
||||||
return image_id
|
return image_id
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error saving image: {e}")
|
log.exception(f"Error saving image: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ def generate_image(
|
||||||
user.id,
|
user.id,
|
||||||
app.state.COMFYUI_BASE_URL,
|
app.state.COMFYUI_BASE_URL,
|
||||||
)
|
)
|
||||||
print(res)
|
log.debug(f"res: {res}")
|
||||||
|
|
||||||
images = []
|
images = []
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ def generate_image(
|
||||||
with open(file_body_path, "w") as f:
|
with open(file_body_path, "w") as f:
|
||||||
json.dump(data.model_dump(exclude_none=True), f)
|
json.dump(data.model_dump(exclude_none=True), f)
|
||||||
|
|
||||||
print(images)
|
log.debug(f"images: {images}")
|
||||||
return images
|
return images
|
||||||
else:
|
else:
|
||||||
if form_data.model:
|
if form_data.model:
|
||||||
|
|
|
@ -4,6 +4,12 @@ import json
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import random
|
import random
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
log.setLevel(SRC_LOG_LEVELS["COMFYUI"])
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
@ -121,7 +127,7 @@ COMFYUI_DEFAULT_PROMPT = """
|
||||||
|
|
||||||
|
|
||||||
def queue_prompt(prompt, client_id, base_url):
|
def queue_prompt(prompt, client_id, base_url):
|
||||||
print("queue_prompt")
|
log.info("queue_prompt")
|
||||||
p = {"prompt": prompt, "client_id": client_id}
|
p = {"prompt": prompt, "client_id": client_id}
|
||||||
data = json.dumps(p).encode("utf-8")
|
data = json.dumps(p).encode("utf-8")
|
||||||
req = urllib.request.Request(f"{base_url}/prompt", data=data)
|
req = urllib.request.Request(f"{base_url}/prompt", data=data)
|
||||||
|
@ -129,7 +135,7 @@ def queue_prompt(prompt, client_id, base_url):
|
||||||
|
|
||||||
|
|
||||||
def get_image(filename, subfolder, folder_type, base_url):
|
def get_image(filename, subfolder, folder_type, base_url):
|
||||||
print("get_image")
|
log.info("get_image")
|
||||||
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
|
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
|
||||||
url_values = urllib.parse.urlencode(data)
|
url_values = urllib.parse.urlencode(data)
|
||||||
with urllib.request.urlopen(f"{base_url}/view?{url_values}") as response:
|
with urllib.request.urlopen(f"{base_url}/view?{url_values}") as response:
|
||||||
|
@ -137,14 +143,14 @@ def get_image(filename, subfolder, folder_type, base_url):
|
||||||
|
|
||||||
|
|
||||||
def get_image_url(filename, subfolder, folder_type, base_url):
|
def get_image_url(filename, subfolder, folder_type, base_url):
|
||||||
print("get_image")
|
log.info("get_image")
|
||||||
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
|
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
|
||||||
url_values = urllib.parse.urlencode(data)
|
url_values = urllib.parse.urlencode(data)
|
||||||
return f"{base_url}/view?{url_values}"
|
return f"{base_url}/view?{url_values}"
|
||||||
|
|
||||||
|
|
||||||
def get_history(prompt_id, base_url):
|
def get_history(prompt_id, base_url):
|
||||||
print("get_history")
|
log.info("get_history")
|
||||||
with urllib.request.urlopen(f"{base_url}/history/{prompt_id}") as response:
|
with urllib.request.urlopen(f"{base_url}/history/{prompt_id}") as response:
|
||||||
return json.loads(response.read())
|
return json.loads(response.read())
|
||||||
|
|
||||||
|
@ -212,15 +218,15 @@ def comfyui_generate_image(
|
||||||
try:
|
try:
|
||||||
ws = websocket.WebSocket()
|
ws = websocket.WebSocket()
|
||||||
ws.connect(f"ws://{host}/ws?clientId={client_id}")
|
ws.connect(f"ws://{host}/ws?clientId={client_id}")
|
||||||
print("WebSocket connection established.")
|
log.info("WebSocket connection established.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to connect to WebSocket server: {e}")
|
log.exception(f"Failed to connect to WebSocket server: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
images = get_images(ws, comfyui_prompt, client_id, base_url)
|
images = get_images(ws, comfyui_prompt, client_id, base_url)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error while receiving images: {e}")
|
log.exception(f"Error while receiving images: {e}")
|
||||||
images = None
|
images = None
|
||||||
|
|
||||||
ws.close()
|
ws.close()
|
||||||
|
|
|
@ -33,7 +33,13 @@ from constants import ERROR_MESSAGES
|
||||||
from utils.utils import decode_token, get_current_user, get_admin_user
|
from utils.utils import decode_token, get_current_user, get_admin_user
|
||||||
|
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS, 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
|
from utils.misc import calculate_sha256
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -75,6 +81,12 @@ async def check_url(request: Request, call_next):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@app.head("/")
|
||||||
|
@app.get("/")
|
||||||
|
async def get_status():
|
||||||
|
return {"status": True}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/urls")
|
@app.get("/urls")
|
||||||
async def get_ollama_api_urls(user=Depends(get_admin_user)):
|
async def get_ollama_api_urls(user=Depends(get_admin_user)):
|
||||||
return {"OLLAMA_BASE_URLS": app.state.OLLAMA_BASE_URLS}
|
return {"OLLAMA_BASE_URLS": app.state.OLLAMA_BASE_URLS}
|
||||||
|
@ -266,7 +278,7 @@ async def pull_model(
|
||||||
if request_id in REQUEST_POOL:
|
if request_id in REQUEST_POOL:
|
||||||
yield chunk
|
yield chunk
|
||||||
else:
|
else:
|
||||||
print("User: canceled request")
|
log.warning("User: canceled request")
|
||||||
break
|
break
|
||||||
finally:
|
finally:
|
||||||
if hasattr(r, "close"):
|
if hasattr(r, "close"):
|
||||||
|
@ -664,7 +676,7 @@ async def generate_completion(
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
detail="error_detail",
|
detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model),
|
||||||
)
|
)
|
||||||
|
|
||||||
url = app.state.OLLAMA_BASE_URLS[url_idx]
|
url = app.state.OLLAMA_BASE_URLS[url_idx]
|
||||||
|
@ -770,7 +782,11 @@ async def generate_chat_completion(
|
||||||
|
|
||||||
r = None
|
r = None
|
||||||
|
|
||||||
log.debug("form_data.model_dump_json(exclude_none=True).encode(): {0} ".format(form_data.model_dump_json(exclude_none=True).encode()))
|
log.debug(
|
||||||
|
"form_data.model_dump_json(exclude_none=True).encode(): {0} ".format(
|
||||||
|
form_data.model_dump_json(exclude_none=True).encode()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def get_request():
|
def get_request():
|
||||||
nonlocal form_data
|
nonlocal form_data
|
||||||
|
@ -1019,6 +1035,14 @@ async def download_model(
|
||||||
url_idx: Optional[int] = None,
|
url_idx: Optional[int] = None,
|
||||||
):
|
):
|
||||||
|
|
||||||
|
allowed_hosts = ["https://huggingface.co/", "https://github.com/"]
|
||||||
|
|
||||||
|
if not any(form_data.url.startswith(host) for host in allowed_hosts):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail="Invalid file_url. Only URLs from allowed hosts are permitted.",
|
||||||
|
)
|
||||||
|
|
||||||
if url_idx == None:
|
if url_idx == None:
|
||||||
url_idx = 0
|
url_idx = 0
|
||||||
url = app.state.OLLAMA_BASE_URLS[url_idx]
|
url = app.state.OLLAMA_BASE_URLS[url_idx]
|
||||||
|
@ -1027,6 +1051,7 @@ async def download_model(
|
||||||
|
|
||||||
if file_name:
|
if file_name:
|
||||||
file_path = f"{UPLOAD_DIR}/{file_name}"
|
file_path = f"{UPLOAD_DIR}/{file_name}"
|
||||||
|
|
||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
download_file_stream(url, form_data.url, file_path, file_name),
|
download_file_stream(url, form_data.url, file_path, file_name),
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from fastapi import (
|
||||||
Form,
|
Form,
|
||||||
)
|
)
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
import os, shutil, logging
|
import os, shutil, logging, re
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
@ -21,6 +21,7 @@ from langchain_community.document_loaders import (
|
||||||
TextLoader,
|
TextLoader,
|
||||||
PyPDFLoader,
|
PyPDFLoader,
|
||||||
CSVLoader,
|
CSVLoader,
|
||||||
|
BSHTMLLoader,
|
||||||
Docx2txtLoader,
|
Docx2txtLoader,
|
||||||
UnstructuredEPubLoader,
|
UnstructuredEPubLoader,
|
||||||
UnstructuredWordDocumentLoader,
|
UnstructuredWordDocumentLoader,
|
||||||
|
@ -114,6 +115,7 @@ class CollectionNameForm(BaseModel):
|
||||||
class StoreWebForm(CollectionNameForm):
|
class StoreWebForm(CollectionNameForm):
|
||||||
url: str
|
url: str
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
async def get_status():
|
async def get_status():
|
||||||
return {
|
return {
|
||||||
|
@ -296,13 +298,18 @@ def store_web(form_data: StoreWebForm, user=Depends(get_current_user)):
|
||||||
|
|
||||||
|
|
||||||
def store_data_in_vector_db(data, collection_name, overwrite: bool = False) -> bool:
|
def store_data_in_vector_db(data, collection_name, overwrite: bool = False) -> bool:
|
||||||
|
|
||||||
text_splitter = RecursiveCharacterTextSplitter(
|
text_splitter = RecursiveCharacterTextSplitter(
|
||||||
chunk_size=app.state.CHUNK_SIZE,
|
chunk_size=app.state.CHUNK_SIZE,
|
||||||
chunk_overlap=app.state.CHUNK_OVERLAP,
|
chunk_overlap=app.state.CHUNK_OVERLAP,
|
||||||
add_start_index=True,
|
add_start_index=True,
|
||||||
)
|
)
|
||||||
docs = text_splitter.split_documents(data)
|
docs = text_splitter.split_documents(data)
|
||||||
return store_docs_in_vector_db(docs, collection_name, overwrite)
|
|
||||||
|
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(
|
def store_text_in_vector_db(
|
||||||
|
@ -318,6 +325,7 @@ def store_text_in_vector_db(
|
||||||
|
|
||||||
|
|
||||||
def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> bool:
|
def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> bool:
|
||||||
|
|
||||||
texts = [doc.page_content for doc in docs]
|
texts = [doc.page_content for doc in docs]
|
||||||
metadatas = [doc.metadata for doc in docs]
|
metadatas = [doc.metadata for doc in docs]
|
||||||
|
|
||||||
|
@ -325,7 +333,7 @@ def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> b
|
||||||
if overwrite:
|
if overwrite:
|
||||||
for collection in CHROMA_CLIENT.list_collections():
|
for collection in CHROMA_CLIENT.list_collections():
|
||||||
if collection_name == collection.name:
|
if collection_name == collection.name:
|
||||||
print(f"deleting existing collection {collection_name}")
|
log.info(f"deleting existing collection {collection_name}")
|
||||||
CHROMA_CLIENT.delete_collection(name=collection_name)
|
CHROMA_CLIENT.delete_collection(name=collection_name)
|
||||||
|
|
||||||
collection = CHROMA_CLIENT.create_collection(
|
collection = CHROMA_CLIENT.create_collection(
|
||||||
|
@ -338,7 +346,7 @@ def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> b
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
log.exception(e)
|
||||||
if e.__class__.__name__ == "UniqueConstraintError":
|
if e.__class__.__name__ == "UniqueConstraintError":
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -402,6 +410,8 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
|
||||||
loader = UnstructuredRSTLoader(file_path, mode="elements")
|
loader = UnstructuredRSTLoader(file_path, mode="elements")
|
||||||
elif file_ext == "xml":
|
elif file_ext == "xml":
|
||||||
loader = UnstructuredXMLLoader(file_path)
|
loader = UnstructuredXMLLoader(file_path)
|
||||||
|
elif file_ext in ["htm", "html"]:
|
||||||
|
loader = BSHTMLLoader(file_path, open_encoding="unicode_escape")
|
||||||
elif file_ext == "md":
|
elif file_ext == "md":
|
||||||
loader = UnstructuredMarkdownLoader(file_path)
|
loader = UnstructuredMarkdownLoader(file_path)
|
||||||
elif file_content_type == "application/epub+zip":
|
elif file_content_type == "application/epub+zip":
|
||||||
|
@ -438,8 +448,11 @@ def store_doc(
|
||||||
|
|
||||||
log.info(f"file.content_type: {file.content_type}")
|
log.info(f"file.content_type: {file.content_type}")
|
||||||
try:
|
try:
|
||||||
filename = file.filename
|
unsanitized_filename = file.filename
|
||||||
|
filename = os.path.basename(unsanitized_filename)
|
||||||
|
|
||||||
file_path = f"{UPLOAD_DIR}/{filename}"
|
file_path = f"{UPLOAD_DIR}/{filename}"
|
||||||
|
|
||||||
contents = file.file.read()
|
contents = file.file.read()
|
||||||
with open(file_path, "wb") as f:
|
with open(file_path, "wb") as f:
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
@ -450,21 +463,23 @@ def store_doc(
|
||||||
collection_name = calculate_sha256(f)[:63]
|
collection_name = calculate_sha256(f)[:63]
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
loader, known_type = get_loader(file.filename, file.content_type, file_path)
|
loader, known_type = get_loader(filename, file.content_type, file_path)
|
||||||
data = loader.load()
|
data = loader.load()
|
||||||
result = store_data_in_vector_db(data, collection_name)
|
|
||||||
|
|
||||||
if result:
|
try:
|
||||||
return {
|
result = store_data_in_vector_db(data, collection_name)
|
||||||
"status": True,
|
|
||||||
"collection_name": collection_name,
|
if result:
|
||||||
"filename": filename,
|
return {
|
||||||
"known_type": known_type,
|
"status": True,
|
||||||
}
|
"collection_name": collection_name,
|
||||||
else:
|
"filename": filename,
|
||||||
|
"known_type": known_type,
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
detail=ERROR_MESSAGES.DEFAULT(),
|
detail=e,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
|
@ -529,38 +544,42 @@ def scan_docs_dir(user=Depends(get_admin_user)):
|
||||||
)
|
)
|
||||||
data = loader.load()
|
data = loader.load()
|
||||||
|
|
||||||
result = store_data_in_vector_db(data, collection_name)
|
try:
|
||||||
|
result = store_data_in_vector_db(data, collection_name)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
sanitized_filename = sanitize_filename(filename)
|
sanitized_filename = sanitize_filename(filename)
|
||||||
doc = Documents.get_doc_by_name(sanitized_filename)
|
doc = Documents.get_doc_by_name(sanitized_filename)
|
||||||
|
|
||||||
if doc == None:
|
if doc == None:
|
||||||
doc = Documents.insert_new_doc(
|
doc = Documents.insert_new_doc(
|
||||||
user.id,
|
user.id,
|
||||||
DocumentForm(
|
DocumentForm(
|
||||||
**{
|
**{
|
||||||
"name": sanitized_filename,
|
"name": sanitized_filename,
|
||||||
"title": filename,
|
"title": filename,
|
||||||
"collection_name": collection_name,
|
"collection_name": collection_name,
|
||||||
"filename": filename,
|
"filename": filename,
|
||||||
"content": (
|
"content": (
|
||||||
json.dumps(
|
json.dumps(
|
||||||
{
|
{
|
||||||
"tags": list(
|
"tags": list(
|
||||||
map(
|
map(
|
||||||
lambda name: {"name": name},
|
lambda name: {"name": name},
|
||||||
tags,
|
tags,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
)
|
if len(tags)
|
||||||
if len(tags)
|
else "{}"
|
||||||
else "{}"
|
),
|
||||||
),
|
}
|
||||||
}
|
),
|
||||||
),
|
)
|
||||||
)
|
except Exception as e:
|
||||||
|
log.exception(e)
|
||||||
|
pass
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
|
|
|
@ -156,6 +156,8 @@ def rag_messages(docs, messages, template, k, embedding_function):
|
||||||
|
|
||||||
relevant_contexts.append(context)
|
relevant_contexts.append(context)
|
||||||
|
|
||||||
|
log.debug(f"relevant_contexts: {relevant_contexts}")
|
||||||
|
|
||||||
context_string = ""
|
context_string = ""
|
||||||
for context in relevant_contexts:
|
for context in relevant_contexts:
|
||||||
if context:
|
if context:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from peewee import *
|
from peewee import *
|
||||||
|
from peewee_migrate import Router
|
||||||
from config import SRC_LOG_LEVELS, DATA_DIR
|
from config import SRC_LOG_LEVELS, DATA_DIR
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
@ -16,4 +17,6 @@ else:
|
||||||
|
|
||||||
|
|
||||||
DB = SqliteDatabase(f"{DATA_DIR}/webui.db")
|
DB = SqliteDatabase(f"{DATA_DIR}/webui.db")
|
||||||
DB.connect()
|
router = Router(DB, migrate_dir="apps/web/internal/migrations", logger=log)
|
||||||
|
router.run()
|
||||||
|
DB.connect(reuse_if_open=True)
|
||||||
|
|
149
backend/apps/web/internal/migrations/001_initial_schema.py
Normal file
149
backend/apps/web/internal/migrations/001_initial_schema.py
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
"""Peewee migrations -- 001_initial_schema.py.
|
||||||
|
|
||||||
|
Some examples (model - class or model name)::
|
||||||
|
|
||||||
|
> Model = migrator.orm['table_name'] # Return model in current state by name
|
||||||
|
> Model = migrator.ModelClass # Return model in current state by name
|
||||||
|
|
||||||
|
> migrator.sql(sql) # Run custom SQL
|
||||||
|
> migrator.run(func, *args, **kwargs) # Run python function with the given args
|
||||||
|
> migrator.create_model(Model) # Create a model (could be used as decorator)
|
||||||
|
> migrator.remove_model(model, cascade=True) # Remove a model
|
||||||
|
> migrator.add_fields(model, **fields) # Add fields to a model
|
||||||
|
> migrator.change_fields(model, **fields) # Change fields
|
||||||
|
> migrator.remove_fields(model, *field_names, cascade=True)
|
||||||
|
> migrator.rename_field(model, old_field_name, new_field_name)
|
||||||
|
> migrator.rename_table(model, new_table_name)
|
||||||
|
> migrator.add_index(model, *col_names, unique=False)
|
||||||
|
> migrator.add_not_null(model, *field_names)
|
||||||
|
> migrator.add_default(model, field_name, default)
|
||||||
|
> migrator.add_constraint(model, name, sql)
|
||||||
|
> migrator.drop_index(model, *col_names)
|
||||||
|
> migrator.drop_not_null(model, *field_names)
|
||||||
|
> migrator.drop_constraints(model, *constraints)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
from peewee_migrate import Migrator
|
||||||
|
|
||||||
|
|
||||||
|
with suppress(ImportError):
|
||||||
|
import playhouse.postgres_ext as pw_pext
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your migrations here."""
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Auth(pw.Model):
|
||||||
|
id = pw.CharField(max_length=255, unique=True)
|
||||||
|
email = pw.CharField(max_length=255)
|
||||||
|
password = pw.CharField(max_length=255)
|
||||||
|
active = pw.BooleanField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "auth"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Chat(pw.Model):
|
||||||
|
id = pw.CharField(max_length=255, unique=True)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
title = pw.CharField()
|
||||||
|
chat = pw.TextField()
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "chat"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class ChatIdTag(pw.Model):
|
||||||
|
id = pw.CharField(max_length=255, unique=True)
|
||||||
|
tag_name = pw.CharField(max_length=255)
|
||||||
|
chat_id = pw.CharField(max_length=255)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "chatidtag"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Document(pw.Model):
|
||||||
|
id = pw.AutoField()
|
||||||
|
collection_name = pw.CharField(max_length=255, unique=True)
|
||||||
|
name = pw.CharField(max_length=255, unique=True)
|
||||||
|
title = pw.CharField()
|
||||||
|
filename = pw.CharField()
|
||||||
|
content = pw.TextField(null=True)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "document"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Modelfile(pw.Model):
|
||||||
|
id = pw.AutoField()
|
||||||
|
tag_name = pw.CharField(max_length=255, unique=True)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
modelfile = pw.TextField()
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "modelfile"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Prompt(pw.Model):
|
||||||
|
id = pw.AutoField()
|
||||||
|
command = pw.CharField(max_length=255, unique=True)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
title = pw.CharField()
|
||||||
|
content = pw.TextField()
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "prompt"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class Tag(pw.Model):
|
||||||
|
id = pw.CharField(max_length=255, unique=True)
|
||||||
|
name = pw.CharField(max_length=255)
|
||||||
|
user_id = pw.CharField(max_length=255)
|
||||||
|
data = pw.TextField(null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "tag"
|
||||||
|
|
||||||
|
@migrator.create_model
|
||||||
|
class User(pw.Model):
|
||||||
|
id = pw.CharField(max_length=255, unique=True)
|
||||||
|
name = pw.CharField(max_length=255)
|
||||||
|
email = pw.CharField(max_length=255)
|
||||||
|
role = pw.CharField(max_length=255)
|
||||||
|
profile_image_url = pw.CharField(max_length=255)
|
||||||
|
timestamp = pw.DateField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table_name = "user"
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your rollback migrations here."""
|
||||||
|
|
||||||
|
migrator.remove_model("user")
|
||||||
|
|
||||||
|
migrator.remove_model("tag")
|
||||||
|
|
||||||
|
migrator.remove_model("prompt")
|
||||||
|
|
||||||
|
migrator.remove_model("modelfile")
|
||||||
|
|
||||||
|
migrator.remove_model("document")
|
||||||
|
|
||||||
|
migrator.remove_model("chatidtag")
|
||||||
|
|
||||||
|
migrator.remove_model("chat")
|
||||||
|
|
||||||
|
migrator.remove_model("auth")
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""Peewee migrations -- 002_add_local_sharing.py.
|
||||||
|
|
||||||
|
Some examples (model - class or model name)::
|
||||||
|
|
||||||
|
> Model = migrator.orm['table_name'] # Return model in current state by name
|
||||||
|
> Model = migrator.ModelClass # Return model in current state by name
|
||||||
|
|
||||||
|
> migrator.sql(sql) # Run custom SQL
|
||||||
|
> migrator.run(func, *args, **kwargs) # Run python function with the given args
|
||||||
|
> migrator.create_model(Model) # Create a model (could be used as decorator)
|
||||||
|
> migrator.remove_model(model, cascade=True) # Remove a model
|
||||||
|
> migrator.add_fields(model, **fields) # Add fields to a model
|
||||||
|
> migrator.change_fields(model, **fields) # Change fields
|
||||||
|
> migrator.remove_fields(model, *field_names, cascade=True)
|
||||||
|
> migrator.rename_field(model, old_field_name, new_field_name)
|
||||||
|
> migrator.rename_table(model, new_table_name)
|
||||||
|
> migrator.add_index(model, *col_names, unique=False)
|
||||||
|
> migrator.add_not_null(model, *field_names)
|
||||||
|
> migrator.add_default(model, field_name, default)
|
||||||
|
> migrator.add_constraint(model, name, sql)
|
||||||
|
> migrator.drop_index(model, *col_names)
|
||||||
|
> migrator.drop_not_null(model, *field_names)
|
||||||
|
> migrator.drop_constraints(model, *constraints)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
from peewee_migrate import Migrator
|
||||||
|
|
||||||
|
|
||||||
|
with suppress(ImportError):
|
||||||
|
import playhouse.postgres_ext as pw_pext
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your migrations here."""
|
||||||
|
|
||||||
|
migrator.add_fields(
|
||||||
|
"chat", share_id=pw.CharField(max_length=255, null=True, unique=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your rollback migrations here."""
|
||||||
|
|
||||||
|
migrator.remove_fields("chat", "share_id")
|
48
backend/apps/web/internal/migrations/003_add_auth_api_key.py
Normal file
48
backend/apps/web/internal/migrations/003_add_auth_api_key.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
"""Peewee migrations -- 002_add_local_sharing.py.
|
||||||
|
|
||||||
|
Some examples (model - class or model name)::
|
||||||
|
|
||||||
|
> Model = migrator.orm['table_name'] # Return model in current state by name
|
||||||
|
> Model = migrator.ModelClass # Return model in current state by name
|
||||||
|
|
||||||
|
> migrator.sql(sql) # Run custom SQL
|
||||||
|
> migrator.run(func, *args, **kwargs) # Run python function with the given args
|
||||||
|
> migrator.create_model(Model) # Create a model (could be used as decorator)
|
||||||
|
> migrator.remove_model(model, cascade=True) # Remove a model
|
||||||
|
> migrator.add_fields(model, **fields) # Add fields to a model
|
||||||
|
> migrator.change_fields(model, **fields) # Change fields
|
||||||
|
> migrator.remove_fields(model, *field_names, cascade=True)
|
||||||
|
> migrator.rename_field(model, old_field_name, new_field_name)
|
||||||
|
> migrator.rename_table(model, new_table_name)
|
||||||
|
> migrator.add_index(model, *col_names, unique=False)
|
||||||
|
> migrator.add_not_null(model, *field_names)
|
||||||
|
> migrator.add_default(model, field_name, default)
|
||||||
|
> migrator.add_constraint(model, name, sql)
|
||||||
|
> migrator.drop_index(model, *col_names)
|
||||||
|
> migrator.drop_not_null(model, *field_names)
|
||||||
|
> migrator.drop_constraints(model, *constraints)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
|
import peewee as pw
|
||||||
|
from peewee_migrate import Migrator
|
||||||
|
|
||||||
|
|
||||||
|
with suppress(ImportError):
|
||||||
|
import playhouse.postgres_ext as pw_pext
|
||||||
|
|
||||||
|
|
||||||
|
def migrate(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your migrations here."""
|
||||||
|
|
||||||
|
migrator.add_fields(
|
||||||
|
"user", api_key=pw.CharField(max_length=255, null=True, unique=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||||
|
"""Write your rollback migrations here."""
|
||||||
|
|
||||||
|
migrator.remove_fields("user", "api_key")
|
21
backend/apps/web/internal/migrations/README.md
Normal file
21
backend/apps/web/internal/migrations/README.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Database Migrations
|
||||||
|
|
||||||
|
This directory contains all the database migrations for the web app.
|
||||||
|
Migrations are done using the [`peewee-migrate`](https://github.com/klen/peewee_migrate) library.
|
||||||
|
|
||||||
|
Migrations are automatically ran at app startup.
|
||||||
|
|
||||||
|
## Creating a migration
|
||||||
|
|
||||||
|
Have you made a change to the schema of an existing model?
|
||||||
|
You will need to create a migration file to ensure that existing databases are updated for backwards compatibility.
|
||||||
|
|
||||||
|
1. Have a database file (`webui.db`) that has the old schema prior to any of your changes.
|
||||||
|
2. Make your changes to the models.
|
||||||
|
3. From the `backend` directory, run the following command:
|
||||||
|
```bash
|
||||||
|
pw_migrate create --auto --auto-source apps.web.models --database sqlite:///${SQLITE_DB} --directory apps/web/internal/migrations ${MIGRATION_NAME}
|
||||||
|
```
|
||||||
|
- `$SQLITE_DB` should be the path to the database file.
|
||||||
|
- `$MIGRATION_NAME` should be a descriptive name for the migration.
|
||||||
|
4. The migration file will be created in the `apps/web/internal/migrations` directory.
|
|
@ -20,6 +20,7 @@ from config import (
|
||||||
ENABLE_SIGNUP,
|
ENABLE_SIGNUP,
|
||||||
USER_PERMISSIONS,
|
USER_PERMISSIONS,
|
||||||
WEBHOOK_URL,
|
WEBHOOK_URL,
|
||||||
|
WEBUI_AUTH_TRUSTED_EMAIL_HEADER,
|
||||||
)
|
)
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
@ -34,7 +35,7 @@ app.state.DEFAULT_PROMPT_SUGGESTIONS = DEFAULT_PROMPT_SUGGESTIONS
|
||||||
app.state.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE
|
app.state.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE
|
||||||
app.state.USER_PERMISSIONS = USER_PERMISSIONS
|
app.state.USER_PERMISSIONS = USER_PERMISSIONS
|
||||||
app.state.WEBHOOK_URL = WEBHOOK_URL
|
app.state.WEBHOOK_URL = WEBHOOK_URL
|
||||||
|
app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
|
|
|
@ -11,6 +11,7 @@ from utils.utils import verify_password
|
||||||
from apps.web.internal.db import DB
|
from apps.web.internal.db import DB
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
||||||
|
|
||||||
|
@ -46,6 +47,10 @@ class Token(BaseModel):
|
||||||
token_type: str
|
token_type: str
|
||||||
|
|
||||||
|
|
||||||
|
class ApiKey(BaseModel):
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
class UserResponse(BaseModel):
|
class UserResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
email: str
|
email: str
|
||||||
|
@ -122,6 +127,28 @@ class AuthsTable:
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def authenticate_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
|
||||||
|
log.info(f"authenticate_user_by_api_key: {api_key}")
|
||||||
|
# if no api_key, return None
|
||||||
|
if not api_key:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = Users.get_user_by_api_key(api_key)
|
||||||
|
return user if user else None
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def authenticate_user_by_trusted_header(self, email: str) -> Optional[UserModel]:
|
||||||
|
log.info(f"authenticate_user_by_trusted_header: {email}")
|
||||||
|
try:
|
||||||
|
auth = Auth.get(Auth.email == email, Auth.active == True)
|
||||||
|
if auth:
|
||||||
|
user = Users.get_user_by_id(auth.id)
|
||||||
|
return user
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def update_user_password_by_id(self, id: str, new_password: str) -> bool:
|
def update_user_password_by_id(self, id: str, new_password: str) -> bool:
|
||||||
try:
|
try:
|
||||||
query = Auth.update(password=new_password).where(Auth.id == id)
|
query = Auth.update(password=new_password).where(Auth.id == id)
|
||||||
|
|
|
@ -20,6 +20,7 @@ class Chat(Model):
|
||||||
title = CharField()
|
title = CharField()
|
||||||
chat = TextField() # Save Chat JSON as Text
|
chat = TextField() # Save Chat JSON as Text
|
||||||
timestamp = DateField()
|
timestamp = DateField()
|
||||||
|
share_id = CharField(null=True, unique=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
database = DB
|
database = DB
|
||||||
|
@ -31,6 +32,7 @@ class ChatModel(BaseModel):
|
||||||
title: str
|
title: str
|
||||||
chat: str
|
chat: str
|
||||||
timestamp: int # timestamp in epoch
|
timestamp: int # timestamp in epoch
|
||||||
|
share_id: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -52,6 +54,7 @@ class ChatResponse(BaseModel):
|
||||||
title: str
|
title: str
|
||||||
chat: dict
|
chat: dict
|
||||||
timestamp: int # timestamp in epoch
|
timestamp: int # timestamp in epoch
|
||||||
|
share_id: Optional[str] = None # id of the chat to be shared
|
||||||
|
|
||||||
|
|
||||||
class ChatTitleIdResponse(BaseModel):
|
class ChatTitleIdResponse(BaseModel):
|
||||||
|
@ -95,6 +98,71 @@ class ChatTable:
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def insert_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]:
|
||||||
|
# Get the existing chat to share
|
||||||
|
chat = Chat.get(Chat.id == chat_id)
|
||||||
|
# Check if the chat is already shared
|
||||||
|
if chat.share_id:
|
||||||
|
return self.get_chat_by_id_and_user_id(chat.share_id, "shared")
|
||||||
|
# Create a new chat with the same data, but with a new ID
|
||||||
|
shared_chat = ChatModel(
|
||||||
|
**{
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"user_id": f"shared-{chat_id}",
|
||||||
|
"title": chat.title,
|
||||||
|
"chat": chat.chat,
|
||||||
|
"timestamp": int(time.time()),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
shared_result = Chat.create(**shared_chat.model_dump())
|
||||||
|
# Update the original chat with the share_id
|
||||||
|
result = (
|
||||||
|
Chat.update(share_id=shared_chat.id).where(Chat.id == chat_id).execute()
|
||||||
|
)
|
||||||
|
|
||||||
|
return shared_chat if (shared_result and result) else None
|
||||||
|
|
||||||
|
def update_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]:
|
||||||
|
try:
|
||||||
|
print("update_shared_chat_by_id")
|
||||||
|
chat = Chat.get(Chat.id == chat_id)
|
||||||
|
print(chat)
|
||||||
|
|
||||||
|
query = Chat.update(
|
||||||
|
title=chat.title,
|
||||||
|
chat=chat.chat,
|
||||||
|
).where(Chat.id == chat.share_id)
|
||||||
|
|
||||||
|
query.execute()
|
||||||
|
|
||||||
|
chat = Chat.get(Chat.id == chat.share_id)
|
||||||
|
return ChatModel(**model_to_dict(chat))
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def delete_shared_chat_by_chat_id(self, chat_id: str) -> bool:
|
||||||
|
try:
|
||||||
|
query = Chat.delete().where(Chat.user_id == f"shared-{chat_id}")
|
||||||
|
query.execute() # Remove the rows, return number of rows removed.
|
||||||
|
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_chat_share_id_by_id(
|
||||||
|
self, id: str, share_id: Optional[str]
|
||||||
|
) -> Optional[ChatModel]:
|
||||||
|
try:
|
||||||
|
query = Chat.update(
|
||||||
|
share_id=share_id,
|
||||||
|
).where(Chat.id == id)
|
||||||
|
query.execute()
|
||||||
|
|
||||||
|
chat = Chat.get(Chat.id == id)
|
||||||
|
return ChatModel(**model_to_dict(chat))
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_chat_lists_by_user_id(
|
def get_chat_lists_by_user_id(
|
||||||
self, user_id: str, skip: int = 0, limit: int = 50
|
self, user_id: str, skip: int = 0, limit: int = 50
|
||||||
) -> List[ChatModel]:
|
) -> List[ChatModel]:
|
||||||
|
@ -131,6 +199,13 @@ class ChatTable:
|
||||||
.order_by(Chat.timestamp.desc())
|
.order_by(Chat.timestamp.desc())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_chat_by_id(self, id: str) -> Optional[ChatModel]:
|
||||||
|
try:
|
||||||
|
chat = Chat.get(Chat.id == id)
|
||||||
|
return ChatModel(**model_to_dict(chat))
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]:
|
def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]:
|
||||||
try:
|
try:
|
||||||
chat = Chat.get(Chat.id == id, Chat.user_id == user_id)
|
chat = Chat.get(Chat.id == id, Chat.user_id == user_id)
|
||||||
|
@ -149,12 +224,15 @@ class ChatTable:
|
||||||
query = Chat.delete().where((Chat.id == id) & (Chat.user_id == user_id))
|
query = Chat.delete().where((Chat.id == id) & (Chat.user_id == user_id))
|
||||||
query.execute() # Remove the rows, return number of rows removed.
|
query.execute() # Remove the rows, return number of rows removed.
|
||||||
|
|
||||||
return True
|
return True and self.delete_shared_chat_by_chat_id(id)
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def delete_chats_by_user_id(self, user_id: str) -> bool:
|
def delete_chats_by_user_id(self, user_id: str) -> bool:
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
self.delete_shared_chats_by_user_id(user_id)
|
||||||
|
|
||||||
query = Chat.delete().where(Chat.user_id == user_id)
|
query = Chat.delete().where(Chat.user_id == user_id)
|
||||||
query.execute() # Remove the rows, return number of rows removed.
|
query.execute() # Remove the rows, return number of rows removed.
|
||||||
|
|
||||||
|
@ -162,5 +240,19 @@ class ChatTable:
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def delete_shared_chats_by_user_id(self, user_id: str) -> bool:
|
||||||
|
try:
|
||||||
|
shared_chat_ids = [
|
||||||
|
f"shared-{chat.id}"
|
||||||
|
for chat in Chat.select().where(Chat.user_id == user_id)
|
||||||
|
]
|
||||||
|
|
||||||
|
query = Chat.delete().where(Chat.user_id << shared_chat_ids)
|
||||||
|
query.execute() # Remove the rows, return number of rows removed.
|
||||||
|
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
Chats = ChatTable(DB)
|
Chats = ChatTable(DB)
|
||||||
|
|
|
@ -13,6 +13,7 @@ from apps.web.internal.db import DB
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ class ModelfilesTable:
|
||||||
self.db.create_tables([Modelfile])
|
self.db.create_tables([Modelfile])
|
||||||
|
|
||||||
def insert_new_modelfile(
|
def insert_new_modelfile(
|
||||||
self, user_id: str,
|
self, user_id: str, form_data: ModelfileForm
|
||||||
form_data: ModelfileForm) -> Optional[ModelfileModel]:
|
) -> Optional[ModelfileModel]:
|
||||||
if "tagName" in form_data.modelfile:
|
if "tagName" in form_data.modelfile:
|
||||||
modelfile = ModelfileModel(
|
modelfile = ModelfileModel(
|
||||||
**{
|
**{
|
||||||
|
@ -73,7 +73,8 @@ class ModelfilesTable:
|
||||||
"tag_name": form_data.modelfile["tagName"],
|
"tag_name": form_data.modelfile["tagName"],
|
||||||
"modelfile": json.dumps(form_data.modelfile),
|
"modelfile": json.dumps(form_data.modelfile),
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = Modelfile.create(**modelfile.model_dump())
|
result = Modelfile.create(**modelfile.model_dump())
|
||||||
|
@ -87,29 +88,28 @@ class ModelfilesTable:
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_modelfile_by_tag_name(self,
|
def get_modelfile_by_tag_name(self, tag_name: str) -> Optional[ModelfileModel]:
|
||||||
tag_name: str) -> Optional[ModelfileModel]:
|
|
||||||
try:
|
try:
|
||||||
modelfile = Modelfile.get(Modelfile.tag_name == tag_name)
|
modelfile = Modelfile.get(Modelfile.tag_name == tag_name)
|
||||||
return ModelfileModel(**model_to_dict(modelfile))
|
return ModelfileModel(**model_to_dict(modelfile))
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_modelfiles(self,
|
def get_modelfiles(self, skip: int = 0, limit: int = 50) -> List[ModelfileResponse]:
|
||||||
skip: int = 0,
|
|
||||||
limit: int = 50) -> List[ModelfileResponse]:
|
|
||||||
return [
|
return [
|
||||||
ModelfileResponse(
|
ModelfileResponse(
|
||||||
**{
|
**{
|
||||||
**model_to_dict(modelfile),
|
**model_to_dict(modelfile),
|
||||||
"modelfile":
|
"modelfile": json.loads(modelfile.modelfile),
|
||||||
json.loads(modelfile.modelfile),
|
}
|
||||||
}) for modelfile in Modelfile.select()
|
)
|
||||||
|
for modelfile in Modelfile.select()
|
||||||
# .limit(limit).offset(skip)
|
# .limit(limit).offset(skip)
|
||||||
]
|
]
|
||||||
|
|
||||||
def update_modelfile_by_tag_name(
|
def update_modelfile_by_tag_name(
|
||||||
self, tag_name: str, modelfile: dict) -> Optional[ModelfileModel]:
|
self, tag_name: str, modelfile: dict
|
||||||
|
) -> Optional[ModelfileModel]:
|
||||||
try:
|
try:
|
||||||
query = Modelfile.update(
|
query = Modelfile.update(
|
||||||
modelfile=json.dumps(modelfile),
|
modelfile=json.dumps(modelfile),
|
||||||
|
|
|
@ -52,8 +52,9 @@ class PromptsTable:
|
||||||
self.db = db
|
self.db = db
|
||||||
self.db.create_tables([Prompt])
|
self.db.create_tables([Prompt])
|
||||||
|
|
||||||
def insert_new_prompt(self, user_id: str,
|
def insert_new_prompt(
|
||||||
form_data: PromptForm) -> Optional[PromptModel]:
|
self, user_id: str, form_data: PromptForm
|
||||||
|
) -> Optional[PromptModel]:
|
||||||
prompt = PromptModel(
|
prompt = PromptModel(
|
||||||
**{
|
**{
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
|
@ -61,7 +62,8 @@ class PromptsTable:
|
||||||
"title": form_data.title,
|
"title": form_data.title,
|
||||||
"content": form_data.content,
|
"content": form_data.content,
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = Prompt.create(**prompt.model_dump())
|
result = Prompt.create(**prompt.model_dump())
|
||||||
|
@ -81,13 +83,14 @@ class PromptsTable:
|
||||||
|
|
||||||
def get_prompts(self) -> List[PromptModel]:
|
def get_prompts(self) -> List[PromptModel]:
|
||||||
return [
|
return [
|
||||||
PromptModel(**model_to_dict(prompt)) for prompt in Prompt.select()
|
PromptModel(**model_to_dict(prompt))
|
||||||
|
for prompt in Prompt.select()
|
||||||
# .limit(limit).offset(skip)
|
# .limit(limit).offset(skip)
|
||||||
]
|
]
|
||||||
|
|
||||||
def update_prompt_by_command(
|
def update_prompt_by_command(
|
||||||
self, command: str,
|
self, command: str, form_data: PromptForm
|
||||||
form_data: PromptForm) -> Optional[PromptModel]:
|
) -> Optional[PromptModel]:
|
||||||
try:
|
try:
|
||||||
query = Prompt.update(
|
query = Prompt.update(
|
||||||
title=form_data.title,
|
title=form_data.title,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import logging
|
||||||
from apps.web.internal.db import DB
|
from apps.web.internal.db import DB
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class User(Model):
|
||||||
role = CharField()
|
role = CharField()
|
||||||
profile_image_url = CharField()
|
profile_image_url = CharField()
|
||||||
timestamp = DateField()
|
timestamp = DateField()
|
||||||
|
api_key = CharField(null=True, unique=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
database = DB
|
database = DB
|
||||||
|
@ -32,6 +33,7 @@ class UserModel(BaseModel):
|
||||||
role: str = "pending"
|
role: str = "pending"
|
||||||
profile_image_url: str = "/user.png"
|
profile_image_url: str = "/user.png"
|
||||||
timestamp: int # timestamp in epoch
|
timestamp: int # timestamp in epoch
|
||||||
|
api_key: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -82,6 +84,13 @@ class UsersTable:
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
|
||||||
|
try:
|
||||||
|
user = User.get(User.api_key == api_key)
|
||||||
|
return UserModel(**model_to_dict(user))
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_user_by_email(self, email: str) -> Optional[UserModel]:
|
def get_user_by_email(self, email: str) -> Optional[UserModel]:
|
||||||
try:
|
try:
|
||||||
user = User.get(User.email == email)
|
user = User.get(User.email == email)
|
||||||
|
@ -149,5 +158,21 @@ class UsersTable:
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def update_user_api_key_by_id(self, id: str, api_key: str) -> str:
|
||||||
|
try:
|
||||||
|
query = User.update(api_key=api_key).where(User.id == id)
|
||||||
|
result = query.execute()
|
||||||
|
|
||||||
|
return True if result == 1 else False
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_user_api_key_by_id(self, id: str) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
user = User.get(User.id == id)
|
||||||
|
return user.api_key
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
Users = UsersTable(DB)
|
Users = UsersTable(DB)
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
from fastapi import Response, Request
|
from fastapi import Request
|
||||||
from fastapi import Depends, FastAPI, HTTPException, status
|
from fastapi import Depends, HTTPException, status
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import List, Union
|
|
||||||
|
|
||||||
from fastapi import APIRouter, status
|
from fastapi import APIRouter
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
import re
|
import re
|
||||||
|
import uuid
|
||||||
|
|
||||||
from apps.web.models.auths import (
|
from apps.web.models.auths import (
|
||||||
SigninForm,
|
SigninForm,
|
||||||
|
@ -17,6 +14,7 @@ from apps.web.models.auths import (
|
||||||
UserResponse,
|
UserResponse,
|
||||||
SigninResponse,
|
SigninResponse,
|
||||||
Auths,
|
Auths,
|
||||||
|
ApiKey,
|
||||||
)
|
)
|
||||||
from apps.web.models.users import Users
|
from apps.web.models.users import Users
|
||||||
|
|
||||||
|
@ -25,10 +23,12 @@ from utils.utils import (
|
||||||
get_current_user,
|
get_current_user,
|
||||||
get_admin_user,
|
get_admin_user,
|
||||||
create_token,
|
create_token,
|
||||||
|
create_api_key,
|
||||||
)
|
)
|
||||||
from utils.misc import parse_duration, validate_email_format
|
from utils.misc import parse_duration, validate_email_format
|
||||||
from utils.webhook import post_webhook
|
from utils.webhook import post_webhook
|
||||||
from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
|
from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
|
||||||
|
from config import WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ async def update_profile(
|
||||||
async def update_password(
|
async def update_password(
|
||||||
form_data: UpdatePasswordForm, session_user=Depends(get_current_user)
|
form_data: UpdatePasswordForm, session_user=Depends(get_current_user)
|
||||||
):
|
):
|
||||||
|
if WEBUI_AUTH_TRUSTED_EMAIL_HEADER:
|
||||||
|
raise HTTPException(400, detail=ERROR_MESSAGES.ACTION_PROHIBITED)
|
||||||
if session_user:
|
if session_user:
|
||||||
user = Auths.authenticate_user(session_user.email, form_data.password)
|
user = Auths.authenticate_user(session_user.email, form_data.password)
|
||||||
|
|
||||||
|
@ -98,7 +100,22 @@ async def update_password(
|
||||||
|
|
||||||
@router.post("/signin", response_model=SigninResponse)
|
@router.post("/signin", response_model=SigninResponse)
|
||||||
async def signin(request: Request, form_data: SigninForm):
|
async def signin(request: Request, form_data: SigninForm):
|
||||||
user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
|
if WEBUI_AUTH_TRUSTED_EMAIL_HEADER:
|
||||||
|
if WEBUI_AUTH_TRUSTED_EMAIL_HEADER not in request.headers:
|
||||||
|
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_TRUSTED_HEADER)
|
||||||
|
|
||||||
|
trusted_email = request.headers[WEBUI_AUTH_TRUSTED_EMAIL_HEADER].lower()
|
||||||
|
if not Users.get_user_by_email(trusted_email.lower()):
|
||||||
|
await signup(
|
||||||
|
request,
|
||||||
|
SignupForm(
|
||||||
|
email=trusted_email, password=str(uuid.uuid4()), name=trusted_email
|
||||||
|
),
|
||||||
|
)
|
||||||
|
user = Auths.authenticate_user_by_trusted_header(trusted_email)
|
||||||
|
else:
|
||||||
|
user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
token = create_token(
|
token = create_token(
|
||||||
data={"id": user.id},
|
data={"id": user.id},
|
||||||
|
@ -249,3 +266,40 @@ async def update_token_expires_duration(
|
||||||
return request.app.state.JWT_EXPIRES_IN
|
return request.app.state.JWT_EXPIRES_IN
|
||||||
else:
|
else:
|
||||||
return request.app.state.JWT_EXPIRES_IN
|
return request.app.state.JWT_EXPIRES_IN
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# API Key
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
# create api key
|
||||||
|
@router.post("/api_key", response_model=ApiKey)
|
||||||
|
async def create_api_key_(user=Depends(get_current_user)):
|
||||||
|
api_key = create_api_key()
|
||||||
|
success = Users.update_user_api_key_by_id(user.id, api_key)
|
||||||
|
if success:
|
||||||
|
return {
|
||||||
|
"api_key": api_key,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_API_KEY_ERROR)
|
||||||
|
|
||||||
|
|
||||||
|
# delete api key
|
||||||
|
@router.delete("/api_key", response_model=bool)
|
||||||
|
async def delete_api_key(user=Depends(get_current_user)):
|
||||||
|
success = Users.update_user_api_key_by_id(user.id, None)
|
||||||
|
return success
|
||||||
|
|
||||||
|
|
||||||
|
# get api key
|
||||||
|
@router.get("/api_key", response_model=ApiKey)
|
||||||
|
async def get_api_key(user=Depends(get_current_user)):
|
||||||
|
api_key = Users.get_user_api_key_by_id(user.id)
|
||||||
|
if api_key:
|
||||||
|
return {
|
||||||
|
"api_key": api_key,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise HTTPException(404, detail=ERROR_MESSAGES.API_KEY_NOT_FOUND)
|
||||||
|
|
|
@ -29,6 +29,7 @@ from apps.web.models.tags import (
|
||||||
from constants import ERROR_MESSAGES
|
from constants import ERROR_MESSAGES
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
||||||
|
|
||||||
|
@ -188,6 +189,78 @@ async def delete_chat_by_id(request: Request, id: str, user=Depends(get_current_
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# ShareChatById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{id}/share", response_model=Optional[ChatResponse])
|
||||||
|
async def share_chat_by_id(id: str, user=Depends(get_current_user)):
|
||||||
|
chat = Chats.get_chat_by_id_and_user_id(id, user.id)
|
||||||
|
if chat:
|
||||||
|
if chat.share_id:
|
||||||
|
shared_chat = Chats.update_shared_chat_by_chat_id(chat.id)
|
||||||
|
return ChatResponse(
|
||||||
|
**{**shared_chat.model_dump(), "chat": json.loads(shared_chat.chat)}
|
||||||
|
)
|
||||||
|
|
||||||
|
shared_chat = Chats.insert_shared_chat_by_chat_id(chat.id)
|
||||||
|
if not shared_chat:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return ChatResponse(
|
||||||
|
**{**shared_chat.model_dump(), "chat": json.loads(shared_chat.chat)}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# DeletedSharedChatById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/{id}/share", response_model=Optional[bool])
|
||||||
|
async def delete_shared_chat_by_id(id: str, user=Depends(get_current_user)):
|
||||||
|
chat = Chats.get_chat_by_id_and_user_id(id, user.id)
|
||||||
|
if chat:
|
||||||
|
if not chat.share_id:
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = Chats.delete_shared_chat_by_chat_id(id)
|
||||||
|
update_result = Chats.update_chat_share_id_by_id(id, None)
|
||||||
|
|
||||||
|
return result and update_result != None
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# GetSharedChatById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/share/{share_id}", response_model=Optional[ChatResponse])
|
||||||
|
async def get_shared_chat_by_id(share_id: str, user=Depends(get_current_user)):
|
||||||
|
chat = Chats.get_chat_by_id(share_id)
|
||||||
|
|
||||||
|
if chat:
|
||||||
|
return ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)})
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# GetChatTagsById
|
# GetChatTagsById
|
||||||
############################
|
############################
|
||||||
|
|
|
@ -10,7 +10,12 @@ import uuid
|
||||||
|
|
||||||
from apps.web.models.users import Users
|
from apps.web.models.users import Users
|
||||||
|
|
||||||
from utils.utils import get_password_hash, get_current_user, get_admin_user, create_token
|
from utils.utils import (
|
||||||
|
get_password_hash,
|
||||||
|
get_current_user,
|
||||||
|
get_admin_user,
|
||||||
|
create_token,
|
||||||
|
)
|
||||||
from utils.misc import get_gravatar_url, validate_email_format
|
from utils.misc import get_gravatar_url, validate_email_format
|
||||||
from constants import ERROR_MESSAGES
|
from constants import ERROR_MESSAGES
|
||||||
|
|
||||||
|
@ -43,7 +48,6 @@ async def set_global_default_models(
|
||||||
return request.app.state.DEFAULT_MODELS
|
return request.app.state.DEFAULT_MODELS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/default/suggestions", response_model=List[PromptSuggestion])
|
@router.post("/default/suggestions", response_model=List[PromptSuggestion])
|
||||||
async def set_global_default_suggestions(
|
async def set_global_default_suggestions(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|
|
@ -24,9 +24,9 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=List[ModelfileResponse])
|
@router.get("/", response_model=List[ModelfileResponse])
|
||||||
async def get_modelfiles(skip: int = 0,
|
async def get_modelfiles(
|
||||||
limit: int = 50,
|
skip: int = 0, limit: int = 50, user=Depends(get_current_user)
|
||||||
user=Depends(get_current_user)):
|
):
|
||||||
return Modelfiles.get_modelfiles(skip, limit)
|
return Modelfiles.get_modelfiles(skip, limit)
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,17 +36,16 @@ async def get_modelfiles(skip: int = 0,
|
||||||
|
|
||||||
|
|
||||||
@router.post("/create", response_model=Optional[ModelfileResponse])
|
@router.post("/create", response_model=Optional[ModelfileResponse])
|
||||||
async def create_new_modelfile(form_data: ModelfileForm,
|
async def create_new_modelfile(form_data: ModelfileForm, user=Depends(get_admin_user)):
|
||||||
user=Depends(get_admin_user)):
|
|
||||||
modelfile = Modelfiles.insert_new_modelfile(user.id, form_data)
|
modelfile = Modelfiles.insert_new_modelfile(user.id, form_data)
|
||||||
|
|
||||||
if modelfile:
|
if modelfile:
|
||||||
return ModelfileResponse(
|
return ModelfileResponse(
|
||||||
**{
|
**{
|
||||||
**modelfile.model_dump(),
|
**modelfile.model_dump(),
|
||||||
"modelfile":
|
"modelfile": json.loads(modelfile.modelfile),
|
||||||
json.loads(modelfile.modelfile),
|
}
|
||||||
})
|
)
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
@ -60,17 +59,18 @@ async def create_new_modelfile(form_data: ModelfileForm,
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=Optional[ModelfileResponse])
|
@router.post("/", response_model=Optional[ModelfileResponse])
|
||||||
async def get_modelfile_by_tag_name(form_data: ModelfileTagNameForm,
|
async def get_modelfile_by_tag_name(
|
||||||
user=Depends(get_current_user)):
|
form_data: ModelfileTagNameForm, user=Depends(get_current_user)
|
||||||
|
):
|
||||||
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
||||||
|
|
||||||
if modelfile:
|
if modelfile:
|
||||||
return ModelfileResponse(
|
return ModelfileResponse(
|
||||||
**{
|
**{
|
||||||
**modelfile.model_dump(),
|
**modelfile.model_dump(),
|
||||||
"modelfile":
|
"modelfile": json.loads(modelfile.modelfile),
|
||||||
json.loads(modelfile.modelfile),
|
}
|
||||||
})
|
)
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
@ -84,8 +84,9 @@ async def get_modelfile_by_tag_name(form_data: ModelfileTagNameForm,
|
||||||
|
|
||||||
|
|
||||||
@router.post("/update", response_model=Optional[ModelfileResponse])
|
@router.post("/update", response_model=Optional[ModelfileResponse])
|
||||||
async def update_modelfile_by_tag_name(form_data: ModelfileUpdateForm,
|
async def update_modelfile_by_tag_name(
|
||||||
user=Depends(get_admin_user)):
|
form_data: ModelfileUpdateForm, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
modelfile = Modelfiles.get_modelfile_by_tag_name(form_data.tag_name)
|
||||||
if modelfile:
|
if modelfile:
|
||||||
updated_modelfile = {
|
updated_modelfile = {
|
||||||
|
@ -94,14 +95,15 @@ async def update_modelfile_by_tag_name(form_data: ModelfileUpdateForm,
|
||||||
}
|
}
|
||||||
|
|
||||||
modelfile = Modelfiles.update_modelfile_by_tag_name(
|
modelfile = Modelfiles.update_modelfile_by_tag_name(
|
||||||
form_data.tag_name, updated_modelfile)
|
form_data.tag_name, updated_modelfile
|
||||||
|
)
|
||||||
|
|
||||||
return ModelfileResponse(
|
return ModelfileResponse(
|
||||||
**{
|
**{
|
||||||
**modelfile.model_dump(),
|
**modelfile.model_dump(),
|
||||||
"modelfile":
|
"modelfile": json.loads(modelfile.modelfile),
|
||||||
json.loads(modelfile.modelfile),
|
}
|
||||||
})
|
)
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
@ -115,7 +117,8 @@ async def update_modelfile_by_tag_name(form_data: ModelfileUpdateForm,
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/delete", response_model=bool)
|
@router.delete("/delete", response_model=bool)
|
||||||
async def delete_modelfile_by_tag_name(form_data: ModelfileTagNameForm,
|
async def delete_modelfile_by_tag_name(
|
||||||
user=Depends(get_admin_user)):
|
form_data: ModelfileTagNameForm, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
result = Modelfiles.delete_modelfile_by_tag_name(form_data.tag_name)
|
result = Modelfiles.delete_modelfile_by_tag_name(form_data.tag_name)
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -16,6 +16,7 @@ from utils.utils import get_current_user, get_password_hash, get_admin_user
|
||||||
from constants import ERROR_MESSAGES
|
from constants import ERROR_MESSAGES
|
||||||
|
|
||||||
from config import SRC_LOG_LEVELS
|
from config import SRC_LOG_LEVELS
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
log.setLevel(SRC_LOG_LEVELS["MODELS"])
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
from fastapi import APIRouter, UploadFile, File, BackgroundTasks
|
from fastapi import APIRouter, UploadFile, File, Response
|
||||||
from fastapi import Depends, HTTPException, status
|
from fastapi import Depends, HTTPException, status
|
||||||
from starlette.responses import StreamingResponse, FileResponse
|
from starlette.responses import StreamingResponse, FileResponse
|
||||||
|
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
import requests
|
|
||||||
import os
|
from fpdf import FPDF
|
||||||
import aiohttp
|
import markdown
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
from utils.utils import get_admin_user
|
from utils.utils import get_admin_user
|
||||||
|
@ -16,7 +13,7 @@ from utils.misc import calculate_sha256, get_gravatar_url
|
||||||
|
|
||||||
from config import OLLAMA_BASE_URLS, DATA_DIR, UPLOAD_DIR
|
from config import OLLAMA_BASE_URLS, DATA_DIR, UPLOAD_DIR
|
||||||
from constants import ERROR_MESSAGES
|
from constants import ERROR_MESSAGES
|
||||||
|
from typing import List
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
@ -28,6 +25,70 @@ async def get_gravatar(
|
||||||
return get_gravatar_url(email)
|
return get_gravatar_url(email)
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownForm(BaseModel):
|
||||||
|
md: str
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/markdown")
|
||||||
|
async def get_html_from_markdown(
|
||||||
|
form_data: MarkdownForm,
|
||||||
|
):
|
||||||
|
return {"html": markdown.markdown(form_data.md)}
|
||||||
|
|
||||||
|
|
||||||
|
class ChatForm(BaseModel):
|
||||||
|
title: str
|
||||||
|
messages: List[dict]
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/pdf")
|
||||||
|
async def download_chat_as_pdf(
|
||||||
|
form_data: ChatForm,
|
||||||
|
):
|
||||||
|
pdf = FPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
|
||||||
|
STATIC_DIR = "./static"
|
||||||
|
FONTS_DIR = f"{STATIC_DIR}/fonts"
|
||||||
|
|
||||||
|
pdf.add_font("NotoSans", "", f"{FONTS_DIR}/NotoSans-Regular.ttf")
|
||||||
|
pdf.add_font("NotoSans", "b", f"{FONTS_DIR}/NotoSans-Bold.ttf")
|
||||||
|
pdf.add_font("NotoSans", "i", f"{FONTS_DIR}/NotoSans-Italic.ttf")
|
||||||
|
pdf.add_font("NotoSansKR", "", f"{FONTS_DIR}/NotoSansKR-Regular.ttf")
|
||||||
|
pdf.add_font("NotoSansJP", "", f"{FONTS_DIR}/NotoSansJP-Regular.ttf")
|
||||||
|
|
||||||
|
pdf.set_font("NotoSans", size=12)
|
||||||
|
pdf.set_fallback_fonts(["NotoSansKR", "NotoSansJP"])
|
||||||
|
|
||||||
|
pdf.set_auto_page_break(auto=True, margin=15)
|
||||||
|
|
||||||
|
# Adjust the effective page width for multi_cell
|
||||||
|
effective_page_width = (
|
||||||
|
pdf.w - 2 * pdf.l_margin - 10
|
||||||
|
) # Subtracted an additional 10 for extra padding
|
||||||
|
|
||||||
|
# Add chat messages
|
||||||
|
for message in form_data.messages:
|
||||||
|
role = message["role"]
|
||||||
|
content = message["content"]
|
||||||
|
pdf.set_font("NotoSans", "B", size=14) # Bold for the role
|
||||||
|
pdf.multi_cell(effective_page_width, 10, f"{role.upper()}", 0, "L")
|
||||||
|
pdf.ln(1) # Extra space between messages
|
||||||
|
|
||||||
|
pdf.set_font("NotoSans", size=10) # Regular for content
|
||||||
|
pdf.multi_cell(effective_page_width, 6, content, 0, "L")
|
||||||
|
pdf.ln(1.5) # Extra space between messages
|
||||||
|
|
||||||
|
# Save the pdf with name .pdf
|
||||||
|
pdf_bytes = pdf.output()
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
content=bytes(pdf_bytes),
|
||||||
|
media_type="application/pdf",
|
||||||
|
headers={"Content-Disposition": f"attachment;filename=chat.pdf"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/db/download")
|
@router.get("/db/download")
|
||||||
async def download_db(user=Depends(get_admin_user)):
|
async def download_db(user=Depends(get_admin_user)):
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,9 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
log.warning("dotenv not installed, skipping...")
|
log.warning("dotenv not installed, skipping...")
|
||||||
|
|
||||||
WEBUI_NAME = "Aura"
|
WEBUI_NAME = os.environ.get("WEBUI_NAME", "Open WebUI")
|
||||||
|
WEBUI_FAVICON_URL = "https://openwebui.com/favicon.png"
|
||||||
|
|
||||||
shutil.copyfile("../build/favicon.png", "./static/favicon.png")
|
shutil.copyfile("../build/favicon.png", "./static/favicon.png")
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
|
@ -116,7 +118,20 @@ else:
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.info(f"GLOBAL_LOG_LEVEL: {GLOBAL_LOG_LEVEL}")
|
log.info(f"GLOBAL_LOG_LEVEL: {GLOBAL_LOG_LEVEL}")
|
||||||
|
|
||||||
log_sources = ["AUDIO", "CONFIG", "DB", "IMAGES", "LITELLM", "MAIN", "MODELS", "OLLAMA", "OPENAI", "RAG"]
|
log_sources = [
|
||||||
|
"AUDIO",
|
||||||
|
"COMFYUI",
|
||||||
|
"CONFIG",
|
||||||
|
"DB",
|
||||||
|
"IMAGES",
|
||||||
|
"LITELLM",
|
||||||
|
"MAIN",
|
||||||
|
"MODELS",
|
||||||
|
"OLLAMA",
|
||||||
|
"OPENAI",
|
||||||
|
"RAG",
|
||||||
|
"WEBHOOK",
|
||||||
|
]
|
||||||
|
|
||||||
SRC_LOG_LEVELS = {}
|
SRC_LOG_LEVELS = {}
|
||||||
|
|
||||||
|
@ -135,13 +150,14 @@ log.setLevel(SRC_LOG_LEVELS["CONFIG"])
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "")
|
CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "")
|
||||||
|
|
||||||
if CUSTOM_NAME:
|
if CUSTOM_NAME:
|
||||||
try:
|
try:
|
||||||
r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}")
|
r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}")
|
||||||
data = r.json()
|
data = r.json()
|
||||||
if r.ok:
|
if r.ok:
|
||||||
if "logo" in data:
|
if "logo" in data:
|
||||||
url = (
|
WEBUI_FAVICON_URL = url = (
|
||||||
f"https://api.openwebui.com{data['logo']}"
|
f"https://api.openwebui.com{data['logo']}"
|
||||||
if data["logo"][0] == "/"
|
if data["logo"][0] == "/"
|
||||||
else data["logo"]
|
else data["logo"]
|
||||||
|
@ -157,7 +173,9 @@ if CUSTOM_NAME:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
if WEBUI_NAME != "Open WebUI":
|
||||||
|
WEBUI_NAME += " (Open WebUI)"
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# DATA/FRONTEND BUILD DIR
|
# DATA/FRONTEND BUILD DIR
|
||||||
|
@ -238,7 +256,7 @@ OLLAMA_API_BASE_URL = os.environ.get(
|
||||||
)
|
)
|
||||||
|
|
||||||
OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "")
|
OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "")
|
||||||
|
K8S_FLAG = os.environ.get("K8S_FLAG", "")
|
||||||
|
|
||||||
if OLLAMA_BASE_URL == "" and OLLAMA_API_BASE_URL != "":
|
if OLLAMA_BASE_URL == "" and OLLAMA_API_BASE_URL != "":
|
||||||
OLLAMA_BASE_URL = (
|
OLLAMA_BASE_URL = (
|
||||||
|
@ -251,6 +269,9 @@ if ENV == "prod":
|
||||||
if OLLAMA_BASE_URL == "/ollama":
|
if OLLAMA_BASE_URL == "/ollama":
|
||||||
OLLAMA_BASE_URL = "http://host.docker.internal:11434"
|
OLLAMA_BASE_URL = "http://host.docker.internal:11434"
|
||||||
|
|
||||||
|
elif K8S_FLAG:
|
||||||
|
OLLAMA_BASE_URL = "http://ollama-service.open-webui.svc.cluster.local:11434"
|
||||||
|
|
||||||
|
|
||||||
OLLAMA_BASE_URLS = os.environ.get("OLLAMA_BASE_URLS", "")
|
OLLAMA_BASE_URLS = os.environ.get("OLLAMA_BASE_URLS", "")
|
||||||
OLLAMA_BASE_URLS = OLLAMA_BASE_URLS if OLLAMA_BASE_URLS != "" else OLLAMA_BASE_URL
|
OLLAMA_BASE_URLS = OLLAMA_BASE_URLS if OLLAMA_BASE_URLS != "" else OLLAMA_BASE_URL
|
||||||
|
@ -345,6 +366,9 @@ WEBUI_VERSION = os.environ.get("WEBUI_VERSION", "v1.0.0-alpha.100")
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
WEBUI_AUTH = True
|
WEBUI_AUTH = True
|
||||||
|
WEBUI_AUTH_TRUSTED_EMAIL_HEADER = os.environ.get(
|
||||||
|
"WEBUI_AUTH_TRUSTED_EMAIL_HEADER", None
|
||||||
|
)
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# WEBUI_SECRET_KEY
|
# WEBUI_SECRET_KEY
|
||||||
|
|
|
@ -20,6 +20,7 @@ class ERROR_MESSAGES(str, Enum):
|
||||||
ENV_VAR_NOT_FOUND = "Required environment variable not found. Terminating now."
|
ENV_VAR_NOT_FOUND = "Required environment variable not found. Terminating now."
|
||||||
CREATE_USER_ERROR = "Oops! Something went wrong while creating your account. Please try again later. If the issue persists, contact support for assistance."
|
CREATE_USER_ERROR = "Oops! Something went wrong while creating your account. Please try again later. If the issue persists, contact support for assistance."
|
||||||
DELETE_USER_ERROR = "Oops! Something went wrong. We encountered an issue while trying to delete the user. Please give it another shot."
|
DELETE_USER_ERROR = "Oops! Something went wrong. We encountered an issue while trying to delete the user. Please give it another shot."
|
||||||
|
EMAIL_MISMATCH = "Uh-oh! This email does not match the email your provider is registered with. Please check your email and try again."
|
||||||
EMAIL_TAKEN = "Uh-oh! This email is already registered. Sign in with your existing account or choose another email to start anew."
|
EMAIL_TAKEN = "Uh-oh! This email is already registered. Sign in with your existing account or choose another email to start anew."
|
||||||
USERNAME_TAKEN = (
|
USERNAME_TAKEN = (
|
||||||
"Uh-oh! This username is already registered. Please choose another username."
|
"Uh-oh! This username is already registered. Please choose another username."
|
||||||
|
@ -36,6 +37,7 @@ class ERROR_MESSAGES(str, Enum):
|
||||||
INVALID_PASSWORD = (
|
INVALID_PASSWORD = (
|
||||||
"The password provided is incorrect. Please check for typos and try again."
|
"The password provided is incorrect. Please check for typos and try again."
|
||||||
)
|
)
|
||||||
|
INVALID_TRUSTED_HEADER = "Your provider has not provided a trusted header. Please contact your administrator for assistance."
|
||||||
UNAUTHORIZED = "401 Unauthorized"
|
UNAUTHORIZED = "401 Unauthorized"
|
||||||
ACCESS_PROHIBITED = "You do not have permission to access this resource. Please contact your administrator for assistance."
|
ACCESS_PROHIBITED = "You do not have permission to access this resource. Please contact your administrator for assistance."
|
||||||
ACTION_PROHIBITED = (
|
ACTION_PROHIBITED = (
|
||||||
|
@ -58,5 +60,8 @@ class ERROR_MESSAGES(str, Enum):
|
||||||
RATE_LIMIT_EXCEEDED = "API rate limit exceeded"
|
RATE_LIMIT_EXCEEDED = "API rate limit exceeded"
|
||||||
|
|
||||||
MODEL_NOT_FOUND = lambda name="": f"Model '{name}' was not found"
|
MODEL_NOT_FOUND = lambda name="": f"Model '{name}' was not found"
|
||||||
OPENAI_NOT_FOUND = lambda name="": f"OpenAI API was not found"
|
OPENAI_NOT_FOUND = lambda name="": "OpenAI API was not found"
|
||||||
OLLAMA_NOT_FOUND = "WebUI could not connect to Ollama"
|
OLLAMA_NOT_FOUND = "WebUI could not connect to Ollama"
|
||||||
|
CREATE_API_KEY_ERROR = "Oops! Something went wrong while creating your API key. Please try again later. If the issue persists, contact support for assistance."
|
||||||
|
|
||||||
|
EMPTY_CONTENT = "The content provided is empty. Please ensure that there is text or data present before proceeding."
|
||||||
|
|
|
@ -1,35 +1,24 @@
|
||||||
{
|
{
|
||||||
"version": 0,
|
"version": 0,
|
||||||
"ui": {
|
"ui": {
|
||||||
"prompt_suggestions": [
|
"default_locale": "en-US",
|
||||||
{
|
"prompt_suggestions": [
|
||||||
"title": [
|
{
|
||||||
"Help me study",
|
"title": ["Help me study", "vocabulary for a college entrance exam"],
|
||||||
"vocabulary for a college entrance exam"
|
"content": "Help me study vocabulary: write a sentence for me to fill in the blank, and I'll try to pick the correct option."
|
||||||
],
|
},
|
||||||
"content": "Help me study vocabulary: write a sentence for me to fill in the blank, and I'll try to pick the correct option."
|
{
|
||||||
},
|
"title": ["Give me ideas", "for what to do with my kids' art"],
|
||||||
{
|
"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."
|
||||||
"title": [
|
},
|
||||||
"Give me ideas",
|
{
|
||||||
"for what to do with my kids' art"
|
"title": ["Tell me a fun fact", "about the Roman Empire"],
|
||||||
],
|
"content": "Tell me a random fun fact about the Roman Empire"
|
||||||
"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."
|
},
|
||||||
},
|
{
|
||||||
{
|
"title": ["Show me a code snippet", "of a website's sticky header"],
|
||||||
"title": [
|
"content": "Show me a code snippet of a website's sticky header in CSS and JavaScript."
|
||||||
"Tell me a fun fact",
|
}
|
||||||
"about the Roman Empire"
|
]
|
||||||
],
|
}
|
||||||
"content": "Tell me a random fun fact about the Roman Empire"
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": [
|
|
||||||
"Show me a code snippet",
|
|
||||||
"of a website's sticky header"
|
|
||||||
],
|
|
||||||
"content": "Show me a code snippet of a website's sticky header in CSS and JavaScript."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ from utils.utils import get_admin_user
|
||||||
from apps.rag.utils import rag_messages
|
from apps.rag.utils import rag_messages
|
||||||
|
|
||||||
from config import (
|
from config import (
|
||||||
|
CONFIG_DATA,
|
||||||
WEBUI_NAME,
|
WEBUI_NAME,
|
||||||
ENV,
|
ENV,
|
||||||
VERSION,
|
VERSION,
|
||||||
|
@ -49,6 +50,7 @@ logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(SRC_LOG_LEVELS["MAIN"])
|
log.setLevel(SRC_LOG_LEVELS["MAIN"])
|
||||||
|
|
||||||
|
|
||||||
class SPAStaticFiles(StaticFiles):
|
class SPAStaticFiles(StaticFiles):
|
||||||
async def get_response(self, path: str, scope):
|
async def get_response(self, path: str, scope):
|
||||||
try:
|
try:
|
||||||
|
@ -60,6 +62,21 @@ class SPAStaticFiles(StaticFiles):
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"""
|
||||||
|
___ __ __ _ _ _ ___
|
||||||
|
/ _ \ _ __ ___ _ __ \ \ / /__| |__ | | | |_ _|
|
||||||
|
| | | | '_ \ / _ \ '_ \ \ \ /\ / / _ \ '_ \| | | || |
|
||||||
|
| |_| | |_) | __/ | | | \ V V / __/ |_) | |_| || |
|
||||||
|
\___/| .__/ \___|_| |_| \_/\_/ \___|_.__/ \___/|___|
|
||||||
|
|_|
|
||||||
|
|
||||||
|
|
||||||
|
v{VERSION} - building the best open-source AI user interface.
|
||||||
|
https://github.com/open-webui/open-webui
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
app = FastAPI(docs_url="/docs" if ENV == "dev" else None, redoc_url=None)
|
app = FastAPI(docs_url="/docs" if ENV == "dev" else None, redoc_url=None)
|
||||||
|
|
||||||
app.state.MODEL_FILTER_ENABLED = MODEL_FILTER_ENABLED
|
app.state.MODEL_FILTER_ENABLED = MODEL_FILTER_ENABLED
|
||||||
|
@ -67,7 +84,6 @@ app.state.MODEL_FILTER_LIST = MODEL_FILTER_LIST
|
||||||
|
|
||||||
app.state.WEBHOOK_URL = WEBHOOK_URL
|
app.state.WEBHOOK_URL = WEBHOOK_URL
|
||||||
|
|
||||||
|
|
||||||
origins = ["*"]
|
origins = ["*"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +104,6 @@ class RAGMiddleware(BaseHTTPMiddleware):
|
||||||
# Example: Add a new key-value pair or modify existing ones
|
# Example: Add a new key-value pair or modify existing ones
|
||||||
# data["modified"] = True # Example modification
|
# data["modified"] = True # Example modification
|
||||||
if "docs" in data:
|
if "docs" in data:
|
||||||
|
|
||||||
data = {**data}
|
data = {**data}
|
||||||
data["messages"] = rag_messages(
|
data["messages"] = rag_messages(
|
||||||
data["docs"],
|
data["docs"],
|
||||||
|
@ -163,14 +178,22 @@ app.mount("/rag/api/v1", rag_app)
|
||||||
|
|
||||||
@app.get("/api/config")
|
@app.get("/api/config")
|
||||||
async def get_app_config():
|
async def get_app_config():
|
||||||
|
# Checking and Handling the Absence of 'ui' in CONFIG_DATA
|
||||||
|
|
||||||
|
default_locale = "en-US"
|
||||||
|
if "ui" in CONFIG_DATA:
|
||||||
|
default_locale = CONFIG_DATA["ui"].get("default_locale", "en-US")
|
||||||
|
|
||||||
|
# The Rest of the Function Now Uses the Variables Defined Above
|
||||||
return {
|
return {
|
||||||
"status": True,
|
"status": True,
|
||||||
"name": WEBUI_NAME,
|
"name": WEBUI_NAME,
|
||||||
"version": VERSION,
|
"version": VERSION,
|
||||||
|
"default_locale": default_locale,
|
||||||
"images": images_app.state.ENABLED,
|
"images": images_app.state.ENABLED,
|
||||||
"default_models": webui_app.state.DEFAULT_MODELS,
|
"default_models": webui_app.state.DEFAULT_MODELS,
|
||||||
"default_prompt_suggestions": webui_app.state.DEFAULT_PROMPT_SUGGESTIONS,
|
"default_prompt_suggestions": webui_app.state.DEFAULT_PROMPT_SUGGESTIONS,
|
||||||
|
"trusted_header_auth": bool(webui_app.state.AUTH_TRUSTED_EMAIL_HEADER),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +214,6 @@ class ModelFilterConfigForm(BaseModel):
|
||||||
async def update_model_filter_config(
|
async def update_model_filter_config(
|
||||||
form_data: ModelFilterConfigForm, user=Depends(get_admin_user)
|
form_data: ModelFilterConfigForm, user=Depends(get_admin_user)
|
||||||
):
|
):
|
||||||
|
|
||||||
app.state.MODEL_FILTER_ENABLED = form_data.enabled
|
app.state.MODEL_FILTER_ENABLED = form_data.enabled
|
||||||
app.state.MODEL_FILTER_LIST = form_data.models
|
app.state.MODEL_FILTER_LIST = form_data.models
|
||||||
|
|
||||||
|
@ -201,6 +223,9 @@ async def update_model_filter_config(
|
||||||
openai_app.state.MODEL_FILTER_ENABLED = app.state.MODEL_FILTER_ENABLED
|
openai_app.state.MODEL_FILTER_ENABLED = app.state.MODEL_FILTER_ENABLED
|
||||||
openai_app.state.MODEL_FILTER_LIST = app.state.MODEL_FILTER_LIST
|
openai_app.state.MODEL_FILTER_LIST = app.state.MODEL_FILTER_LIST
|
||||||
|
|
||||||
|
litellm_app.state.MODEL_FILTER_ENABLED = app.state.MODEL_FILTER_ENABLED
|
||||||
|
litellm_app.state.MODEL_FILTER_LIST = app.state.MODEL_FILTER_LIST
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"enabled": app.state.MODEL_FILTER_ENABLED,
|
"enabled": app.state.MODEL_FILTER_ENABLED,
|
||||||
"models": app.state.MODEL_FILTER_LIST,
|
"models": app.state.MODEL_FILTER_LIST,
|
||||||
|
@ -231,7 +256,6 @@ async def update_webhook_url(form_data: UrlForm, user=Depends(get_admin_user)):
|
||||||
|
|
||||||
@app.get("/api/version")
|
@app.get("/api/version")
|
||||||
async def get_app_config():
|
async def get_app_config():
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"version": VERSION,
|
"version": VERSION,
|
||||||
}
|
}
|
||||||
|
@ -239,7 +263,7 @@ async def get_app_config():
|
||||||
|
|
||||||
@app.get("/api/changelog")
|
@app.get("/api/changelog")
|
||||||
async def get_app_changelog():
|
async def get_app_changelog():
|
||||||
return CHANGELOG
|
return {key: CHANGELOG[key] for idx, key in enumerate(CHANGELOG) if idx < 5}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/version/updates")
|
@app.get("/api/version/updates")
|
||||||
|
@ -259,6 +283,20 @@ async def get_app_latest_release_version():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/manifest.json")
|
||||||
|
async def get_manifest_json():
|
||||||
|
return {
|
||||||
|
"name": WEBUI_NAME,
|
||||||
|
"short_name": WEBUI_NAME,
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#343541",
|
||||||
|
"theme_color": "#343541",
|
||||||
|
"orientation": "portrait-primary",
|
||||||
|
"icons": [{"src": "/favicon.png", "type": "image/png", "sizes": "844x884"}],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
app.mount("/cache", StaticFiles(directory="data/cache"), name="cache")
|
app.mount("/cache", StaticFiles(directory="data/cache"), name="cache")
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,12 @@ uuid
|
||||||
requests
|
requests
|
||||||
aiohttp
|
aiohttp
|
||||||
peewee
|
peewee
|
||||||
|
peewee-migrate
|
||||||
bcrypt
|
bcrypt
|
||||||
|
|
||||||
litellm==1.30.7
|
litellm==1.30.7
|
||||||
|
boto3
|
||||||
|
|
||||||
argon2-cffi
|
argon2-cffi
|
||||||
apscheduler
|
apscheduler
|
||||||
google-generativeai
|
google-generativeai
|
||||||
|
@ -39,6 +42,8 @@ xlrd
|
||||||
opencv-python-headless
|
opencv-python-headless
|
||||||
rapidocr-onnxruntime
|
rapidocr-onnxruntime
|
||||||
|
|
||||||
|
fpdf2
|
||||||
|
|
||||||
faster-whisper
|
faster-whisper
|
||||||
|
|
||||||
PyJWT
|
PyJWT
|
||||||
|
|
BIN
backend/static/fonts/NotoSans-Bold.ttf
Normal file
BIN
backend/static/fonts/NotoSans-Bold.ttf
Normal file
Binary file not shown.
BIN
backend/static/fonts/NotoSans-Italic.ttf
Normal file
BIN
backend/static/fonts/NotoSans-Italic.ttf
Normal file
Binary file not shown.
BIN
backend/static/fonts/NotoSans-Regular.ttf
Normal file
BIN
backend/static/fonts/NotoSans-Regular.ttf
Normal file
Binary file not shown.
BIN
backend/static/fonts/NotoSansJP-Regular.ttf
Normal file
BIN
backend/static/fonts/NotoSansJP-Regular.ttf
Normal file
Binary file not shown.
BIN
backend/static/fonts/NotoSansKR-Regular.ttf
Normal file
BIN
backend/static/fonts/NotoSansKR-Regular.ttf
Normal file
Binary file not shown.
|
@ -1,6 +1,8 @@
|
||||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
from fastapi import HTTPException, status, Depends
|
from fastapi import HTTPException, status, Depends
|
||||||
|
|
||||||
from apps.web.models.users import Users
|
from apps.web.models.users import Users
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional
|
||||||
from constants import ERROR_MESSAGES
|
from constants import ERROR_MESSAGES
|
||||||
|
@ -8,6 +10,7 @@ from passlib.context import CryptContext
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import requests
|
import requests
|
||||||
import jwt
|
import jwt
|
||||||
|
import uuid
|
||||||
import logging
|
import logging
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
@ -58,6 +61,11 @@ def extract_token_from_auth_header(auth_header: str):
|
||||||
return auth_header[len("Bearer ") :]
|
return auth_header[len("Bearer ") :]
|
||||||
|
|
||||||
|
|
||||||
|
def create_api_key():
|
||||||
|
key = str(uuid.uuid4()).replace("-", "")
|
||||||
|
return f"sk-{key}"
|
||||||
|
|
||||||
|
|
||||||
def get_http_authorization_cred(auth_header: str):
|
def get_http_authorization_cred(auth_header: str):
|
||||||
try:
|
try:
|
||||||
scheme, credentials = auth_header.split(" ")
|
scheme, credentials = auth_header.split(" ")
|
||||||
|
@ -69,6 +77,10 @@ def get_http_authorization_cred(auth_header: str):
|
||||||
def get_current_user(
|
def get_current_user(
|
||||||
auth_token: HTTPAuthorizationCredentials = Depends(bearer_security),
|
auth_token: HTTPAuthorizationCredentials = Depends(bearer_security),
|
||||||
):
|
):
|
||||||
|
# auth by api key
|
||||||
|
if auth_token.credentials.startswith("sk-"):
|
||||||
|
return get_current_user_by_api_key(auth_token.credentials)
|
||||||
|
# auth by jwt token
|
||||||
data = decode_token(auth_token.credentials)
|
data = decode_token(auth_token.credentials)
|
||||||
if data != None and "id" in data:
|
if data != None and "id" in data:
|
||||||
user = Users.get_user_by_id(data["id"])
|
user = Users.get_user_by_id(data["id"])
|
||||||
|
@ -85,6 +97,16 @@ def get_current_user(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user_by_api_key(api_key: str):
|
||||||
|
user = Users.get_user_by_api_key(api_key)
|
||||||
|
if user is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.INVALID_TOKEN,
|
||||||
|
)
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
def get_verified_user(user=Depends(get_current_user)):
|
def get_verified_user(user=Depends(get_current_user)):
|
||||||
if user.role not in {"user", "admin"}:
|
if user.role not in {"user", "admin"}:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
@ -1,20 +1,54 @@
|
||||||
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from config import SRC_LOG_LEVELS, VERSION, WEBUI_FAVICON_URL, WEBUI_NAME
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
log.setLevel(SRC_LOG_LEVELS["WEBHOOK"])
|
||||||
|
|
||||||
|
|
||||||
def post_webhook(url: str, message: str, event_data: dict) -> bool:
|
def post_webhook(url: str, message: str, event_data: dict) -> bool:
|
||||||
try:
|
try:
|
||||||
payload = {}
|
payload = {}
|
||||||
|
|
||||||
if "https://hooks.slack.com" in url:
|
# Slack and Google Chat Webhooks
|
||||||
|
if "https://hooks.slack.com" in url or "https://chat.googleapis.com" in url:
|
||||||
payload["text"] = message
|
payload["text"] = message
|
||||||
|
# Discord Webhooks
|
||||||
elif "https://discord.com/api/webhooks" in url:
|
elif "https://discord.com/api/webhooks" in url:
|
||||||
payload["content"] = message
|
payload["content"] = message
|
||||||
|
# Microsoft Teams Webhooks
|
||||||
|
elif "webhook.office.com" in url:
|
||||||
|
action = event_data.get("action", "undefined")
|
||||||
|
facts = [
|
||||||
|
{"name": name, "value": value}
|
||||||
|
for name, value in json.loads(event_data.get("user", {})).items()
|
||||||
|
]
|
||||||
|
payload = {
|
||||||
|
"@type": "MessageCard",
|
||||||
|
"@context": "http://schema.org/extensions",
|
||||||
|
"themeColor": "0076D7",
|
||||||
|
"summary": message,
|
||||||
|
"sections": [
|
||||||
|
{
|
||||||
|
"activityTitle": message,
|
||||||
|
"activitySubtitle": f"{WEBUI_NAME} ({VERSION}) - {action}",
|
||||||
|
"activityImage": WEBUI_FAVICON_URL,
|
||||||
|
"facts": facts,
|
||||||
|
"markdown": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
# Default Payload
|
||||||
else:
|
else:
|
||||||
payload = {**event_data}
|
payload = {**event_data}
|
||||||
|
|
||||||
|
log.debug(f"payload: {payload}")
|
||||||
r = requests.post(url, json=payload)
|
r = requests.post(url, json=payload)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
log.debug(f"r.text: {r.text}")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
log.exception(e)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -7,7 +7,7 @@ ollama
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- define "ollama.url" -}}
|
{{- define "ollama.url" -}}
|
||||||
{{- printf "http://%s.%s.svc.cluster.local:%d/api" (include "ollama.name" .) (.Release.Namespace) (.Values.ollama.service.port | int) }}
|
{{- printf "http://%s.%s.svc.cluster.local:%d/" (include "ollama.name" .) (.Release.Namespace) (.Values.ollama.service.port | int) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- define "chart.name" -}}
|
{{- define "chart.name" -}}
|
||||||
|
|
|
@ -88,7 +88,7 @@ spec:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: {{ .Values.ollama.persistence.size | quote }}
|
storage: {{ .Values.ollama.persistence.size | quote }}
|
||||||
storageClass: {{ .Values.ollama.persistence.storageClass }}
|
storageClassName: {{ .Values.ollama.persistence.storageClass }}
|
||||||
{{- with .Values.ollama.persistence.selector }}
|
{{- with .Values.ollama.persistence.selector }}
|
||||||
selector:
|
selector:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|
|
@ -17,7 +17,7 @@ spec:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: {{ .Values.webui.persistence.size }}
|
storage: {{ .Values.webui.persistence.size }}
|
||||||
storageClass: {{ .Values.webui.persistence.storageClass }}
|
storageClassName: {{ .Values.webui.persistence.storageClass }}
|
||||||
{{- with .Values.webui.persistence.selector }}
|
{{- with .Values.webui.persistence.selector }}
|
||||||
selector:
|
selector:
|
||||||
{{- toYaml . | nindent 4 }}
|
{{- toYaml . | nindent 4 }}
|
||||||
|
|
|
@ -35,4 +35,4 @@ spec:
|
||||||
volumes:
|
volumes:
|
||||||
- name: webui-volume
|
- name: webui-volume
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: ollama-webui-pvc
|
claimName: open-webui-pvc
|
|
@ -2,8 +2,8 @@ apiVersion: v1
|
||||||
kind: PersistentVolumeClaim
|
kind: PersistentVolumeClaim
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: ollama-webui
|
app: open-webui
|
||||||
name: ollama-webui-pvc
|
name: open-webui-pvc
|
||||||
namespace: open-webui
|
namespace: open-webui
|
||||||
spec:
|
spec:
|
||||||
accessModes: ["ReadWriteOnce"]
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
|
200
package-lock.json
generated
200
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "open-webui",
|
"name": "open-webui",
|
||||||
"version": "0.1.114",
|
"version": "0.1.117",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "open-webui",
|
"name": "open-webui",
|
||||||
"version": "0.1.114",
|
"version": "0.1.117",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sveltejs/adapter-node": "^1.3.1",
|
"@sveltejs/adapter-node": "^1.3.1",
|
||||||
"async": "^3.2.5",
|
"async": "^3.2.5",
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
"i18next-resources-to-backend": "^1.2.0",
|
"i18next-resources-to-backend": "^1.2.0",
|
||||||
"idb": "^7.1.1",
|
"idb": "^7.1.1",
|
||||||
"js-sha256": "^0.10.1",
|
"js-sha256": "^0.10.1",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
"katex": "^0.16.9",
|
"katex": "^0.16.9",
|
||||||
"marked": "^9.1.0",
|
"marked": "^9.1.0",
|
||||||
"svelte-sonner": "^0.3.19",
|
"svelte-sonner": "^0.3.19",
|
||||||
|
@ -1067,6 +1068,12 @@
|
||||||
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
|
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/raf": {
|
||||||
|
"version": "3.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
|
||||||
|
"integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||||
|
@ -1402,6 +1409,17 @@
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
|
||||||
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
|
"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/atob": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||||
|
"bin": {
|
||||||
|
"atob": "bin/atob.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.19",
|
"version": "10.4.19",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
|
||||||
|
@ -1459,6 +1477,15 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-arraybuffer": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
@ -1666,6 +1693,17 @@
|
||||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/btoa": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
|
||||||
|
"bin": {
|
||||||
|
"btoa": "bin/btoa.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer": {
|
"node_modules/buffer": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
@ -1758,6 +1796,31 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/canvg": {
|
||||||
|
"version": "3.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
|
||||||
|
"integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@types/raf": "^3.4.0",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"raf": "^3.4.1",
|
||||||
|
"regenerator-runtime": "^0.13.7",
|
||||||
|
"rgbcolor": "^1.0.1",
|
||||||
|
"stackblur-canvas": "^2.0.0",
|
||||||
|
"svg-pathdata": "^6.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/canvg/node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.13.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||||
|
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
@ -1944,6 +2007,17 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/core-js": {
|
||||||
|
"version": "3.36.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz",
|
||||||
|
"integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/core-js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/core-util-is": {
|
"node_modules/core-util-is": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||||
|
@ -1964,6 +2038,15 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/css-line-break": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/css-select": {
|
"node_modules/css-select": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||||
|
@ -2156,6 +2239,12 @@
|
||||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dompurify": {
|
||||||
|
"version": "2.4.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.9.tgz",
|
||||||
|
"integrity": "sha512-iHtnxYMotKgOTvxIqq677JsKHvCOkAFqj9x8Mek2zdeHW1XjuFKwjpmZeMaXQRQ8AbJZDbcRz/+r1QhwvFtmQg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/domutils": {
|
"node_modules/domutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
|
||||||
|
@ -2584,6 +2673,11 @@
|
||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fflate": {
|
||||||
|
"version": "0.4.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
|
||||||
|
"integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
|
@ -3003,6 +3097,19 @@
|
||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html2canvas": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"css-line-break": "^2.1.0",
|
||||||
|
"text-segmentation": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
|
@ -3403,10 +3510,27 @@
|
||||||
"graceful-fs": "^4.1.6"
|
"graceful-fs": "^4.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jspdf": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.14.0",
|
||||||
|
"atob": "^2.1.2",
|
||||||
|
"btoa": "^1.2.1",
|
||||||
|
"fflate": "^0.4.8"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"canvg": "^3.0.6",
|
||||||
|
"core-js": "^3.6.0",
|
||||||
|
"dompurify": "^2.2.0",
|
||||||
|
"html2canvas": "^1.0.0-rc.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/katex": {
|
"node_modules/katex": {
|
||||||
"version": "0.16.9",
|
"version": "0.16.10",
|
||||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz",
|
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz",
|
||||||
"integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==",
|
"integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://opencollective.com/katex",
|
"https://opencollective.com/katex",
|
||||||
"https://github.com/sponsors/katex"
|
"https://github.com/sponsors/katex"
|
||||||
|
@ -3971,6 +4095,12 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/performance-now": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/periscopic": {
|
"node_modules/periscopic": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
|
||||||
|
@ -4391,6 +4521,15 @@
|
||||||
"rimraf": "bin.js"
|
"rimraf": "bin.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/raf": {
|
||||||
|
"version": "3.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
|
||||||
|
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"performance-now": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
@ -4494,6 +4633,15 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rgbcolor": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rimraf": {
|
"node_modules/rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
@ -4814,6 +4962,15 @@
|
||||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/stackblur-canvas": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.1.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/stream-composer": {
|
"node_modules/stream-composer": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
|
||||||
|
@ -5215,6 +5372,15 @@
|
||||||
"@types/estree": "*"
|
"@types/estree": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svg-pathdata": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/symlink-or-copy": {
|
"node_modules/symlink-or-copy": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz",
|
||||||
|
@ -5353,6 +5519,15 @@
|
||||||
"streamx": "^2.12.5"
|
"streamx": "^2.12.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/text-segmentation": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -5583,6 +5758,15 @@
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/utrie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"base64-arraybuffer": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "9.0.1",
|
"version": "9.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
@ -5676,9 +5860,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "4.5.2",
|
"version": "4.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
|
||||||
"integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
|
"integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.18.10",
|
"esbuild": "^0.18.10",
|
||||||
"postcss": "^8.4.27",
|
"postcss": "^8.4.27",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "open-webui",
|
"name": "open-webui",
|
||||||
"version": "0.1.115",
|
"version": "0.1.117",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev --host",
|
"dev": "vite dev --host",
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
"lint:types": "npm run check",
|
"lint:types": "npm run check",
|
||||||
"lint:backend": "pylint backend/",
|
"lint:backend": "pylint backend/",
|
||||||
"format": "prettier --plugin-search-dir --write '**/*.{js,ts,svelte,css,md,html,json}'",
|
"format": "prettier --plugin-search-dir --write '**/*.{js,ts,svelte,css,md,html,json}'",
|
||||||
"format:backend": "yapf --recursive backend -p -i",
|
"format:backend": "black . --exclude \"/venv/\"",
|
||||||
"i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write 'src/lib/i18n/**/*.{js,json}'"
|
"i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write 'src/lib/i18n/**/*.{js,json}'"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -53,10 +53,11 @@
|
||||||
"i18next-resources-to-backend": "^1.2.0",
|
"i18next-resources-to-backend": "^1.2.0",
|
||||||
"idb": "^7.1.1",
|
"idb": "^7.1.1",
|
||||||
"js-sha256": "^0.10.1",
|
"js-sha256": "^0.10.1",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
"katex": "^0.16.9",
|
"katex": "^0.16.9",
|
||||||
"marked": "^9.1.0",
|
"marked": "^9.1.0",
|
||||||
"svelte-sonner": "^0.3.19",
|
"svelte-sonner": "^0.3.19",
|
||||||
"tippy.js": "^6.3.7",
|
"tippy.js": "^6.3.7",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,3 +78,7 @@ select {
|
||||||
/* for Chrome */
|
/* for Chrome */
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.katex-mathml {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
<script>
|
<script>
|
||||||
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
|
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
|
||||||
(() => {
|
(() => {
|
||||||
if (
|
if (localStorage?.theme && localStorage?.theme.includes('oled')) {
|
||||||
|
document.documentElement.style.setProperty('--color-gray-900', '#000000');
|
||||||
|
document.documentElement.style.setProperty('--color-gray-950', '#000000');
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
} else if (
|
||||||
localStorage.theme === 'light' ||
|
localStorage.theme === 'light' ||
|
||||||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: light)').matches)
|
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: light)').matches)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -318,3 +318,78 @@ export const updateJWTExpiresDuration = async (token: string, duration: string)
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createAPIKey = async (token: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err.detail;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return res.api_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAPIKey = async (token: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err.detail;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return res.api_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteAPIKey = async (token: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err.detail;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
|
@ -218,6 +218,102 @@ export const getChatById = async (token: string, id: string) => {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getChatByShareId = async (token: string, share_id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/share/${share_id}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...(token && { authorization: `Bearer ${token}` })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const shareChatById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/share`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...(token && { authorization: `Bearer ${token}` })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteSharedChatById = async (token: string, id: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/share`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...(token && { authorization: `Bearer ${token}` })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const updateChatById = async (token: string, id: string, chat: object) => {
|
export const updateChatById = async (token: string, id: string, chat: object) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const getLiteLLMModels = async (token: string = '') => {
|
||||||
id: model.id,
|
id: model.id,
|
||||||
name: model.name ?? model.id,
|
name: model.name ?? model.id,
|
||||||
external: true,
|
external: true,
|
||||||
source: 'litellm'
|
source: 'LiteLLM'
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
|
|
|
@ -263,3 +263,53 @@ export const synthesizeOpenAISpeech = async (
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const generateTitle = async (
|
||||||
|
token: string = '',
|
||||||
|
template: string,
|
||||||
|
model: string,
|
||||||
|
prompt: string,
|
||||||
|
url: string = OPENAI_API_BASE_URL
|
||||||
|
) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
template = template.replace(/{{prompt}}/g, prompt);
|
||||||
|
|
||||||
|
console.log(template);
|
||||||
|
|
||||||
|
const res = await fetch(`${url}/chat/completions`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: model,
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: 'user',
|
||||||
|
content: template
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stream: false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
if ('detail' in err) {
|
||||||
|
error = err.detail;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res?.choices[0]?.message?.content ?? 'New Chat';
|
||||||
|
};
|
||||||
|
|
|
@ -22,6 +22,57 @@ export const getGravatarUrl = async (email: string) => {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const downloadChatAsPDF = async (chat: object) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const blob = await fetch(`${WEBUI_API_BASE_URL}/utils/pdf`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
title: chat.title,
|
||||||
|
messages: chat.messages
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.blob();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getHTMLFromMarkdown = async (md: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/utils/markdown`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
md: md
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
error = err;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.html;
|
||||||
|
};
|
||||||
|
|
||||||
export const downloadDatabase = async (token: string) => {
|
export const downloadDatabase = async (token: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
export let chatId = '';
|
export let chatId = '';
|
||||||
|
export let readOnly = false;
|
||||||
export let sendPrompt: Function;
|
export let sendPrompt: Function;
|
||||||
export let continueGeneration: Function;
|
export let continueGeneration: Function;
|
||||||
export let regenerateResponse: Function;
|
export let regenerateResponse: Function;
|
||||||
|
@ -317,6 +318,7 @@
|
||||||
<UserMessage
|
<UserMessage
|
||||||
on:delete={() => messageDeleteHandler(message.id)}
|
on:delete={() => messageDeleteHandler(message.id)}
|
||||||
user={$user}
|
user={$user}
|
||||||
|
{readOnly}
|
||||||
{message}
|
{message}
|
||||||
isFirstMessage={messageIdx === 0}
|
isFirstMessage={messageIdx === 0}
|
||||||
siblings={message.parentId !== null
|
siblings={message.parentId !== null
|
||||||
|
@ -335,6 +337,7 @@
|
||||||
modelfiles={selectedModelfiles}
|
modelfiles={selectedModelfiles}
|
||||||
siblings={history.messages[message.parentId]?.childrenIds ?? []}
|
siblings={history.messages[message.parentId]?.childrenIds ?? []}
|
||||||
isLastMessage={messageIdx + 1 === messages.length}
|
isLastMessage={messageIdx + 1 === messages.length}
|
||||||
|
{readOnly}
|
||||||
{confirmEditResponseMessage}
|
{confirmEditResponseMessage}
|
||||||
{showPreviousMessage}
|
{showPreviousMessage}
|
||||||
{showNextMessage}
|
{showNextMessage}
|
||||||
|
|
|
@ -17,7 +17,11 @@
|
||||||
import { config, settings } from '$lib/stores';
|
import { config, settings } from '$lib/stores';
|
||||||
import { synthesizeOpenAISpeech } from '$lib/apis/openai';
|
import { synthesizeOpenAISpeech } from '$lib/apis/openai';
|
||||||
import { imageGenerations } from '$lib/apis/images';
|
import { imageGenerations } from '$lib/apis/images';
|
||||||
import { extractSentences } from '$lib/utils';
|
import {
|
||||||
|
extractSentences,
|
||||||
|
revertSanitizedResponseContent,
|
||||||
|
sanitizeResponseContent
|
||||||
|
} from '$lib/utils';
|
||||||
|
|
||||||
import Name from './Name.svelte';
|
import Name from './Name.svelte';
|
||||||
import ProfileImage from './ProfileImage.svelte';
|
import ProfileImage from './ProfileImage.svelte';
|
||||||
|
@ -33,6 +37,8 @@
|
||||||
|
|
||||||
export let isLastMessage = true;
|
export let isLastMessage = true;
|
||||||
|
|
||||||
|
export let readOnly = false;
|
||||||
|
|
||||||
export let confirmEditResponseMessage: Function;
|
export let confirmEditResponseMessage: Function;
|
||||||
export let showPreviousMessage: Function;
|
export let showPreviousMessage: Function;
|
||||||
export let showNextMessage: Function;
|
export let showNextMessage: Function;
|
||||||
|
@ -54,7 +60,7 @@
|
||||||
let loadingSpeech = false;
|
let loadingSpeech = false;
|
||||||
let generatingImage = false;
|
let generatingImage = false;
|
||||||
|
|
||||||
$: tokens = marked.lexer(message.content);
|
$: tokens = marked.lexer(sanitizeResponseContent(message.content));
|
||||||
|
|
||||||
const renderer = new marked.Renderer();
|
const renderer = new marked.Renderer();
|
||||||
|
|
||||||
|
@ -128,7 +134,7 @@
|
||||||
// • auto-render specific keys, e.g.:
|
// • auto-render specific keys, e.g.:
|
||||||
delimiters: [
|
delimiters: [
|
||||||
{ left: '$$', right: '$$', display: false },
|
{ left: '$$', right: '$$', display: false },
|
||||||
{ left: '$', right: '$', display: false },
|
{ left: '$ ', right: ' $', display: false },
|
||||||
{ left: '\\(', right: '\\)', display: false },
|
{ left: '\\(', right: '\\)', display: false },
|
||||||
{ left: '\\[', right: '\\]', display: false },
|
{ left: '\\[', right: '\\]', display: false },
|
||||||
{ left: '[ ', right: ' ]', display: false }
|
{ left: '[ ', right: ' ]', display: false }
|
||||||
|
@ -403,8 +409,10 @@
|
||||||
{:else}
|
{:else}
|
||||||
{#each tokens as token}
|
{#each tokens as token}
|
||||||
{#if token.type === 'code'}
|
{#if token.type === 'code'}
|
||||||
<!-- {token.text} -->
|
<CodeBlock
|
||||||
<CodeBlock lang={token.lang} code={token.text} />
|
lang={token.lang}
|
||||||
|
code={revertSanitizedResponseContent(token.text)}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
{@html marked.parse(token.raw, {
|
{@html marked.parse(token.raw, {
|
||||||
...defaults,
|
...defaults,
|
||||||
|
@ -422,7 +430,7 @@
|
||||||
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
|
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
|
||||||
>
|
>
|
||||||
{#if siblings.length > 1}
|
{#if siblings.length > 1}
|
||||||
<div class="flex self-center min-w-fit -mt-1">
|
<div class="flex self-center min-w-fit">
|
||||||
<button
|
<button
|
||||||
class="self-center dark:hover:text-white hover:text-black transition"
|
class="self-center dark:hover:text-white hover:text-black transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
@ -469,31 +477,33 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Tooltip content="Edit" placement="bottom">
|
{#if !readOnly}
|
||||||
<button
|
<Tooltip content="Edit" placement="bottom">
|
||||||
class="{isLastMessage
|
<button
|
||||||
? 'visible'
|
class="{isLastMessage
|
||||||
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
|
? 'visible'
|
||||||
on:click={() => {
|
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
|
||||||
editMessageHandler();
|
on:click={() => {
|
||||||
}}
|
editMessageHandler();
|
||||||
>
|
}}
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
stroke-linecap="round"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke-linejoin="round"
|
fill="none"
|
||||||
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
|
viewBox="0 0 24 24"
|
||||||
/>
|
stroke-width="2"
|
||||||
</svg>
|
stroke="currentColor"
|
||||||
</button>
|
class="w-4 h-4"
|
||||||
</Tooltip>
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<Tooltip content="Copy" placement="bottom">
|
<Tooltip content="Copy" placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
@ -521,59 +531,61 @@
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip content="Good Response" placement="bottom">
|
{#if !readOnly}
|
||||||
<button
|
<Tooltip content="Good Response" placement="bottom">
|
||||||
class="{isLastMessage
|
<button
|
||||||
? 'visible'
|
class="{isLastMessage
|
||||||
: 'invisible group-hover:visible'} p-1 rounded {message.rating === 1
|
? 'visible'
|
||||||
? 'bg-gray-100 dark:bg-gray-800'
|
: 'invisible group-hover:visible'} p-1 rounded {message.rating === 1
|
||||||
: ''} dark:hover:text-white hover:text-black transition"
|
? 'bg-gray-100 dark:bg-gray-800'
|
||||||
on:click={() => {
|
: ''} dark:hover:text-white hover:text-black transition"
|
||||||
rateMessage(message.id, 1);
|
on:click={() => {
|
||||||
}}
|
rateMessage(message.id, 1);
|
||||||
>
|
}}
|
||||||
<svg
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-4 h-4"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
><path
|
|
||||||
d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"
|
|
||||||
/></svg
|
|
||||||
>
|
>
|
||||||
</button>
|
<svg
|
||||||
</Tooltip>
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="w-4 h-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><path
|
||||||
|
d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip content="Bad Response" placement="bottom">
|
<Tooltip content="Bad Response" placement="bottom">
|
||||||
<button
|
<button
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1 rounded {message.rating === -1
|
: 'invisible group-hover:visible'} p-1 rounded {message.rating === -1
|
||||||
? 'bg-gray-100 dark:bg-gray-800'
|
? 'bg-gray-100 dark:bg-gray-800'
|
||||||
: ''} dark:hover:text-white hover:text-black transition"
|
: ''} dark:hover:text-white hover:text-black transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
rateMessage(message.id, -1);
|
rateMessage(message.id, -1);
|
||||||
}}
|
}}
|
||||||
>
|
|
||||||
<svg
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-width="2"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="w-4 h-4"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
><path
|
|
||||||
d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"
|
|
||||||
/></svg
|
|
||||||
>
|
>
|
||||||
</button>
|
<svg
|
||||||
</Tooltip>
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="w-4 h-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><path
|
||||||
|
d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<Tooltip content="Read Aloud" placement="bottom">
|
<Tooltip content="Read Aloud" placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
@ -656,7 +668,7 @@
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{#if $config.images}
|
{#if $config.images && !readOnly}
|
||||||
<Tooltip content="Generate Image" placement="bottom">
|
<Tooltip content="Generate Image" placement="bottom">
|
||||||
<button
|
<button
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
|
@ -752,7 +764,7 @@
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if isLastMessage}
|
{#if isLastMessage && !readOnly}
|
||||||
<Tooltip content="Continue Response" placement="bottom">
|
<Tooltip content="Continue Response" placement="bottom">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
export let message;
|
export let message;
|
||||||
export let siblings;
|
export let siblings;
|
||||||
export let isFirstMessage: boolean;
|
export let isFirstMessage: boolean;
|
||||||
|
export let readOnly: boolean;
|
||||||
|
|
||||||
export let confirmEditMessage: Function;
|
export let confirmEditMessage: Function;
|
||||||
export let showPreviousMessage: Function;
|
export let showPreviousMessage: Function;
|
||||||
|
@ -203,7 +204,7 @@
|
||||||
|
|
||||||
<div class=" flex justify-start space-x-1 text-gray-700 dark:text-gray-500">
|
<div class=" flex justify-start space-x-1 text-gray-700 dark:text-gray-500">
|
||||||
{#if siblings.length > 1}
|
{#if siblings.length > 1}
|
||||||
<div class="flex self-center -mt-1">
|
<div class="flex self-center">
|
||||||
<button
|
<button
|
||||||
class="self-center dark:hover:text-white hover:text-black transition"
|
class="self-center dark:hover:text-white hover:text-black transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
@ -250,29 +251,31 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Tooltip content="Edit" placement="bottom">
|
{#if !readOnly}
|
||||||
<button
|
<Tooltip content="Edit" placement="bottom">
|
||||||
class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition edit-user-message-button"
|
<button
|
||||||
on:click={() => {
|
class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition edit-user-message-button"
|
||||||
editMessageHandler();
|
on:click={() => {
|
||||||
}}
|
editMessageHandler();
|
||||||
>
|
}}
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
stroke-linecap="round"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke-linejoin="round"
|
fill="none"
|
||||||
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
|
viewBox="0 0 24 24"
|
||||||
/>
|
stroke-width="2"
|
||||||
</svg>
|
stroke="currentColor"
|
||||||
</button>
|
class="w-4 h-4"
|
||||||
</Tooltip>
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<Tooltip content="Copy" placement="bottom">
|
<Tooltip content="Copy" placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
@ -298,7 +301,7 @@
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
{#if !isFirstMessage}
|
{#if !isFirstMessage && !readOnly}
|
||||||
<Tooltip content="Delete" placement="bottom">
|
<Tooltip content="Delete" placement="bottom">
|
||||||
<button
|
<button
|
||||||
class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition"
|
class="invisible group-hover:visible p-1 rounded dark:hover:text-white hover:text-black transition"
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { Collapsible } from 'bits-ui';
|
||||||
|
|
||||||
import { setDefaultModels } from '$lib/apis/configs';
|
import { setDefaultModels } from '$lib/apis/configs';
|
||||||
import { models, showSettings, settings, user } from '$lib/stores';
|
import { models, showSettings, settings, user } from '$lib/stores';
|
||||||
import { onMount, tick, getContext } from 'svelte';
|
import { onMount, tick, getContext } from 'svelte';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import Select from '../common/Select.svelte';
|
import Selector from './ModelSelector/Selector.svelte';
|
||||||
|
import Tooltip from '../common/Tooltip.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
@ -33,19 +36,19 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col my-2 w-full">
|
<div class="flex flex-col mt-0.5 w-full">
|
||||||
{#each selectedModels as selectedModel, selectedModelIdx}
|
{#each selectedModels as selectedModel, selectedModelIdx}
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<div class="overflow-hidden w-full">
|
<div class="overflow-hidden w-full">
|
||||||
<div class="mr-2 max-w-full">
|
<div class="mr-0.5 max-w-full">
|
||||||
<Select
|
<Selector
|
||||||
placeholder={$i18n.t('Select a model')}
|
placeholder={$i18n.t('Select a model')}
|
||||||
items={$models
|
items={$models
|
||||||
.filter((model) => model.name !== 'hr')
|
.filter((model) => model.name !== 'hr')
|
||||||
.map((model) => ({
|
.map((model) => ({
|
||||||
value: model.id,
|
value: model.id,
|
||||||
label:
|
label: model.name,
|
||||||
model.name + `${model.size ? ` (${(model.size / 1024 ** 3).toFixed(1)}GB)` : ''}`
|
info: model
|
||||||
}))}
|
}))}
|
||||||
bind:value={selectedModel}
|
bind:value={selectedModel}
|
||||||
/>
|
/>
|
||||||
|
@ -53,84 +56,56 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if selectedModelIdx === 0}
|
{#if selectedModelIdx === 0}
|
||||||
<button
|
<div class=" self-center mr-2 disabled:text-gray-600 disabled:hover:text-gray-600">
|
||||||
class=" self-center {selectedModelIdx === 0
|
<Tooltip content="Add Model">
|
||||||
? 'mr-3'
|
<button
|
||||||
: 'mr-7'} disabled:text-gray-600 disabled:hover:text-gray-600"
|
class=" "
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
selectedModels = [...selectedModels, ''];
|
selectedModels = [...selectedModels, ''];
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m6-6H6" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m6-6H6" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<div class=" self-center disabled:text-gray-600 disabled:hover:text-gray-600 mr-2">
|
||||||
class=" self-center disabled:text-gray-600 disabled:hover:text-gray-600 {selectedModelIdx ===
|
<Tooltip content="Remove Model">
|
||||||
0
|
<button
|
||||||
? 'mr-3'
|
{disabled}
|
||||||
: 'mr-7'}"
|
on:click={() => {
|
||||||
{disabled}
|
selectedModels.splice(selectedModelIdx, 1);
|
||||||
on:click={() => {
|
selectedModels = selectedModels;
|
||||||
selectedModels.splice(selectedModelIdx, 1);
|
}}
|
||||||
selectedModels = selectedModels;
|
>
|
||||||
}}
|
<svg
|
||||||
>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<svg
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
stroke-width="1.5"
|
||||||
viewBox="0 0 24 24"
|
stroke="currentColor"
|
||||||
stroke-width="1.5"
|
class="w-4 h-4"
|
||||||
stroke="currentColor"
|
>
|
||||||
class="w-4 h-4"
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
|
||||||
>
|
</svg>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
|
</button>
|
||||||
</svg>
|
</Tooltip>
|
||||||
</button>
|
</div>
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if selectedModelIdx === 0}
|
|
||||||
<button
|
|
||||||
class=" self-center dark:hover:text-gray-300"
|
|
||||||
id="open-settings-button"
|
|
||||||
on:click={async () => {
|
|
||||||
await showSettings.set(!$showSettings);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 011.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.56.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.893.149c-.425.07-.765.383-.93.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 01-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.397.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 01-.12-1.45l.527-.737c.25-.35.273-.806.108-1.204-.165-.397-.505-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.107-1.204l-.527-.738a1.125 1.125 0 01.12-1.45l.773-.773a1.125 1.125 0 011.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-left mt-1.5 ml-1 text-xs text-gray-500">
|
<div class="text-left mt-0.5 ml-1 text-[0.7rem] text-gray-500">
|
||||||
<button on:click={saveDefaultModel}> {$i18n.t('Set as default')}</button>
|
<button on:click={saveDefaultModel}> {$i18n.t('Set as default')}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
389
src/lib/components/chat/ModelSelector/Selector.svelte
Normal file
389
src/lib/components/chat/ModelSelector/Selector.svelte
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Select } from 'bits-ui';
|
||||||
|
|
||||||
|
import { flyAndScale } from '$lib/utils/transitions';
|
||||||
|
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
|
||||||
|
|
||||||
|
import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
|
||||||
|
import Check from '$lib/components/icons/Check.svelte';
|
||||||
|
import Search from '$lib/components/icons/Search.svelte';
|
||||||
|
|
||||||
|
import { cancelOllamaRequest, deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama';
|
||||||
|
|
||||||
|
import { user, MODEL_DOWNLOAD_POOL, models } from '$lib/stores';
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
|
import { capitalizeFirstLetter, getModels, splitStream } from '$lib/utils';
|
||||||
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
|
||||||
|
const i18n = getContext('i18n');
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let value = '';
|
||||||
|
export let placeholder = 'Select a model';
|
||||||
|
export let searchEnabled = true;
|
||||||
|
export let searchPlaceholder = 'Search a model';
|
||||||
|
|
||||||
|
export let items = [{ value: 'mango', label: 'Mango' }];
|
||||||
|
|
||||||
|
let searchValue = '';
|
||||||
|
let ollamaVersion = null;
|
||||||
|
|
||||||
|
$: filteredItems = searchValue
|
||||||
|
? items.filter((item) => item.value.includes(searchValue.toLowerCase()))
|
||||||
|
: items;
|
||||||
|
|
||||||
|
const pullModelHandler = async () => {
|
||||||
|
const sanitizedModelTag = searchValue.trim();
|
||||||
|
|
||||||
|
console.log($MODEL_DOWNLOAD_POOL);
|
||||||
|
if ($MODEL_DOWNLOAD_POOL[sanitizedModelTag]) {
|
||||||
|
toast.error(
|
||||||
|
$i18n.t(`Model '{{modelTag}}' is already in queue for downloading.`, {
|
||||||
|
modelTag: sanitizedModelTag
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Object.keys($MODEL_DOWNLOAD_POOL).length === 3) {
|
||||||
|
toast.error(
|
||||||
|
$i18n.t('Maximum of 3 models can be downloaded simultaneously. Please try again later.')
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await pullModel(localStorage.token, sanitizedModelTag, '0').catch((error) => {
|
||||||
|
toast.error(error);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
const reader = res.body
|
||||||
|
.pipeThrough(new TextDecoderStream())
|
||||||
|
.pipeThrough(splitStream('\n'))
|
||||||
|
.getReader();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
const { value, done } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
|
||||||
|
let lines = value.split('\n');
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line !== '') {
|
||||||
|
let data = JSON.parse(line);
|
||||||
|
console.log(data);
|
||||||
|
if (data.error) {
|
||||||
|
throw data.error;
|
||||||
|
}
|
||||||
|
if (data.detail) {
|
||||||
|
throw data.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.id) {
|
||||||
|
MODEL_DOWNLOAD_POOL.set({
|
||||||
|
...$MODEL_DOWNLOAD_POOL,
|
||||||
|
[sanitizedModelTag]: {
|
||||||
|
...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
|
||||||
|
requestId: data.id,
|
||||||
|
reader,
|
||||||
|
done: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.status) {
|
||||||
|
if (data.digest) {
|
||||||
|
let downloadProgress = 0;
|
||||||
|
if (data.completed) {
|
||||||
|
downloadProgress = Math.round((data.completed / data.total) * 1000) / 10;
|
||||||
|
} else {
|
||||||
|
downloadProgress = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
MODEL_DOWNLOAD_POOL.set({
|
||||||
|
...$MODEL_DOWNLOAD_POOL,
|
||||||
|
[sanitizedModelTag]: {
|
||||||
|
...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
|
||||||
|
pullProgress: downloadProgress,
|
||||||
|
digest: data.digest
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toast.success(data.status);
|
||||||
|
|
||||||
|
MODEL_DOWNLOAD_POOL.set({
|
||||||
|
...$MODEL_DOWNLOAD_POOL,
|
||||||
|
[sanitizedModelTag]: {
|
||||||
|
...$MODEL_DOWNLOAD_POOL[sanitizedModelTag],
|
||||||
|
done: data.status === 'success'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
if (typeof error !== 'string') {
|
||||||
|
error = error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.error(error);
|
||||||
|
// opts.callback({ success: false, error, modelName: opts.modelName });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($MODEL_DOWNLOAD_POOL[sanitizedModelTag].done) {
|
||||||
|
toast.success(
|
||||||
|
$i18n.t(`Model '{{modelName}}' has been successfully downloaded.`, {
|
||||||
|
modelName: sanitizedModelTag
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
models.set(await getModels(localStorage.token));
|
||||||
|
} else {
|
||||||
|
toast.error('Download canceled');
|
||||||
|
}
|
||||||
|
|
||||||
|
delete $MODEL_DOWNLOAD_POOL[sanitizedModelTag];
|
||||||
|
|
||||||
|
MODEL_DOWNLOAD_POOL.set({
|
||||||
|
...$MODEL_DOWNLOAD_POOL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
|
||||||
|
});
|
||||||
|
|
||||||
|
const cancelModelPullHandler = async (model: string) => {
|
||||||
|
const { reader, requestId } = $MODEL_DOWNLOAD_POOL[model];
|
||||||
|
if (reader) {
|
||||||
|
await reader.cancel();
|
||||||
|
|
||||||
|
await cancelOllamaRequest(localStorage.token, requestId);
|
||||||
|
delete $MODEL_DOWNLOAD_POOL[model];
|
||||||
|
MODEL_DOWNLOAD_POOL.set({
|
||||||
|
...$MODEL_DOWNLOAD_POOL
|
||||||
|
});
|
||||||
|
await deleteModel(localStorage.token, model);
|
||||||
|
toast.success(`${model} download has been canceled`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Select.Root
|
||||||
|
{items}
|
||||||
|
onOpenChange={async () => {
|
||||||
|
searchValue = '';
|
||||||
|
window.setTimeout(() => document.getElementById('model-search-input')?.focus(), 0);
|
||||||
|
}}
|
||||||
|
selected={items.find((item) => item.value === value) ?? ''}
|
||||||
|
onSelectedChange={(selectedItem) => {
|
||||||
|
value = selectedItem.value;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select.Trigger class="relative w-full" aria-label={placeholder}>
|
||||||
|
<Select.Value
|
||||||
|
class="flex text-left px-0.5 outline-none bg-transparent truncate text-lg font-semibold placeholder-gray-400 focus:outline-none"
|
||||||
|
{placeholder}
|
||||||
|
/>
|
||||||
|
<ChevronDown className="absolute end-2 top-1/2 -translate-y-[45%] size-3.5" strokeWidth="2.5" />
|
||||||
|
</Select.Trigger>
|
||||||
|
<Select.Content
|
||||||
|
class=" z-40 w-full rounded-lg bg-white dark:bg-gray-900 dark:text-white shadow-lg border border-gray-300/30 dark:border-gray-700/50 outline-none"
|
||||||
|
transition={flyAndScale}
|
||||||
|
sideOffset={4}
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
{#if searchEnabled}
|
||||||
|
<div class="flex items-center gap-2.5 px-5 mt-3.5 mb-3">
|
||||||
|
<Search className="size-4" strokeWidth="2.5" />
|
||||||
|
|
||||||
|
<input
|
||||||
|
id="model-search-input"
|
||||||
|
bind:value={searchValue}
|
||||||
|
class="w-full text-sm bg-transparent outline-none"
|
||||||
|
placeholder={searchPlaceholder}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="border-gray-100 dark:border-gray-800" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="px-3 my-2 max-h-72 overflow-y-auto">
|
||||||
|
{#each filteredItems as item}
|
||||||
|
<Select.Item
|
||||||
|
class="flex w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-none transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg cursor-pointer data-[highlighted]:bg-muted"
|
||||||
|
value={item.value}
|
||||||
|
label={item.label}
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="line-clamp-1">
|
||||||
|
{item.label}
|
||||||
|
|
||||||
|
<span class=" text-xs font-medium text-gray-600 dark:text-gray-400"
|
||||||
|
>{item.info?.details?.parameter_size ?? ''}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- {JSON.stringify(item.info)} -->
|
||||||
|
|
||||||
|
{#if item.info.external}
|
||||||
|
<Tooltip content={item.info?.source ?? 'External'}>
|
||||||
|
<div class=" mr-2">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="size-3"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M8.914 6.025a.75.75 0 0 1 1.06 0 3.5 3.5 0 0 1 0 4.95l-2 2a3.5 3.5 0 0 1-5.396-4.402.75.75 0 0 1 1.251.827 2 2 0 0 0 3.085 2.514l2-2a2 2 0 0 0 0-2.828.75.75 0 0 1 0-1.06Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M7.086 9.975a.75.75 0 0 1-1.06 0 3.5 3.5 0 0 1 0-4.95l2-2a3.5 3.5 0 0 1 5.396 4.402.75.75 0 0 1-1.251-.827 2 2 0 0 0-3.085-2.514l-2 2a2 2 0 0 0 0 2.828.75.75 0 0 1 0 1.06Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
{:else}
|
||||||
|
<Tooltip
|
||||||
|
content={`${
|
||||||
|
item.info?.details?.quantization_level
|
||||||
|
? item.info?.details?.quantization_level + ' '
|
||||||
|
: ''
|
||||||
|
}${item.info.size ? `(${(item.info.size / 1024 ** 3).toFixed(1)}GB)` : ''}`}
|
||||||
|
>
|
||||||
|
<div class=" mr-2">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if value === item.value}
|
||||||
|
<div class="ml-auto">
|
||||||
|
<Check />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</Select.Item>
|
||||||
|
{:else}
|
||||||
|
<div>
|
||||||
|
<div class="block px-3 py-2 text-sm text-gray-700 dark:text-gray-100">
|
||||||
|
No results found
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
{#if !(searchValue.trim() in $MODEL_DOWNLOAD_POOL) && searchValue && ollamaVersion && $user.role === 'admin'}
|
||||||
|
<button
|
||||||
|
class="flex w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-none transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg cursor-pointer data-[highlighted]:bg-muted"
|
||||||
|
on:click={() => {
|
||||||
|
pullModelHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Pull "{searchValue}" from Ollama.com
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#each Object.keys($MODEL_DOWNLOAD_POOL) as model}
|
||||||
|
<div
|
||||||
|
class="flex w-full justify-between font-medium select-none rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-none transition-all duration-75 rounded-lg cursor-pointer data-[highlighted]:bg-muted"
|
||||||
|
>
|
||||||
|
<div class="flex">
|
||||||
|
<div class="-ml-2 mr-2.5 translate-y-0.5">
|
||||||
|
<svg
|
||||||
|
class="size-4"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><style>
|
||||||
|
.spinner_ajPY {
|
||||||
|
transform-origin: center;
|
||||||
|
animation: spinner_AtaB 0.75s infinite linear;
|
||||||
|
}
|
||||||
|
@keyframes spinner_AtaB {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style><path
|
||||||
|
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
||||||
|
opacity=".25"
|
||||||
|
/><path
|
||||||
|
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
|
||||||
|
class="spinner_ajPY"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col self-start">
|
||||||
|
<div class="line-clamp-1">
|
||||||
|
Downloading "{model}" {'pullProgress' in $MODEL_DOWNLOAD_POOL[model]
|
||||||
|
? `(${$MODEL_DOWNLOAD_POOL[model].pullProgress}%)`
|
||||||
|
: ''}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if 'digest' in $MODEL_DOWNLOAD_POOL[model] && $MODEL_DOWNLOAD_POOL[model].digest}
|
||||||
|
<div class="-mt-1 h-fit text-[0.7rem] dark:text-gray-500 line-clamp-1">
|
||||||
|
{$MODEL_DOWNLOAD_POOL[model].digest}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mr-2 translate-y-0.5">
|
||||||
|
<Tooltip content="Cancel">
|
||||||
|
<button
|
||||||
|
class="text-gray-800 dark:text-gray-100"
|
||||||
|
on:click={() => {
|
||||||
|
cancelModelPullHandler(model);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4 text-gray-800 dark:text-white"
|
||||||
|
aria-hidden="true"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M6 18 17.94 6M18 18 6.06 6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
|
@ -6,6 +6,8 @@
|
||||||
import { compareVersion } from '$lib/utils';
|
import { compareVersion } from '$lib/utils';
|
||||||
import { onMount, getContext } from 'svelte';
|
import { onMount, getContext } from 'svelte';
|
||||||
|
|
||||||
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
let ollamaVersion = '';
|
let ollamaVersion = '';
|
||||||
|
@ -51,8 +53,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full justify-between items-center">
|
<div class="flex w-full justify-between items-center">
|
||||||
<div class="flex flex-col text-xs text-gray-700 dark:text-gray-200">
|
<div class="flex flex-col text-xs text-gray-700 dark:text-gray-200">
|
||||||
<div>
|
<div class="flex gap-1">
|
||||||
v{WEBUI_VERSION}
|
<Tooltip content={WEBUI_VERSION === '0.1.117' ? "🪖 We're just getting started." : ''}>
|
||||||
|
v{WEBUI_VERSION}
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="https://github.com/open-webui/open-webui/releases/tag/v{version.latest}"
|
href="https://github.com/open-webui/open-webui/releases/tag/v{version.latest}"
|
||||||
|
@ -126,7 +130,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
|
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
|
||||||
{$i18n.t('Created by')}
|
{#if !$WEBUI_NAME.includes('Open WebUI')}
|
||||||
|
<span class=" text-gray-500 dark:text-gray-300 font-medium">{$WEBUI_NAME}</span> -
|
||||||
|
{/if}{$i18n.t('Created by')}
|
||||||
<a
|
<a
|
||||||
class=" text-gray-500 dark:text-gray-300 font-medium"
|
class=" text-gray-500 dark:text-gray-300 font-medium"
|
||||||
href="https://github.com/tjbck"
|
href="https://github.com/tjbck"
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
import { onMount, getContext } from 'svelte';
|
import { onMount, getContext } from 'svelte';
|
||||||
|
|
||||||
import { user } from '$lib/stores';
|
import { user } from '$lib/stores';
|
||||||
import { updateUserProfile } from '$lib/apis/auths';
|
import { updateUserProfile, createAPIKey, getAPIKey } from '$lib/apis/auths';
|
||||||
|
|
||||||
import UpdatePassword from './Account/UpdatePassword.svelte';
|
import UpdatePassword from './Account/UpdatePassword.svelte';
|
||||||
import { getGravatarUrl } from '$lib/apis/utils';
|
import { getGravatarUrl } from '$lib/apis/utils';
|
||||||
import { copyToClipboard } from '$lib/utils';
|
import { copyToClipboard } from '$lib/utils';
|
||||||
|
import Plus from '$lib/components/icons/Plus.svelte';
|
||||||
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
@ -15,8 +17,14 @@
|
||||||
|
|
||||||
let profileImageUrl = '';
|
let profileImageUrl = '';
|
||||||
let name = '';
|
let name = '';
|
||||||
|
|
||||||
let showJWTToken = false;
|
let showJWTToken = false;
|
||||||
let JWTTokenCopied = false;
|
let JWTTokenCopied = false;
|
||||||
|
|
||||||
|
let APIKey = '';
|
||||||
|
let showAPIKey = false;
|
||||||
|
let APIKeyCopied = false;
|
||||||
|
|
||||||
let profileImageInputElement: HTMLInputElement;
|
let profileImageInputElement: HTMLInputElement;
|
||||||
|
|
||||||
const submitHandler = async () => {
|
const submitHandler = async () => {
|
||||||
|
@ -33,9 +41,23 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(() => {
|
const createAPIKeyHandler = async () => {
|
||||||
|
APIKey = await createAPIKey(localStorage.token);
|
||||||
|
if (APIKey) {
|
||||||
|
toast.success($i18n.t('API Key created.'));
|
||||||
|
} else {
|
||||||
|
toast.error($i18n.t('Failed to create API Key.'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
name = $user.name;
|
name = $user.name;
|
||||||
profileImageUrl = $user.profile_image_url;
|
profileImageUrl = $user.profile_image_url;
|
||||||
|
|
||||||
|
APIKey = await getAPIKey(localStorage.token).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -170,41 +192,83 @@
|
||||||
|
|
||||||
<hr class=" dark:border-gray-700 my-4" />
|
<hr class=" dark:border-gray-700 my-4" />
|
||||||
|
|
||||||
<div class=" w-full justify-between">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex w-full justify-between">
|
<div class="justify-between w-full">
|
||||||
<div class=" self-center text-xs font-medium">{$i18n.t('JWT Token')}</div>
|
<div class="flex justify-between w-full">
|
||||||
</div>
|
<div class="self-center text-xs font-medium">{$i18n.t('JWT Token')}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex mt-2">
|
<div class="flex mt-2">
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<input
|
<input
|
||||||
class="w-full rounded-l-lg py-1.5 pl-4 text-sm dark:text-gray-300 dark:bg-gray-800 outline-none"
|
class="w-full rounded-l-lg py-1.5 pl-4 text-sm bg-white dark:text-gray-300 dark:bg-gray-800 outline-none"
|
||||||
type={showJWTToken ? 'text' : 'password'}
|
type={showJWTToken ? 'text' : 'password'}
|
||||||
value={localStorage.token}
|
value={localStorage.token}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="px-2 transition rounded-r-lg bg-white dark:bg-gray-800"
|
||||||
|
on:click={() => {
|
||||||
|
showJWTToken = !showJWTToken;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if showJWTToken}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l10.5 10.5a.75.75 0 1 0 1.06-1.06l-1.322-1.323a7.012 7.012 0 0 0 2.16-3.11.87.87 0 0 0 0-.567A7.003 7.003 0 0 0 4.82 3.76l-1.54-1.54Zm3.196 3.195 1.135 1.136A1.502 1.502 0 0 1 9.45 8.389l1.136 1.135a3 3 0 0 0-4.109-4.109Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="m7.812 10.994 1.816 1.816A7.003 7.003 0 0 1 1.38 8.28a.87.87 0 0 1 0-.566 6.985 6.985 0 0 1 1.113-2.039l2.513 2.513a3 3 0 0 0 2.806 2.806Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" />
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M1.38 8.28a.87.87 0 0 1 0-.566 7.003 7.003 0 0 1 13.238.006.87.87 0 0 1 0 .566A7.003 7.003 0 0 1 1.379 8.28ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="dark:bg-gray-800 px-2 transition rounded-r-lg"
|
class="ml-1.5 px-1.5 py-1 dark:hover:bg-gray-800 transition rounded-lg"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
showJWTToken = !showJWTToken;
|
copyToClipboard(localStorage.token);
|
||||||
|
JWTTokenCopied = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
JWTTokenCopied = false;
|
||||||
|
}, 2000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{#if showJWTToken}
|
{#if JWTTokenCopied}
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 20 20"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l10.5 10.5a.75.75 0 1 0 1.06-1.06l-1.322-1.323a7.012 7.012 0 0 0 2.16-3.11.87.87 0 0 0 0-.567A7.003 7.003 0 0 0 4.82 3.76l-1.54-1.54Zm3.196 3.195 1.135 1.136A1.502 1.502 0 0 1 9.45 8.389l1.136 1.135a3 3 0 0 0-4.109-4.109Z"
|
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
/>
|
/>
|
||||||
<path
|
|
||||||
d="m7.812 10.994 1.816 1.816A7.003 7.003 0 0 1 1.38 8.28a.87.87 0 0 1 0-.566 6.985 6.985 0 0 1 1.113-2.039l2.513 2.513a3 3 0 0 0 2.806 2.806Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
</svg>
|
||||||
{:else}
|
{:else}
|
||||||
<svg
|
<svg
|
||||||
|
@ -213,60 +277,156 @@
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" />
|
|
||||||
<path
|
<path
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
d="M1.38 8.28a.87.87 0 0 1 0-.566 7.003 7.003 0 0 1 13.238.006.87.87 0 0 1 0 .566A7.003 7.003 0 0 1 1.379 8.28ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
d="M11.986 3H12a2 2 0 0 1 2 2v6a2 2 0 0 1-1.5 1.937V7A2.5 2.5 0 0 0 10 4.5H4.063A2 2 0 0 1 6 3h.014A2.25 2.25 0 0 1 8.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM10.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M3 6a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1H3Zm1.75 2.5a.75.75 0 0 0 0 1.5h3.5a.75.75 0 0 0 0-1.5h-3.5ZM4 11.75a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1-.75-.75Z"
|
||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="justify-between w-full">
|
||||||
|
<div class="flex justify-between w-full">
|
||||||
|
<div class="self-center text-xs font-medium">{$i18n.t('API Key')}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<div class="flex mt-2">
|
||||||
class="ml-1.5 px-1.5 py-1 hover:bg-gray-800 transition rounded-lg"
|
{#if APIKey}
|
||||||
on:click={() => {
|
<div class="flex w-full">
|
||||||
copyToClipboard(localStorage.token);
|
<input
|
||||||
JWTTokenCopied = true;
|
class="w-full rounded-l-lg py-1.5 pl-4 text-sm bg-white dark:text-gray-300 dark:bg-gray-800 outline-none"
|
||||||
setTimeout(() => {
|
type={showAPIKey ? 'text' : 'password'}
|
||||||
JWTTokenCopied = false;
|
value={APIKey}
|
||||||
}, 2000);
|
disabled
|
||||||
}}
|
|
||||||
>
|
|
||||||
{#if JWTTokenCopied}
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="currentColor"
|
|
||||||
class="w-4 h-4"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
|
||||||
|
<button
|
||||||
|
class="px-2 transition rounded-r-lg bg-white dark:bg-gray-800"
|
||||||
|
on:click={() => {
|
||||||
|
showAPIKey = !showAPIKey;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if showAPIKey}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l10.5 10.5a.75.75 0 1 0 1.06-1.06l-1.322-1.323a7.012 7.012 0 0 0 2.16-3.11.87.87 0 0 0 0-.567A7.003 7.003 0 0 0 4.82 3.76l-1.54-1.54Zm3.196 3.195 1.135 1.136A1.502 1.502 0 0 1 9.45 8.389l1.136 1.135a3 3 0 0 0-4.109-4.109Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="m7.812 10.994 1.816 1.816A7.003 7.003 0 0 1 1.38 8.28a.87.87 0 0 1 0-.566 6.985 6.985 0 0 1 1.113-2.039l2.513 2.513a3 3 0 0 0 2.806 2.806Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" />
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M1.38 8.28a.87.87 0 0 1 0-.566 7.003 7.003 0 0 1 13.238.006.87.87 0 0 1 0 .566A7.003 7.003 0 0 1 1.379 8.28ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="ml-1.5 px-1.5 py-1 dark:hover:bg-gray-800 transition rounded-lg"
|
||||||
|
on:click={() => {
|
||||||
|
copyToClipboard(APIKey);
|
||||||
|
APIKeyCopied = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
APIKeyCopied = false;
|
||||||
|
}, 2000);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{#if APIKeyCopied}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{:else}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-4 h-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M11.986 3H12a2 2 0 0 1 2 2v6a2 2 0 0 1-1.5 1.937V7A2.5 2.5 0 0 0 10 4.5H4.063A2 2 0 0 1 6 3h.014A2.25 2.25 0 0 1 8.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM10.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M3 6a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1H3Zm1.75 2.5a.75.75 0 0 0 0 1.5h3.5a.75.75 0 0 0 0-1.5h-3.5ZM4 11.75a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1-.75-.75Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Tooltip content="Create new key">
|
||||||
|
<button
|
||||||
|
class=" px-1.5 py-1 dark:hover:bg-gray-800transition rounded-lg"
|
||||||
|
on:click={() => {
|
||||||
|
createAPIKeyHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
{:else}
|
{:else}
|
||||||
<svg
|
<button
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
class="flex gap-1.5 items-center font-medium px-3.5 py-1.5 rounded-lg bg-gray-100/70 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition"
|
||||||
viewBox="0 0 16 16"
|
on:click={() => {
|
||||||
fill="currentColor"
|
createAPIKeyHandler();
|
||||||
class="w-4 h-4"
|
}}
|
||||||
|
>
|
||||||
|
<Plus strokeWidth="2" className=" size-3.5" />
|
||||||
|
|
||||||
|
Create new secret key</button
|
||||||
>
|
>
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M11.986 3H12a2 2 0 0 1 2 2v6a2 2 0 0 1-1.5 1.937V7A2.5 2.5 0 0 0 10 4.5H4.063A2 2 0 0 1 6 3h.014A2.25 2.25 0 0 1 8.25 1h1.5a2.25 2.25 0 0 1 2.236 2ZM10.5 4v-.75a.75.75 0 0 0-.75-.75h-1.5a.75.75 0 0 0-.75.75V4h3Z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M3 6a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1H3Zm1.75 2.5a.75.75 0 0 0 0 1.5h3.5a.75.75 0 0 0 0-1.5h-3.5ZM4 11.75a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1-.75-.75Z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
export let getModels: Function;
|
export let getModels: Function;
|
||||||
|
|
||||||
// General
|
// General
|
||||||
let themes = ['dark', 'light', 'rose-pine dark', 'rose-pine-dawn light'];
|
let themes = ['dark', 'light', 'rose-pine dark', 'rose-pine-dawn light', 'oled-dark'];
|
||||||
let selectedTheme = 'system';
|
let selectedTheme = 'system';
|
||||||
|
|
||||||
let languages = [];
|
let languages = [];
|
||||||
|
@ -91,12 +91,17 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const applyTheme = (_theme: string) => {
|
const applyTheme = (_theme: string) => {
|
||||||
let themeToApply = _theme;
|
let themeToApply = _theme === 'oled-dark' ? 'dark' : _theme;
|
||||||
|
|
||||||
if (_theme === 'system') {
|
if (_theme === 'system') {
|
||||||
themeToApply = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
themeToApply = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (themeToApply === 'dark' && !_theme.includes('oled')) {
|
||||||
|
document.documentElement.style.setProperty('--color-gray-900', '#171717');
|
||||||
|
document.documentElement.style.setProperty('--color-gray-950', '#0d0d0d');
|
||||||
|
}
|
||||||
|
|
||||||
themes
|
themes
|
||||||
.filter((e) => e !== themeToApply)
|
.filter((e) => e !== themeToApply)
|
||||||
.forEach((e) => {
|
.forEach((e) => {
|
||||||
|
@ -115,7 +120,11 @@
|
||||||
const themeChangeHandler = (_theme: string) => {
|
const themeChangeHandler = (_theme: string) => {
|
||||||
theme.set(_theme);
|
theme.set(_theme);
|
||||||
localStorage.setItem('theme', _theme);
|
localStorage.setItem('theme', _theme);
|
||||||
|
if (_theme.includes('oled')) {
|
||||||
|
document.documentElement.style.setProperty('--color-gray-900', '#000000');
|
||||||
|
document.documentElement.style.setProperty('--color-gray-950', '#000000');
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
}
|
||||||
applyTheme(_theme);
|
applyTheme(_theme);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -136,6 +145,7 @@
|
||||||
>
|
>
|
||||||
<option value="system">⚙️ {$i18n.t('System')}</option>
|
<option value="system">⚙️ {$i18n.t('System')}</option>
|
||||||
<option value="dark">🌑 {$i18n.t('Dark')}</option>
|
<option value="dark">🌑 {$i18n.t('Dark')}</option>
|
||||||
|
<option value="oled-dark">🌃 {$i18n.t('OLED Dark')}</option>
|
||||||
<option value="light">☀️ {$i18n.t('Light')}</option>
|
<option value="light">☀️ {$i18n.t('Light')}</option>
|
||||||
<option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option>
|
<option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option>
|
||||||
<option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option>
|
<option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getBackendConfig } from '$lib/apis';
|
import { getBackendConfig } from '$lib/apis';
|
||||||
import { setDefaultPromptSuggestions } from '$lib/apis/configs';
|
import { setDefaultPromptSuggestions } from '$lib/apis/configs';
|
||||||
import { config, models, user } from '$lib/stores';
|
import { config, models, settings, user } from '$lib/stores';
|
||||||
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
import { createEventDispatcher, onMount, getContext } from 'svelte';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
let titleAutoGenerate = true;
|
let titleAutoGenerate = true;
|
||||||
let responseAutoCopy = false;
|
let responseAutoCopy = false;
|
||||||
let titleAutoGenerateModel = '';
|
let titleAutoGenerateModel = '';
|
||||||
|
let titleAutoGenerateModelExternal = '';
|
||||||
let fullScreenMode = false;
|
let fullScreenMode = false;
|
||||||
let titleGenerationPrompt = '';
|
let titleGenerationPrompt = '';
|
||||||
|
|
||||||
|
@ -33,7 +34,12 @@
|
||||||
|
|
||||||
const toggleTitleAutoGenerate = async () => {
|
const toggleTitleAutoGenerate = async () => {
|
||||||
titleAutoGenerate = !titleAutoGenerate;
|
titleAutoGenerate = !titleAutoGenerate;
|
||||||
saveSettings({ titleAutoGenerate: titleAutoGenerate });
|
saveSettings({
|
||||||
|
title: {
|
||||||
|
...$settings.title,
|
||||||
|
auto: titleAutoGenerate
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleResponseAutoCopy = async () => {
|
const toggleResponseAutoCopy = async () => {
|
||||||
|
@ -65,8 +71,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettings({
|
saveSettings({
|
||||||
titleAutoGenerateModel: titleAutoGenerateModel !== '' ? titleAutoGenerateModel : undefined,
|
title: {
|
||||||
titleGenerationPrompt: titleGenerationPrompt ? titleGenerationPrompt : undefined
|
...$settings.title,
|
||||||
|
model: titleAutoGenerateModel !== '' ? titleAutoGenerateModel : undefined,
|
||||||
|
modelExternal:
|
||||||
|
titleAutoGenerateModelExternal !== '' ? titleAutoGenerateModelExternal : undefined,
|
||||||
|
prompt: titleGenerationPrompt ? titleGenerationPrompt : undefined
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,16 +88,18 @@
|
||||||
|
|
||||||
let settings = JSON.parse(localStorage.getItem('settings') ?? '{}');
|
let settings = JSON.parse(localStorage.getItem('settings') ?? '{}');
|
||||||
|
|
||||||
titleAutoGenerate = settings.titleAutoGenerate ?? true;
|
titleAutoGenerate = settings?.title?.auto ?? true;
|
||||||
responseAutoCopy = settings.responseAutoCopy ?? false;
|
titleAutoGenerateModel = settings?.title?.model ?? '';
|
||||||
showUsername = settings.showUsername ?? false;
|
titleAutoGenerateModelExternal = settings?.title?.modelExternal ?? '';
|
||||||
fullScreenMode = settings.fullScreenMode ?? false;
|
|
||||||
titleAutoGenerateModel = settings.titleAutoGenerateModel ?? '';
|
|
||||||
titleGenerationPrompt =
|
titleGenerationPrompt =
|
||||||
settings.titleGenerationPrompt ??
|
settings?.title?.prompt ??
|
||||||
$i18n.t(
|
$i18n.t(
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':"
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':"
|
||||||
) + ' {{prompt}}';
|
) + ' {{prompt}}';
|
||||||
|
|
||||||
|
responseAutoCopy = settings.responseAutoCopy ?? false;
|
||||||
|
showUsername = settings.showUsername ?? false;
|
||||||
|
fullScreenMode = settings.fullScreenMode ?? false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -190,8 +203,9 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Title Auto-Generation Model')}</div>
|
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('Set Title Auto-Generation Model')}</div>
|
||||||
<div class="flex w-full">
|
<div class="flex w-full gap-2 pr-2">
|
||||||
<div class="flex-1 mr-2">
|
<div class="flex-1">
|
||||||
|
<div class=" text-xs mb-1">Local Models</div>
|
||||||
<select
|
<select
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
bind:value={titleAutoGenerateModel}
|
bind:value={titleAutoGenerateModel}
|
||||||
|
@ -207,6 +221,24 @@
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class=" text-xs mb-1">External Models</div>
|
||||||
|
<select
|
||||||
|
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
|
bind:value={titleAutoGenerateModelExternal}
|
||||||
|
placeholder={$i18n.t('Select a model')}
|
||||||
|
>
|
||||||
|
<option value="" selected>{$i18n.t('Current Model')}</option>
|
||||||
|
{#each $models as model}
|
||||||
|
{#if model.name !== 'hr'}
|
||||||
|
<option value={model.name} class="bg-gray-100 dark:bg-gray-700">
|
||||||
|
{model.name}
|
||||||
|
</option>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 mr-2">
|
<div class="mt-3 mr-2">
|
||||||
|
|
|
@ -258,6 +258,9 @@
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const error = await fileResponse?.json();
|
||||||
|
toast.error(error?.detail ?? error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uploaded) {
|
if (uploaded) {
|
||||||
|
|
|
@ -1,41 +1,153 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext } from 'svelte';
|
import { getContext, onMount } from 'svelte';
|
||||||
import Modal from '../common/Modal.svelte';
|
|
||||||
|
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
|
import { deleteSharedChatById, getChatById, shareChatById } from '$lib/apis/chats';
|
||||||
|
import { chatId, modelfiles } from '$lib/stores';
|
||||||
|
import { copyToClipboard } from '$lib/utils';
|
||||||
|
|
||||||
|
import Modal from '../common/Modal.svelte';
|
||||||
|
import Link from '../icons/Link.svelte';
|
||||||
|
|
||||||
|
let chat = null;
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
export let downloadChat: Function;
|
const shareLocalChat = async () => {
|
||||||
export let shareChat: Function;
|
const _chat = chat;
|
||||||
|
|
||||||
|
const sharedChat = await shareChatById(localStorage.token, $chatId);
|
||||||
|
const chatShareUrl = `${window.location.origin}/s/${sharedChat.id}`;
|
||||||
|
|
||||||
|
toast.success($i18n.t('Copied shared chat URL to clipboard!'));
|
||||||
|
copyToClipboard(chatShareUrl);
|
||||||
|
chat = await getChatById(localStorage.token, $chatId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const shareChat = async () => {
|
||||||
|
const _chat = chat.chat;
|
||||||
|
console.log('share', _chat);
|
||||||
|
|
||||||
|
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
||||||
|
const url = 'https://openwebui.com';
|
||||||
|
// const url = 'http://localhost:5173';
|
||||||
|
|
||||||
|
const tab = await window.open(`${url}/chats/upload`, '_blank');
|
||||||
|
window.addEventListener(
|
||||||
|
'message',
|
||||||
|
(event) => {
|
||||||
|
if (event.origin !== url) return;
|
||||||
|
if (event.data === 'loaded') {
|
||||||
|
tab.postMessage(
|
||||||
|
JSON.stringify({
|
||||||
|
chat: _chat,
|
||||||
|
modelfiles: $modelfiles.filter((modelfile) =>
|
||||||
|
_chat.models.includes(modelfile.tagName)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
'*'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
|
|
||||||
|
$: if (show) {
|
||||||
|
(async () => {
|
||||||
|
if ($chatId) {
|
||||||
|
chat = await getChatById(localStorage.token, $chatId);
|
||||||
|
} else {
|
||||||
|
chat = null;
|
||||||
|
console.log(chat);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal bind:show size="xs">
|
<Modal bind:show size="sm">
|
||||||
<div class="px-4 pt-4 pb-5 w-full flex flex-col justify-center">
|
<div>
|
||||||
<button
|
<div class=" flex justify-between dark:text-gray-300 px-5 py-4">
|
||||||
class=" self-center px-8 py-1.5 w-full rounded-full text-sm font-medium bg-blue-600 hover:bg-blue-500 text-white"
|
<div class=" text-lg font-medium self-center">{$i18n.t('Share Chat')}</div>
|
||||||
type="button"
|
|
||||||
on:click={() => {
|
|
||||||
shareChat();
|
|
||||||
show = false;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{$i18n.t('Share to OpenWebUI Community')}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="flex justify-center space-x-1 mt-1.5">
|
|
||||||
<div class=" self-center text-gray-400 text-xs font-medium">{$i18n.t('or')}</div>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class=" self-center rounded-full text-xs font-medium text-gray-700 dark:text-gray-500 underline"
|
class="self-center"
|
||||||
type="button"
|
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
downloadChat();
|
|
||||||
show = false;
|
show = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{$i18n.t('Download as a File')}
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="w-5 h-5"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<hr class=" dark:border-gray-800" />
|
||||||
|
|
||||||
|
{#if chat}
|
||||||
|
<div class="px-4 pt-4 pb-5 w-full flex flex-col justify-center">
|
||||||
|
<div class=" text-sm dark:text-gray-300 mb-1">
|
||||||
|
{#if chat.share_id}
|
||||||
|
<a href="/s/{chat.share_id}" target="_blank"
|
||||||
|
>You have shared this chat <span class=" underline">before</span>.</a
|
||||||
|
>
|
||||||
|
Click here to
|
||||||
|
<button
|
||||||
|
class="underline"
|
||||||
|
on:click={async () => {
|
||||||
|
const res = await deleteSharedChatById(localStorage.token, $chatId);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
chat = await getChatById(localStorage.token, $chatId);
|
||||||
|
}
|
||||||
|
}}>delete this link</button
|
||||||
|
> and create a new shared link.
|
||||||
|
{:else}
|
||||||
|
Messages you send after creating your link won't be shared. Users with the URL will be
|
||||||
|
able to view the shared chat.
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<div class="flex flex-col items-end space-x-1 mt-1.5">
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<button
|
||||||
|
class=" self-center px-3.5 py-2 rounded-xl text-sm font-medium bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
shareChat();
|
||||||
|
show = false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{$i18n.t('Share to OpenWebUI Community')}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class=" self-center flex items-center gap-1 px-3.5 py-2 rounded-xl text-sm font-medium bg-emerald-600 hover:bg-emerald-500 text-white"
|
||||||
|
type="button"
|
||||||
|
on:click={() => {
|
||||||
|
shareLocalChat();
|
||||||
|
show = false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Link />
|
||||||
|
|
||||||
|
{#if chat.share_id}
|
||||||
|
{$i18n.t('Update and Copy Link')}
|
||||||
|
{:else}
|
||||||
|
{$i18n.t('Copy Link')}
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
20
src/lib/components/chat/TagChatModal.svelte
Normal file
20
src/lib/components/chat/TagChatModal.svelte
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
import Modal from '../common/Modal.svelte';
|
||||||
|
|
||||||
|
import Tags from '../common/Tags.svelte';
|
||||||
|
|
||||||
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
export let tags;
|
||||||
|
export let deleteTag: Function;
|
||||||
|
export let addTag: Function;
|
||||||
|
|
||||||
|
export let show = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal bind:show size="xs">
|
||||||
|
<div class="px-4 pt-4 pb-5 w-full flex flex-col justify-center">
|
||||||
|
<Tags {tags} {deleteTag} {addTag} />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
export let value = '';
|
export let value = '';
|
||||||
export let placeholder = 'Select a model';
|
export let placeholder = 'Select a model';
|
||||||
|
export let searchEnabled = true;
|
||||||
|
export let searchPlaceholder = 'Search a model';
|
||||||
|
|
||||||
export let items = [
|
export let items = [
|
||||||
{ value: 'mango', label: 'Mango' },
|
{ value: 'mango', label: 'Mango' },
|
||||||
{ value: 'watermelon', label: 'Watermelon' },
|
{ value: 'watermelon', label: 'Watermelon' },
|
||||||
|
@ -49,39 +52,44 @@
|
||||||
transition={flyAndScale}
|
transition={flyAndScale}
|
||||||
sideOffset={4}
|
sideOffset={4}
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2.5 px-5 mt-3.5 mb-3">
|
<slot>
|
||||||
<Search className="size-4" strokeWidth="2.5" />
|
{#if searchEnabled}
|
||||||
|
<div class="flex items-center gap-2.5 px-5 mt-3.5 mb-3">
|
||||||
|
<Search className="size-4" strokeWidth="2.5" />
|
||||||
|
|
||||||
<input
|
<input
|
||||||
bind:value={searchValue}
|
bind:value={searchValue}
|
||||||
class="w-full text-sm bg-transparent outline-none"
|
class="w-full text-sm bg-transparent outline-none"
|
||||||
placeholder="Search a model"
|
placeholder={searchPlaceholder}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="border-gray-100 dark:border-gray-800" />
|
<hr class="border-gray-100 dark:border-gray-800" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="px-3 my-2 max-h-80 overflow-y-auto">
|
<div class="px-3 my-2 max-h-80 overflow-y-auto">
|
||||||
{#each filteredItems as item}
|
{#each filteredItems as item}
|
||||||
<Select.Item
|
<Select.Item
|
||||||
class="flex w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-none transition-all duration-75 data-[highlighted]:bg-muted"
|
class="flex w-full font-medium line-clamp-1 select-none items-center rounded-button py-2 pl-3 pr-1.5 text-sm text-gray-700 dark:text-gray-100 outline-none transition-all duration-75 hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg cursor-pointer data-[highlighted]:bg-muted"
|
||||||
value={item.value}
|
value={item.value}
|
||||||
label={item.label}
|
label={item.label}
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
|
|
||||||
{#if value === item.value}
|
{#if value === item.value}
|
||||||
<div class="ml-auto">
|
<div class="ml-auto">
|
||||||
<Check />
|
<Check />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</Select.Item>
|
||||||
|
{:else}
|
||||||
|
<div>
|
||||||
|
<div class="block px-5 py-2 text-sm text-gray-700 dark:text-gray-100">
|
||||||
|
No results found
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
</div>
|
||||||
</Select.Item>
|
{/each}
|
||||||
{:else}
|
</div>
|
||||||
<span class="block px-5 py-2 text-sm text-gray-700 dark:text-gray-100">
|
</slot>
|
||||||
No results found
|
|
||||||
</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</Select.Content>
|
</Select.Content>
|
||||||
<Select.Input name="favoriteFruit" />
|
|
||||||
</Select.Root>
|
</Select.Root>
|
|
@ -1,24 +1,25 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let className: string = 'text-white';
|
export let className: string = '';
|
||||||
export let theme: 'blue' | 'white' | 'black' = 'white';
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex justify-center text-center {className}">
|
<div class="flex justify-center text-center {className}">
|
||||||
<svg
|
<svg class="size-5" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"
|
||||||
class="animate-spin -ml-1 mr-3 h-5 w-5 {theme === 'blue'
|
><style>
|
||||||
? 'text-sky-600'
|
.spinner_ajPY {
|
||||||
: theme === 'white'
|
transform-origin: center;
|
||||||
? 'text-white'
|
animation: spinner_AtaB 0.75s infinite linear;
|
||||||
: 'text-gray-600'} "
|
}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
@keyframes spinner_AtaB {
|
||||||
fill="none"
|
100% {
|
||||||
viewBox="0 0 24 24"
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style><path
|
||||||
|
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
||||||
|
opacity=".25"
|
||||||
|
/><path
|
||||||
|
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
|
||||||
|
class="spinner_ajPY"
|
||||||
|
/></svg
|
||||||
>
|
>
|
||||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
|
|
||||||
<path
|
|
||||||
class="opacity-75"
|
|
||||||
fill="currentColor"
|
|
||||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
export let addTag: Function;
|
export let addTag: Function;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-row space-x-0.5 line-clamp-1">
|
<div class="flex flex-row flex-wrap gap-0.5 line-clamp-1">
|
||||||
<TagList
|
<TagList
|
||||||
{tags}
|
{tags}
|
||||||
on:delete={(e) => {
|
on:delete={(e) => {
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TagInput
|
<TagInput
|
||||||
|
label={tags.length == 0 ? 'Add Tags' : ''}
|
||||||
on:add={(e) => {
|
on:add={(e) => {
|
||||||
addTag(e.detail);
|
addTag(e.detail);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, getContext } from 'svelte';
|
import { createEventDispatcher, getContext } from 'svelte';
|
||||||
|
import { tags } from '$lib/stores';
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
export let label = '';
|
||||||
let showTagInput = false;
|
let showTagInput = false;
|
||||||
let tagName = '';
|
let tagName = '';
|
||||||
|
|
||||||
|
const addTagHandler = async () => {
|
||||||
|
tagName = tagName.trim();
|
||||||
|
if (tagName !== '') {
|
||||||
|
dispatch('add', tagName);
|
||||||
|
tagName = '';
|
||||||
|
showTagInput = false;
|
||||||
|
} else {
|
||||||
|
toast.error('Invalid Tag');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex space-x-1 pl-1.5">
|
<div class="flex space-x-1 pl-1.5">
|
||||||
{#if showTagInput}
|
{#if showTagInput}
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<button
|
<button type="button" on:click={addTagHandler}>
|
||||||
type="button"
|
|
||||||
on:click={() => {
|
|
||||||
dispatch('add', tagName);
|
|
||||||
tagName = '';
|
|
||||||
showTagInput = false;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
@ -34,12 +41,21 @@
|
||||||
</button>
|
</button>
|
||||||
<input
|
<input
|
||||||
bind:value={tagName}
|
bind:value={tagName}
|
||||||
class=" pl-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[8rem]"
|
class=" pl-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-none line-clamp-1 w-[5.5rem]"
|
||||||
placeholder={$i18n.t('Add a tag')}
|
placeholder={$i18n.t('Add a tag')}
|
||||||
|
list="tagOptions"
|
||||||
|
on:keydown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
addTagHandler();
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
<datalist id="tagOptions">
|
||||||
|
{#each $tags as tag}
|
||||||
|
<option value={tag.name} />
|
||||||
|
{/each}
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- TODO: Tag Suggestions -->
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -62,4 +78,8 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{#if label && !showTagInput}
|
||||||
|
<span class="text-xs pl-1.5 self-center">{label}</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
{#each tags as tag}
|
{#each tags as tag}
|
||||||
<div
|
<div
|
||||||
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition border dark:border-gray-600 dark:text-white"
|
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition border dark:border-gray-800 dark:text-white"
|
||||||
>
|
>
|
||||||
<div class=" text-[0.7rem] font-medium self-center line-clamp-1">
|
<div class=" text-[0.7rem] font-medium self-center line-clamp-1">
|
||||||
{tag.name}
|
{tag.name}
|
||||||
|
|
|
@ -29,6 +29,6 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={tooltipElement} aria-label={content}>
|
<div bind:this={tooltipElement} aria-label={content} class="flex">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
19
src/lib/components/icons/ChevronUpDown.svelte
Normal file
19
src/lib/components/icons/ChevronUpDown.svelte
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"
|
||||||
|
/>
|
||||||
|
</svg>
|
19
src/lib/components/icons/EllipsisVertical.svelte
Normal file
19
src/lib/components/icons/EllipsisVertical.svelte
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 12.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 18.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
16
src/lib/components/icons/Link.svelte
Normal file
16
src/lib/components/icons/Link.svelte
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class={className}>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M8.914 6.025a.75.75 0 0 1 1.06 0 3.5 3.5 0 0 1 0 4.95l-2 2a3.5 3.5 0 0 1-5.396-4.402.75.75 0 0 1 1.251.827 2 2 0 0 0 3.085 2.514l2-2a2 2 0 0 0 0-2.828.75.75 0 0 1 0-1.06Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M7.086 9.975a.75.75 0 0 1-1.06 0 3.5 3.5 0 0 1 0-4.95l2-2a3.5 3.5 0 0 1 5.396 4.402.75.75 0 0 1-1.251-.827 2 2 0 0 0-3.085-2.514l-2 2a2 2 0 0 0 0 2.828.75.75 0 0 1 0 1.06Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
15
src/lib/components/icons/Plus.svelte
Normal file
15
src/lib/components/icons/Plus.svelte
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||||
|
</svg>
|
|
@ -1,14 +1,14 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import fileSaver from 'file-saver';
|
|
||||||
const { saveAs } = fileSaver;
|
|
||||||
|
|
||||||
import { getChatById } from '$lib/apis/chats';
|
import { WEBUI_NAME, chatId, modelfiles, settings, showSettings } from '$lib/stores';
|
||||||
import { WEBUI_NAME, chatId, modelfiles, settings } from '$lib/stores';
|
|
||||||
|
import { slide } from 'svelte/transition';
|
||||||
import ShareChatModal from '../chat/ShareChatModal.svelte';
|
import ShareChatModal from '../chat/ShareChatModal.svelte';
|
||||||
import TagInput from '../common/Tags/TagInput.svelte';
|
import ModelSelector from '../chat/ModelSelector.svelte';
|
||||||
import Tags from '../common/Tags.svelte';
|
import Tooltip from '../common/Tooltip.svelte';
|
||||||
|
import Menu from './Navbar/Menu.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
@ -16,123 +16,126 @@
|
||||||
export let title: string = $WEBUI_NAME;
|
export let title: string = $WEBUI_NAME;
|
||||||
export let shareEnabled: boolean = false;
|
export let shareEnabled: boolean = false;
|
||||||
|
|
||||||
|
export let chat;
|
||||||
|
export let selectedModels;
|
||||||
|
|
||||||
export let tags = [];
|
export let tags = [];
|
||||||
export let addTag: Function;
|
export let addTag: Function;
|
||||||
export let deleteTag: Function;
|
export let deleteTag: Function;
|
||||||
|
|
||||||
|
export let showModelSelector = true;
|
||||||
|
|
||||||
let showShareChatModal = false;
|
let showShareChatModal = false;
|
||||||
|
let showDownloadChatModal = false;
|
||||||
let tagName = '';
|
|
||||||
let showTagInput = false;
|
|
||||||
|
|
||||||
const shareChat = async () => {
|
|
||||||
const chat = (await getChatById(localStorage.token, $chatId)).chat;
|
|
||||||
console.log('share', chat);
|
|
||||||
|
|
||||||
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
|
||||||
const url = 'https://openwebui.com';
|
|
||||||
// const url = 'http://localhost:5173';
|
|
||||||
|
|
||||||
const tab = await window.open(`${url}/chats/upload`, '_blank');
|
|
||||||
window.addEventListener(
|
|
||||||
'message',
|
|
||||||
(event) => {
|
|
||||||
if (event.origin !== url) return;
|
|
||||||
if (event.data === 'loaded') {
|
|
||||||
tab.postMessage(
|
|
||||||
JSON.stringify({
|
|
||||||
chat: chat,
|
|
||||||
modelfiles: $modelfiles.filter((modelfile) => chat.models.includes(modelfile.tagName))
|
|
||||||
}),
|
|
||||||
'*'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const downloadChat = async () => {
|
|
||||||
const chat = (await getChatById(localStorage.token, $chatId)).chat;
|
|
||||||
console.log('download', chat);
|
|
||||||
|
|
||||||
const chatText = chat.messages.reduce((a, message, i, arr) => {
|
|
||||||
return `${a}### ${message.role.toUpperCase()}\n${message.content}\n\n`;
|
|
||||||
}, '');
|
|
||||||
|
|
||||||
let blob = new Blob([chatText], {
|
|
||||||
type: 'text/plain'
|
|
||||||
});
|
|
||||||
|
|
||||||
saveAs(blob, `chat-${chat.title}.txt`);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ShareChatModal bind:show={showShareChatModal} {downloadChat} {shareChat} />
|
<ShareChatModal bind:show={showShareChatModal} />
|
||||||
<nav id="nav" class=" sticky py-2.5 top-0 flex flex-row justify-center z-30">
|
<nav id="nav" class=" sticky py-2.5 top-0 flex flex-row justify-center z-30">
|
||||||
<div
|
<div
|
||||||
class=" flex {$settings?.fullScreenMode ?? null
|
class=" flex {$settings?.fullScreenMode ?? null ? 'max-w-full' : 'max-w-3xl'}
|
||||||
? 'max-w-full'
|
w-full mx-auto px-3"
|
||||||
: 'max-w-3xl'} w-full mx-auto px-3"
|
|
||||||
>
|
>
|
||||||
<div class="flex items-center w-full max-w-full">
|
<div class="flex items-center w-full max-w-full">
|
||||||
<div class="pr-2 self-start">
|
<div class="flex-1 overflow-hidden max-w-full">
|
||||||
<button
|
{#if showModelSelector}
|
||||||
id="new-chat-button"
|
<ModelSelector bind:selectedModels />
|
||||||
class=" cursor-pointer p-1.5 flex dark:hover:bg-gray-700 rounded-lg transition"
|
{/if}
|
||||||
on:click={initNewChat}
|
</div>
|
||||||
>
|
|
||||||
<div class=" m-auto self-center">
|
<div class="self-start flex flex-none items-center">
|
||||||
<svg
|
<div class="flex self-center w-[1px] h-5 mx-2 bg-gray-300 dark:bg-stone-700" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 20 20"
|
{#if !shareEnabled}
|
||||||
fill="currentColor"
|
<Tooltip content="Settings">
|
||||||
class="w-5 h-5"
|
<button
|
||||||
|
class="cursor-pointer p-1.5 flex dark:hover:bg-gray-700 rounded-full transition"
|
||||||
|
id="open-settings-button"
|
||||||
|
on:click={async () => {
|
||||||
|
await showSettings.set(!$showSettings);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M5.433 13.917l1.262-3.155A4 4 0 017.58 9.42l6.92-6.918a2.121 2.121 0 013 3l-6.92 6.918c-.383.383-.84.685-1.343.886l-3.154 1.262a.5.5 0 01-.65-.65z"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
/>
|
fill="none"
|
||||||
<path
|
viewBox="0 0 24 24"
|
||||||
d="M3.5 5.75c0-.69.56-1.25 1.25-1.25H10A.75.75 0 0010 3H4.75A2.75 2.75 0 002 5.75v9.5A2.75 2.75 0 004.75 18h9.5A2.75 2.75 0 0017 15.25V10a.75.75 0 00-1.5 0v5.25c0 .69-.56 1.25-1.25 1.25h-9.5c-.69 0-1.25-.56-1.25-1.25v-9.5z"
|
stroke-width="1.5"
|
||||||
/>
|
stroke="currentColor"
|
||||||
</svg>
|
class="w-5 h-5"
|
||||||
</div>
|
>
|
||||||
</button>
|
<path
|
||||||
</div>
|
stroke-linecap="round"
|
||||||
<div class=" flex-1 self-center font-medium line-clamp-1">
|
stroke-linejoin="round"
|
||||||
<div>
|
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"
|
||||||
{title != '' ? title : $WEBUI_NAME}
|
/>
|
||||||
</div>
|
<path
|
||||||
</div>
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
<div class="pl-2 self-center flex items-center space-x-2">
|
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
{#if shareEnabled}
|
/>
|
||||||
<Tags {tags} {deleteTag} {addTag} />
|
</svg>
|
||||||
|
</button>
|
||||||
<button
|
</Tooltip>
|
||||||
class=" cursor-pointer p-1.5 flex dark:hover:bg-gray-700 rounded-lg transition"
|
{:else}
|
||||||
on:click={async () => {
|
<Menu
|
||||||
|
{chat}
|
||||||
|
{shareEnabled}
|
||||||
|
shareHandler={() => {
|
||||||
showShareChatModal = !showShareChatModal;
|
showShareChatModal = !showShareChatModal;
|
||||||
|
}}
|
||||||
// console.log(showShareChatModal);
|
downloadHandler={() => {
|
||||||
|
showDownloadChatModal = !showDownloadChatModal;
|
||||||
|
}}
|
||||||
|
{tags}
|
||||||
|
{deleteTag}
|
||||||
|
{addTag}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="cursor-pointer p-1.5 flex dark:hover:bg-gray-700 rounded-full transition"
|
||||||
|
>
|
||||||
|
<div class=" m-auto self-center">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-5"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M6.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM12.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM18.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</Menu>
|
||||||
|
{/if}
|
||||||
|
<Tooltip content="New Chat">
|
||||||
|
<button
|
||||||
|
id="new-chat-button"
|
||||||
|
class=" cursor-pointer p-1.5 flex dark:hover:bg-gray-700 rounded-full transition"
|
||||||
|
on:click={() => {
|
||||||
|
initNewChat();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class=" m-auto self-center">
|
<div class=" m-auto self-center">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 20 20"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-5 h-5"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill-rule="evenodd"
|
d="M5.433 13.917l1.262-3.155A4 4 0 017.58 9.42l6.92-6.918a2.121 2.121 0 013 3l-6.92 6.918c-.383.383-.84.685-1.343.886l-3.154 1.262a.5.5 0 01-.65-.65z"
|
||||||
d="M15.75 4.5a3 3 0 1 1 .825 2.066l-8.421 4.679a3.002 3.002 0 0 1 0 1.51l8.421 4.679a3 3 0 1 1-.729 1.31l-8.421-4.678a3 3 0 1 1 0-4.132l8.421-4.679a3 3 0 0 1-.096-.755Z"
|
/>
|
||||||
clip-rule="evenodd"
|
<path
|
||||||
|
d="M3.5 5.75c0-.69.56-1.25 1.25-1.25H10A.75.75 0 0010 3H4.75A2.75 2.75 0 002 5.75v9.5A2.75 2.75 0 004.75 18h9.5A2.75 2.75 0 0017 15.25V10a.75.75 0 00-1.5 0v5.25c0 .69-.56 1.25-1.25 1.25h-9.5c-.69 0-1.25-.56-1.25-1.25v-9.5z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
223
src/lib/components/layout/Navbar/Menu.svelte
Normal file
223
src/lib/components/layout/Navbar/Menu.svelte
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu } from 'bits-ui';
|
||||||
|
|
||||||
|
import fileSaver from 'file-saver';
|
||||||
|
const { saveAs } = fileSaver;
|
||||||
|
|
||||||
|
import { jsPDF } from 'jspdf';
|
||||||
|
|
||||||
|
import { showSettings } from '$lib/stores';
|
||||||
|
import { flyAndScale } from '$lib/utils/transitions';
|
||||||
|
|
||||||
|
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||||
|
import Tags from '$lib/components/common/Tags.svelte';
|
||||||
|
import { WEBUI_BASE_URL } from '$lib/constants';
|
||||||
|
import { downloadChatAsPDF } from '$lib/apis/utils';
|
||||||
|
|
||||||
|
export let shareEnabled: boolean = false;
|
||||||
|
export let shareHandler: Function;
|
||||||
|
export let downloadHandler: Function;
|
||||||
|
|
||||||
|
// export let tagHandler: Function;
|
||||||
|
|
||||||
|
export let chat;
|
||||||
|
export let tags;
|
||||||
|
export let deleteTag: Function;
|
||||||
|
export let addTag: Function;
|
||||||
|
|
||||||
|
export let onClose: Function = () => {};
|
||||||
|
|
||||||
|
const downloadTxt = async () => {
|
||||||
|
const _chat = chat.chat;
|
||||||
|
console.log('download', chat);
|
||||||
|
|
||||||
|
const chatText = _chat.messages.reduce((a, message, i, arr) => {
|
||||||
|
return `${a}### ${message.role.toUpperCase()}\n${message.content}\n\n`;
|
||||||
|
}, '');
|
||||||
|
|
||||||
|
let blob = new Blob([chatText], {
|
||||||
|
type: 'text/plain'
|
||||||
|
});
|
||||||
|
|
||||||
|
saveAs(blob, `chat-${_chat.title}.txt`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const downloadPdf = async () => {
|
||||||
|
const _chat = chat.chat;
|
||||||
|
console.log('download', chat);
|
||||||
|
|
||||||
|
const blob = await downloadChatAsPDF(_chat);
|
||||||
|
|
||||||
|
// Create a URL for the blob
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// Create a link element to trigger the download
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `chat-${_chat.title}.pdf`;
|
||||||
|
|
||||||
|
// Append the link to the body and click it programmatically
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// Remove the link from the body
|
||||||
|
document.body.removeChild(a);
|
||||||
|
|
||||||
|
// Revoke the URL to release memory
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Dropdown
|
||||||
|
on:change={(e) => {
|
||||||
|
if (e.detail === false) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<div slot="content">
|
||||||
|
<DropdownMenu.Content
|
||||||
|
class="w-full max-w-[200px] rounded-lg px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-900 dark:text-white shadow-lg"
|
||||||
|
sideOffset={8}
|
||||||
|
side="bottom"
|
||||||
|
align="end"
|
||||||
|
transition={flyAndScale}
|
||||||
|
>
|
||||||
|
<DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer dark:hover:bg-gray-850 rounded-md"
|
||||||
|
on:click={async () => {
|
||||||
|
await showSettings.set(!$showSettings);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<div class="flex items-center">Settings</div>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
|
{#if shareEnabled}
|
||||||
|
<DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer dark:hover:bg-gray-850 rounded-md"
|
||||||
|
on:click={() => {
|
||||||
|
shareHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="currentColor"
|
||||||
|
class="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M15.75 4.5a3 3 0 1 1 .825 2.066l-8.421 4.679a3.002 3.002 0 0 1 0 1.51l8.421 4.679a3 3 0 1 1-.729 1.31l-8.421-4.678a3 3 0 1 1 0-4.132l8.421-4.679a3 3 0 0 1-.096-.755Z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<div class="flex items-center">Share</div>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
|
<!-- <DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer"
|
||||||
|
on:click={() => {
|
||||||
|
downloadHandler();
|
||||||
|
}}
|
||||||
|
/> -->
|
||||||
|
<DropdownMenu.Sub>
|
||||||
|
<DropdownMenu.SubTrigger
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer dark:hover:bg-gray-850 rounded-md"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class="flex items-center">Download</div>
|
||||||
|
</DropdownMenu.SubTrigger>
|
||||||
|
<DropdownMenu.SubContent
|
||||||
|
class="w-full rounded-lg px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-900 dark:text-white shadow-lg"
|
||||||
|
transition={flyAndScale}
|
||||||
|
sideOffset={8}
|
||||||
|
>
|
||||||
|
<DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer dark:hover:bg-gray-850 rounded-md"
|
||||||
|
on:click={() => {
|
||||||
|
downloadTxt();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="flex items-center line-clamp-1">Plain text (.txt)</div>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
|
||||||
|
<DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer dark:hover:bg-gray-850 rounded-md"
|
||||||
|
on:click={() => {
|
||||||
|
downloadPdf();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="flex items-center line-clamp-1">PDF document (.pdf)</div>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
</DropdownMenu.SubContent>
|
||||||
|
</DropdownMenu.Sub>
|
||||||
|
|
||||||
|
<hr class="border-gray-100 dark:border-gray-800 mt-2.5 mb-1.5" />
|
||||||
|
|
||||||
|
<div class="flex p-1">
|
||||||
|
<Tags {tags} {deleteTag} {addTag} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <DropdownMenu.Item
|
||||||
|
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer"
|
||||||
|
on:click={() => {
|
||||||
|
tagHandler();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z"
|
||||||
|
/>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class="flex items-center">Tag</div>
|
||||||
|
</DropdownMenu.Item> -->
|
||||||
|
{/if}
|
||||||
|
</DropdownMenu.Content>
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
|
@ -107,7 +107,7 @@
|
||||||
bind:this={navElement}
|
bind:this={navElement}
|
||||||
class="h-screen max-h-[100dvh] min-h-screen {show
|
class="h-screen max-h-[100dvh] min-h-screen {show
|
||||||
? 'lg:relative w-[260px]'
|
? 'lg:relative w-[260px]'
|
||||||
: '-translate-x-[260px] w-[0px]'} bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-200 text-sm transition z-40 fixed top-0 left-0
|
: '-translate-x-[260px] w-[0px]'} bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-200 text-sm transition fixed z-50 top-0 left-0
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -581,7 +581,7 @@
|
||||||
<div class="py-2 w-full">
|
<div class="py-2 w-full">
|
||||||
{#if $user.role === 'admin'}
|
{#if $user.role === 'admin'}
|
||||||
<button
|
<button
|
||||||
class="flex py-2.5 px-3.5 w-full dark:hover:bg-gray-800 transition"
|
class="flex py-2.5 px-3.5 w-full hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
goto('/admin');
|
goto('/admin');
|
||||||
showDropdown = false;
|
showDropdown = false;
|
||||||
|
@ -607,7 +607,7 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="flex py-2.5 px-3.5 w-full dark:hover:bg-gray-800 transition"
|
class="flex py-2.5 px-3.5 w-full hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
goto('/playground');
|
goto('/playground');
|
||||||
showDropdown = false;
|
showDropdown = false;
|
||||||
|
@ -634,7 +634,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="flex py-2.5 px-3.5 w-full dark:hover:bg-gray-800 transition"
|
class="flex py-2.5 px-3.5 w-full hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
||||||
on:click={async () => {
|
on:click={async () => {
|
||||||
await showSettings.set(true);
|
await showSettings.set(true);
|
||||||
showDropdown = false;
|
showDropdown = false;
|
||||||
|
@ -669,7 +669,7 @@
|
||||||
|
|
||||||
<div class="py-2 w-full">
|
<div class="py-2 w-full">
|
||||||
<button
|
<button
|
||||||
class="flex py-2.5 px-3.5 w-full dark:hover:bg-gray-800 transition"
|
class="flex py-2.5 px-3.5 w-full hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
location.href = '/auth';
|
location.href = '/auth';
|
||||||
|
@ -706,7 +706,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="fixed left-0 top-[50dvh] z-40 -translate-y-1/2 transition-transform translate-x-[255px] md:translate-x-[260px] rotate-0"
|
class="fixed left-0 top-[50dvh] -translate-y-1/2 transition-transform translate-x-[255px] md:translate-x-[260px] rotate-0"
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
placement="right"
|
placement="right"
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const SUPPORTED_FILE_TYPE = [
|
||||||
'text/plain',
|
'text/plain',
|
||||||
'text/csv',
|
'text/csv',
|
||||||
'text/xml',
|
'text/xml',
|
||||||
|
'text/html',
|
||||||
'text/x-python',
|
'text/x-python',
|
||||||
'text/css',
|
'text/css',
|
||||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
@ -50,6 +51,8 @@ export const SUPPORTED_FILE_EXTENSIONS = [
|
||||||
'h',
|
'h',
|
||||||
'c',
|
'c',
|
||||||
'cs',
|
'cs',
|
||||||
|
'htm',
|
||||||
|
'html',
|
||||||
'sql',
|
'sql',
|
||||||
'log',
|
'log',
|
||||||
'ini',
|
'ini',
|
||||||
|
|
|
@ -37,30 +37,36 @@ const createIsLoadingStore = (i18n: i18nType) => {
|
||||||
return isLoading;
|
return isLoading;
|
||||||
};
|
};
|
||||||
|
|
||||||
i18next
|
export const initI18n = (defaultLocale: string) => {
|
||||||
.use(
|
let detectionOrder = defaultLocale
|
||||||
resourcesToBackend(
|
? ['querystring', 'localStorage']
|
||||||
(language: string, namespace: string) => import(`./locales/${language}/${namespace}.json`)
|
: ['querystring', 'localStorage', 'navigator'];
|
||||||
)
|
let fallbackDefaultLocale = defaultLocale ? [defaultLocale] : ['en-US'];
|
||||||
)
|
|
||||||
.use(LanguageDetector)
|
const loadResource = (language: string, namespace: string) =>
|
||||||
.init({
|
import(`./locales/${language}/${namespace}.json`);
|
||||||
debug: false,
|
|
||||||
detection: {
|
i18next
|
||||||
order: ['querystring', 'localStorage', 'navigator'],
|
.use(resourcesToBackend(loadResource))
|
||||||
caches: ['localStorage'],
|
.use(LanguageDetector)
|
||||||
lookupQuerystring: 'lang',
|
.init({
|
||||||
lookupLocalStorage: 'locale'
|
debug: false,
|
||||||
},
|
detection: {
|
||||||
fallbackLng: {
|
order: detectionOrder,
|
||||||
default: ['en-US']
|
caches: ['localStorage'],
|
||||||
},
|
lookupQuerystring: 'lang',
|
||||||
ns: 'translation',
|
lookupLocalStorage: 'locale'
|
||||||
returnEmptyString: false,
|
},
|
||||||
interpolation: {
|
fallbackLng: {
|
||||||
escapeValue: false // not needed for svelte as it escapes by default
|
default: fallbackDefaultLocale
|
||||||
}
|
},
|
||||||
});
|
ns: 'translation',
|
||||||
|
returnEmptyString: false,
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false // not needed for svelte as it escapes by default
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const i18n = createI18nStore(i18next);
|
const i18n = createI18nStore(i18next);
|
||||||
const isLoadingStore = createIsLoadingStore(i18next);
|
const isLoadingStore = createIsLoadingStore(i18next);
|
||||||
|
|
|
@ -279,7 +279,7 @@
|
||||||
"Send a Message": "Изпращане на Съобщение",
|
"Send a Message": "Изпращане на Съобщение",
|
||||||
"Send message": "Изпращане на съобщение",
|
"Send message": "Изпращане на съобщение",
|
||||||
"Server connection verified": "Server connection verified",
|
"Server connection verified": "Server connection verified",
|
||||||
"Set as default": "Задай като по подразбиране",
|
"Set as default": "Задай по подразбиране",
|
||||||
"Set Default Model": "Задай Модел По Подразбиране",
|
"Set Default Model": "Задай Модел По Подразбиране",
|
||||||
"Set Image Size": "Задай Размер на Изображението",
|
"Set Image Size": "Задай Размер на Изображението",
|
||||||
"Set Steps": "Задай Стъпки",
|
"Set Steps": "Задай Стъпки",
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
"Title": "Заглавие",
|
"Title": "Заглавие",
|
||||||
"Title Auto-Generation": "Автоматично Генериране на Заглавие",
|
"Title Auto-Generation": "Автоматично Генериране на Заглавие",
|
||||||
"Title Generation Prompt": "Промпт за Генериране на Заглавие",
|
"Title Generation Prompt": "Промпт за Генериране на Заглавие",
|
||||||
"to": "до",
|
"to": "в",
|
||||||
"To access the available model names for downloading,": "За да получите достъп до наличните имена на модели за изтегляне,",
|
"To access the available model names for downloading,": "За да получите достъп до наличните имена на модели за изтегляне,",
|
||||||
"To access the GGUF models available for downloading,": "За да получите достъп до GGUF моделите, налични за изтегляне,",
|
"To access the GGUF models available for downloading,": "За да получите достъп до GGUF моделите, налични за изтегляне,",
|
||||||
"to chat input.": "към чат входа.",
|
"to chat input.": "към чат входа.",
|
||||||
|
@ -360,4 +360,4 @@
|
||||||
"You": "Вие",
|
"You": "Вие",
|
||||||
"You're a helpful assistant.": "Вие сте полезен асистент.",
|
"You're a helpful assistant.": "Вие сте полезен асистент.",
|
||||||
"You're now logged in.": "Сега, вие влязохте в системата."
|
"You're now logged in.": "Сега, вие влязохте в системата."
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,4 +360,4 @@
|
||||||
"You": "Tu",
|
"You": "Tu",
|
||||||
"You're a helpful assistant.": "Ets un assistent útil.",
|
"You're a helpful assistant.": "Ets un assistent útil.",
|
||||||
"You're now logged in.": "Ara estàs connectat."
|
"You're now logged in.": "Ara estàs connectat."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,128 +1,128 @@
|
||||||
{
|
{
|
||||||
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.",
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "",
|
||||||
"(Beta)": "(Beta)",
|
"(Beta)": "",
|
||||||
"(e.g. `sh webui.sh --api`)": "(e.g. `sh webui.sh --api`)",
|
"(e.g. `sh webui.sh --api`)": "",
|
||||||
"(latest)": "(latest)",
|
"(latest)": "",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} is thinking...",
|
"{{modelName}} is thinking...": "",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} Backend Required",
|
"{{webUIName}} Backend Required": "",
|
||||||
"a user": "",
|
"a user": "",
|
||||||
"About": "About",
|
"About": "",
|
||||||
"Account": "Account",
|
"Account": "",
|
||||||
"Action": "Action",
|
"Action": "",
|
||||||
"Add a model": "Add a model",
|
"Add a model": "",
|
||||||
"Add a model tag name": "Add a model tag name",
|
"Add a model tag name": "",
|
||||||
"Add a short description about what this modelfile does": "Add a short description about what this modelfile does",
|
"Add a short description about what this modelfile does": "",
|
||||||
"Add a short title for this prompt": "Add a short title for this prompt",
|
"Add a short title for this prompt": "",
|
||||||
"Add a tag": "Add a tag",
|
"Add a tag": "",
|
||||||
"Add Docs": "Add Docs",
|
"Add Docs": "",
|
||||||
"Add Files": "Add Files",
|
"Add Files": "",
|
||||||
"Add message": "Add message",
|
"Add message": "",
|
||||||
"add tags": "add tags",
|
"add tags": "",
|
||||||
"Adjusting these settings will apply changes universally to all users.": "Adjusting these settings will apply changes universally to all users.",
|
"Adjusting these settings will apply changes universally to all users.": "",
|
||||||
"admin": "admin",
|
"admin": "",
|
||||||
"Admin Panel": "Admin Panel",
|
"Admin Panel": "",
|
||||||
"Admin Settings": "Admin Settings",
|
"Admin Settings": "",
|
||||||
"Advanced Parameters": "Advanced Parameters",
|
"Advanced Parameters": "",
|
||||||
"all": "all",
|
"all": "",
|
||||||
"All Users": "All Users",
|
"All Users": "",
|
||||||
"Allow": "Allow",
|
"Allow": "",
|
||||||
"Allow Chat Deletion": "Allow Chat Deletion",
|
"Allow Chat Deletion": "",
|
||||||
"alphanumeric characters and hyphens": "alphanumeric characters and hyphens",
|
"alphanumeric characters and hyphens": "",
|
||||||
"Already have an account?": "Already have an account?",
|
"Already have an account?": "",
|
||||||
"an assistant": "",
|
"an assistant": "",
|
||||||
"and": "and",
|
"and": "",
|
||||||
"API Base URL": "API Base URL",
|
"API Base URL": "",
|
||||||
"API Key": "API Key",
|
"API Key": "",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "",
|
||||||
"are allowed - Activate this command by typing": "are allowed - Activate this command by typing",
|
"are allowed - Activate this command by typing": "",
|
||||||
"Are you sure?": "",
|
"Are you sure?": "",
|
||||||
"Audio": "Audio",
|
"Audio": "",
|
||||||
"Auto-playback response": "Auto-playback response",
|
"Auto-playback response": "",
|
||||||
"Auto-send input after 3 sec.": "Auto-send input after 3 sec.",
|
"Auto-send input after 3 sec.": "",
|
||||||
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
|
"AUTOMATIC1111 Base URL": "",
|
||||||
"AUTOMATIC1111 Base URL is required.": "",
|
"AUTOMATIC1111 Base URL is required.": "",
|
||||||
"available!": "available!",
|
"available!": "",
|
||||||
"Back": "Back",
|
"Back": "",
|
||||||
"Builder Mode": "Builder Mode",
|
"Builder Mode": "",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "",
|
||||||
"Categories": "Categories",
|
"Categories": "",
|
||||||
"Change Password": "Change Password",
|
"Change Password": "",
|
||||||
"Chat": "Chat",
|
"Chat": "",
|
||||||
"Chat History": "Chat History",
|
"Chat History": "",
|
||||||
"Chat History is off for this browser.": "Chat History is off for this browser.",
|
"Chat History is off for this browser.": "",
|
||||||
"Chats": "Chats",
|
"Chats": "",
|
||||||
"Check Again": "Check Again",
|
"Check Again": "",
|
||||||
"Check for updates": "Check for updates",
|
"Check for updates": "",
|
||||||
"Checking for updates...": "Checking for updates...",
|
"Checking for updates...": "",
|
||||||
"Choose a model before saving...": "Choose a model before saving...",
|
"Choose a model before saving...": "",
|
||||||
"Chunk Overlap": "Chunk Overlap",
|
"Chunk Overlap": "",
|
||||||
"Chunk Params": "Chunk Params",
|
"Chunk Params": "",
|
||||||
"Chunk Size": "Chunk Size",
|
"Chunk Size": "",
|
||||||
"Click here for help.": "Click here for help.",
|
"Click here for help.": "",
|
||||||
"Click here to check other modelfiles.": "Click here to check other modelfiles.",
|
"Click here to check other modelfiles.": "",
|
||||||
"Click here to select": "",
|
"Click here to select": "",
|
||||||
"Click here to select documents.": "",
|
"Click here to select documents.": "",
|
||||||
"click here.": "click here.",
|
"click here.": "",
|
||||||
"Click on the user role button to change a user's role.": "Click on the user role button to change a user's role.",
|
"Click on the user role button to change a user's role.": "",
|
||||||
"Close": "Close",
|
"Close": "",
|
||||||
"Collection": "Collection",
|
"Collection": "",
|
||||||
"Command": "Command",
|
"Command": "",
|
||||||
"Confirm Password": "Confirm Password",
|
"Confirm Password": "",
|
||||||
"Connections": "Connections",
|
"Connections": "",
|
||||||
"Content": "Content",
|
"Content": "",
|
||||||
"Context Length": "Context Length",
|
"Context Length": "",
|
||||||
"Conversation Mode": "Conversation Mode",
|
"Conversation Mode": "",
|
||||||
"Copy last code block": "Copy last code block",
|
"Copy last code block": "",
|
||||||
"Copy last response": "Copy last response",
|
"Copy last response": "",
|
||||||
"Copying to clipboard was successful!": "Copying to clipboard was successful!",
|
"Copying to clipboard was successful!": "",
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':",
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "",
|
||||||
"Create a modelfile": "Create a modelfile",
|
"Create a modelfile": "",
|
||||||
"Create Account": "Create Account",
|
"Create Account": "",
|
||||||
"Created at": "Created at",
|
"Created at": "",
|
||||||
"Created by": "Created by",
|
"Created by": "",
|
||||||
"Current Model": "Current Model",
|
"Current Model": "",
|
||||||
"Current Password": "Current Password",
|
"Current Password": "",
|
||||||
"Custom": "Custom",
|
"Custom": "",
|
||||||
"Customize Ollama models for a specific purpose": "Customize Ollama models for a specific purpose",
|
"Customize Ollama models for a specific purpose": "",
|
||||||
"Dark": "Dark",
|
"Dark": "",
|
||||||
"Database": "Database",
|
"Database": "",
|
||||||
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
"DD/MM/YYYY HH:mm": "",
|
||||||
"Default": "Default",
|
"Default": "",
|
||||||
"Default (Automatic1111)": "",
|
"Default (Automatic1111)": "",
|
||||||
"Default (Web API)": "Default (Web API)",
|
"Default (Web API)": "",
|
||||||
"Default model updated": "Default model updated",
|
"Default model updated": "",
|
||||||
"Default Prompt Suggestions": "Default Prompt Suggestions",
|
"Default Prompt Suggestions": "",
|
||||||
"Default User Role": "Default User Role",
|
"Default User Role": "",
|
||||||
"delete": "delete",
|
"delete": "",
|
||||||
"Delete a model": "Delete a model",
|
"Delete a model": "",
|
||||||
"Delete chat": "Delete chat",
|
"Delete chat": "",
|
||||||
"Delete Chats": "Delete Chats",
|
"Delete Chats": "",
|
||||||
"Deleted {{deleteModelTag}}": "Deleted {{deleteModelTag}}",
|
"Deleted {{deleteModelTag}}": "",
|
||||||
"Deleted {tagName}": "Deleted {tagName}",
|
"Deleted {tagName}": "",
|
||||||
"Description": "Description",
|
"Description": "",
|
||||||
"Desktop Notifications": "Notification",
|
"Desktop Notifications": "",
|
||||||
"Disabled": "Disabled",
|
"Disabled": "",
|
||||||
"Discover a modelfile": "Discover a modelfile",
|
"Discover a modelfile": "",
|
||||||
"Discover a prompt": "Discover a prompt",
|
"Discover a prompt": "",
|
||||||
"Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts",
|
"Discover, download, and explore custom prompts": "",
|
||||||
"Discover, download, and explore model presets": "Discover, download, and explore model presets",
|
"Discover, download, and explore model presets": "",
|
||||||
"Display the username instead of You in the Chat": "Display the username instead of 'You' in the Chat",
|
"Display the username instead of You in the Chat": "",
|
||||||
"Document": "Document",
|
"Document": "",
|
||||||
"Document Settings": "Document Settings",
|
"Document Settings": "",
|
||||||
"Documents": "Documents",
|
"Documents": "",
|
||||||
"does not make any external connections, and your data stays securely on your locally hosted server.": "does not make any external connections, and your data stays securely on your locally hosted server.",
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "",
|
||||||
"Don't Allow": "Don't Allow",
|
"Don't Allow": "",
|
||||||
"Don't have an account?": "Don't have an account?",
|
"Don't have an account?": "",
|
||||||
"Download as a File": "Download as a File",
|
"Download as a File": "",
|
||||||
"Download Database": "Download Database",
|
"Download Database": "",
|
||||||
"Drop any files here to add to the conversation": "Drop any files here to add to the conversation",
|
"Drop any files here to add to the conversation": "",
|
||||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.",
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "",
|
||||||
"Edit Doc": "Edit Doc",
|
"Edit Doc": "",
|
||||||
"Edit User": "Edit User",
|
"Edit User": "",
|
||||||
"Email": "Email",
|
"Email": "",
|
||||||
"Enable Chat History": "Enable Chat History",
|
"Enable Chat History": "",
|
||||||
"Enable New Sign Ups": "Enable New Sign Ups",
|
"Enable New Sign Ups": "",
|
||||||
"Enabled": "Enabled",
|
"Enabled": "",
|
||||||
"Enter {{role}} message here": "",
|
"Enter {{role}} message here": "",
|
||||||
"Enter API Key": "",
|
"Enter API Key": "",
|
||||||
"Enter Chunk Overlap": "",
|
"Enter Chunk Overlap": "",
|
||||||
|
@ -135,229 +135,229 @@
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "",
|
"Enter Max Tokens (litellm_params.max_tokens)": "",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "",
|
"Enter model tag (e.g. {{modelTag}})": "",
|
||||||
"Enter Number of Steps (e.g. 50)": "",
|
"Enter Number of Steps (e.g. 50)": "",
|
||||||
"Enter stop sequence": "Enter stop sequence",
|
"Enter stop sequence": "",
|
||||||
"Enter Top K": "",
|
"Enter Top K": "",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "",
|
||||||
"Enter Your Email": "Enter Your Email",
|
"Enter Your Email": "",
|
||||||
"Enter Your Full Name": "Enter Your Full Name",
|
"Enter Your Full Name": "",
|
||||||
"Enter Your Password": "Enter Your Password",
|
"Enter Your Password": "",
|
||||||
"Experimental": "Experimental",
|
"Experimental": "",
|
||||||
"Export All Chats (All Users)": "Export All Chats (All Users)",
|
"Export All Chats (All Users)": "",
|
||||||
"Export Chats": "Export Chats",
|
"Export Chats": "",
|
||||||
"Export Documents Mapping": "Export Documents Mapping",
|
"Export Documents Mapping": "",
|
||||||
"Export Modelfiles": "Export Modelfiles",
|
"Export Modelfiles": "",
|
||||||
"Export Prompts": "Export Prompts",
|
"Export Prompts": "",
|
||||||
"Failed to read clipboard contents": "Failed to read clipboard contents",
|
"Failed to read clipboard contents": "",
|
||||||
"File Mode": "File Mode",
|
"File Mode": "",
|
||||||
"File not found.": "File not found.",
|
"File not found.": "",
|
||||||
"Focus chat input": "Focus chat input",
|
"Focus chat input": "",
|
||||||
"Format your variables using square brackets like this:": "Format your variables using square brackets like this:",
|
"Format your variables using square brackets like this:": "",
|
||||||
"From (Base Model)": "From (Base Model)",
|
"From (Base Model)": "",
|
||||||
"Full Screen Mode": "Full Screen Mode",
|
"Full Screen Mode": "",
|
||||||
"General": "General",
|
"General": "",
|
||||||
"General Settings": "General Settings",
|
"General Settings": "",
|
||||||
"Hello, {{name}}": "Hello, {{name}}",
|
"Hello, {{name}}": "",
|
||||||
"Hide": "Hide",
|
"Hide": "",
|
||||||
"Hide Additional Params": "Hide Additional Params",
|
"Hide Additional Params": "",
|
||||||
"How can I help you today?": "How can I help you today?",
|
"How can I help you today?": "",
|
||||||
"Image Generation (Experimental)": "Image Generation (Experimental)",
|
"Image Generation (Experimental)": "",
|
||||||
"Image Generation Engine": "",
|
"Image Generation Engine": "",
|
||||||
"Image Settings": "Image Settings",
|
"Image Settings": "",
|
||||||
"Images": "Images",
|
"Images": "",
|
||||||
"Import Chats": "Import Chats",
|
"Import Chats": "",
|
||||||
"Import Documents Mapping": "Import Documents Mapping",
|
"Import Documents Mapping": "",
|
||||||
"Import Modelfiles": "Import Modelfiles",
|
"Import Modelfiles": "",
|
||||||
"Import Prompts": "Import Prompts",
|
"Import Prompts": "",
|
||||||
"Include `--api` flag when running stable-diffusion-webui": "Include `--api` flag when running stable-diffusion-webui",
|
"Include `--api` flag when running stable-diffusion-webui": "",
|
||||||
"Interface": "Interface",
|
"Interface": "",
|
||||||
"join our Discord for help.": "join our Discord for help.",
|
"join our Discord for help.": "",
|
||||||
"JSON": "JSON",
|
"JSON": "",
|
||||||
"JWT Expiration": "JWT Expiration",
|
"JWT Expiration": "",
|
||||||
"JWT Token": "JWT Token",
|
"JWT Token": "",
|
||||||
"Keep Alive": "Keep Alive",
|
"Keep Alive": "",
|
||||||
"Keyboard shortcuts": "Keyboard shortcuts",
|
"Keyboard shortcuts": "",
|
||||||
"Language": "Language",
|
"Language": "",
|
||||||
"Light": "Light",
|
"Light": "",
|
||||||
"Listening...": "Listening...",
|
"Listening...": "",
|
||||||
"LLMs can make mistakes. Verify important information.": "LLMs can make mistakes. Verify important information.",
|
"LLMs can make mistakes. Verify important information.": "",
|
||||||
"Made by OpenWebUI Community": "Made by OpenWebUI Community",
|
"Made by OpenWebUI Community": "",
|
||||||
"Make sure to enclose them with": "Make sure to enclose them with",
|
"Make sure to enclose them with": "",
|
||||||
"Manage LiteLLM Models": "Manage LiteLLM Models",
|
"Manage LiteLLM Models": "",
|
||||||
"Manage Models": "Manage Models",
|
"Manage Models": "",
|
||||||
"Manage Ollama Models": "Manage Ollama Models",
|
"Manage Ollama Models": "",
|
||||||
"Max Tokens": "Max Tokens",
|
"Max Tokens": "",
|
||||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximum of 3 models can be downloaded simultaneously. Please try again later.",
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
|
||||||
"Mirostat": "Mirostat",
|
"Mirostat": "",
|
||||||
"Mirostat Eta": "Mirostat Eta",
|
"Mirostat Eta": "",
|
||||||
"Mirostat Tau": "Mirostat Tau",
|
"Mirostat Tau": "",
|
||||||
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
"MMMM DD, YYYY": "",
|
||||||
"Model '{{modelName}}' has been successfully downloaded.": "Model '{{modelName}}' has been successfully downloaded.",
|
"Model '{{modelName}}' has been successfully downloaded.": "",
|
||||||
"Model '{{modelTag}}' is already in queue for downloading.": "Model '{{modelTag}}' is already in queue for downloading.",
|
"Model '{{modelTag}}' is already in queue for downloading.": "",
|
||||||
"Model {{modelId}} not found": "Model {{modelId}} not found",
|
"Model {{modelId}} not found": "",
|
||||||
"Model {{modelName}} already exists.": "Model {{modelName}} already exists.",
|
"Model {{modelName}} already exists.": "",
|
||||||
"Model Name": "Model Name",
|
"Model Name": "",
|
||||||
"Model not selected": "Model not selected",
|
"Model not selected": "",
|
||||||
"Model Tag Name": "Model Tag Name",
|
"Model Tag Name": "",
|
||||||
"Model Whitelisting": "Model Whitelisting",
|
"Model Whitelisting": "",
|
||||||
"Model(s) Whitelisted": "Model(s) Whitelisted",
|
"Model(s) Whitelisted": "",
|
||||||
"Modelfile": "Modelfile",
|
"Modelfile": "",
|
||||||
"Modelfile Advanced Settings": "Modelfile Advanced Settings",
|
"Modelfile Advanced Settings": "",
|
||||||
"Modelfile Content": "Modelfile Content",
|
"Modelfile Content": "",
|
||||||
"Modelfiles": "Modelfiles",
|
"Modelfiles": "",
|
||||||
"Models": "Models",
|
"Models": "",
|
||||||
"My Documents": "My Documents",
|
"My Documents": "",
|
||||||
"My Modelfiles": "My Modelfiles",
|
"My Modelfiles": "",
|
||||||
"My Prompts": "My Prompts",
|
"My Prompts": "",
|
||||||
"Name": "Name",
|
"Name": "",
|
||||||
"Name Tag": "Name Tag",
|
"Name Tag": "",
|
||||||
"Name your modelfile": "Name your modelfile",
|
"Name your modelfile": "",
|
||||||
"New Chat": "New Chat",
|
"New Chat": "",
|
||||||
"New Password": "New Password",
|
"New Password": "",
|
||||||
"Not sure what to add?": "Not sure what to add?",
|
"Not sure what to add?": "",
|
||||||
"Not sure what to write? Switch to": "Not sure what to write? Switch to",
|
"Not sure what to write? Switch to": "",
|
||||||
"Off": "Off",
|
"Off": "",
|
||||||
"Okay, Let's Go!": "Okay, Let's Go!",
|
"Okay, Let's Go!": "",
|
||||||
"Ollama Base URL": "",
|
"Ollama Base URL": "",
|
||||||
"Ollama Version": "Ollama Version",
|
"Ollama Version": "",
|
||||||
"On": "On",
|
"On": "",
|
||||||
"Only": "Only",
|
"Only": "",
|
||||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Only alphanumeric characters and hyphens are allowed in the command string.",
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "",
|
||||||
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.",
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "",
|
||||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Oops! Looks like the URL is invalid. Please double-check and try again.",
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "",
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "",
|
||||||
"Open": "Open",
|
"Open": "",
|
||||||
"Open AI": "Open AI",
|
"Open AI": "",
|
||||||
"Open AI (Dall-E)": "",
|
"Open AI (Dall-E)": "",
|
||||||
"Open new chat": "Open new chat",
|
"Open new chat": "",
|
||||||
"OpenAI API": "OpenAI API",
|
"OpenAI API": "",
|
||||||
"OpenAI API Key": "",
|
"OpenAI API Key": "",
|
||||||
"OpenAI API Key is required.": "",
|
"OpenAI API Key is required.": "",
|
||||||
"or": "or",
|
"or": "",
|
||||||
"Parameters": "Parameters",
|
"Parameters": "",
|
||||||
"Password": "Password",
|
"Password": "",
|
||||||
"PDF Extract Images (OCR)": "PDF Extract Images (OCR)",
|
"PDF Extract Images (OCR)": "",
|
||||||
"pending": "pending",
|
"pending": "",
|
||||||
"Permission denied when accessing microphone: {{error}}": "Permission denied when accessing microphone: {{error}}",
|
"Permission denied when accessing microphone: {{error}}": "",
|
||||||
"Playground": "Playground",
|
"Playground": "",
|
||||||
"Profile": "Profile",
|
"Profile": "",
|
||||||
"Prompt Content": "Prompt Content",
|
"Prompt Content": "",
|
||||||
"Prompt suggestions": "Prompt suggestions",
|
"Prompt suggestions": "",
|
||||||
"Prompts": "Prompts",
|
"Prompts": "",
|
||||||
"Pull a model from Ollama.com": "Pull a model from Ollama.com",
|
"Pull a model from Ollama.com": "",
|
||||||
"Pull Progress": "Pull Progress",
|
"Pull Progress": "",
|
||||||
"Query Params": "Query Params",
|
"Query Params": "",
|
||||||
"RAG Template": "RAG Template",
|
"RAG Template": "",
|
||||||
"Raw Format": "Raw Format",
|
"Raw Format": "",
|
||||||
"Record voice": "Record voice",
|
"Record voice": "",
|
||||||
"Redirecting you to OpenWebUI Community": "Redirecting you to OpenWebUI Community",
|
"Redirecting you to OpenWebUI Community": "",
|
||||||
"Release Notes": "Release Notes",
|
"Release Notes": "",
|
||||||
"Repeat Last N": "Repeat Last N",
|
"Repeat Last N": "",
|
||||||
"Repeat Penalty": "Repeat Penalty",
|
"Repeat Penalty": "",
|
||||||
"Request Mode": "Request Mode",
|
"Request Mode": "",
|
||||||
"Reset Vector Storage": "Reset Vector Storage",
|
"Reset Vector Storage": "",
|
||||||
"Response AutoCopy to Clipboard": "Response AutoCopy to Clipboard",
|
"Response AutoCopy to Clipboard": "",
|
||||||
"Role": "Role",
|
"Role": "",
|
||||||
"Rosé Pine": "Rosé Pine",
|
"Rosé Pine": "",
|
||||||
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
"Rosé Pine Dawn": "",
|
||||||
"Save": "Save",
|
"Save": "",
|
||||||
"Save & Create": "Save & Create",
|
"Save & Create": "",
|
||||||
"Save & Submit": "Save & Submit",
|
"Save & Submit": "",
|
||||||
"Save & Update": "Save & Update",
|
"Save & Update": "",
|
||||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through",
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "",
|
||||||
"Scan": "Scan",
|
"Scan": "",
|
||||||
"Scan complete!": "Scan complete!",
|
"Scan complete!": "",
|
||||||
"Scan for documents from {{path}}": "Scan for documents from {{path}}",
|
"Scan for documents from {{path}}": "",
|
||||||
"Search": "Search",
|
"Search": "",
|
||||||
"Search Documents": "Search Documents",
|
"Search Documents": "",
|
||||||
"Search Prompts": "Search Prompts",
|
"Search Prompts": "",
|
||||||
"See readme.md for instructions": "See readme.md for instructions",
|
"See readme.md for instructions": "",
|
||||||
"See what's new": "See what's new",
|
"See what's new": "",
|
||||||
"Seed": "Seed",
|
"Seed": "",
|
||||||
"Select a mode": "",
|
"Select a mode": "",
|
||||||
"Select a model": "Select a model",
|
"Select a model": "",
|
||||||
"Select an Ollama instance": "",
|
"Select an Ollama instance": "",
|
||||||
"Send a Message": "Send a Message",
|
"Send a Message": "",
|
||||||
"Send message": "Send message",
|
"Send message": "",
|
||||||
"Server connection verified": "Server connection verified",
|
"Server connection verified": "",
|
||||||
"Set as default": "Set as default",
|
"Set as default": "",
|
||||||
"Set Default Model": "Set Default Model",
|
"Set Default Model": "",
|
||||||
"Set Image Size": "Set Image Size",
|
"Set Image Size": "",
|
||||||
"Set Steps": "Set Steps",
|
"Set Steps": "",
|
||||||
"Set Title Auto-Generation Model": "Set Title Auto-Generation Model",
|
"Set Title Auto-Generation Model": "",
|
||||||
"Set Voice": "Set Voice",
|
"Set Voice": "",
|
||||||
"Settings": "Settings",
|
"Settings": "",
|
||||||
"Settings saved successfully!": "Settings saved successfully!",
|
"Settings saved successfully!": "",
|
||||||
"Share to OpenWebUI Community": "Share to OpenWebUI Community",
|
"Share to OpenWebUI Community": "",
|
||||||
"short-summary": "short-summary",
|
"short-summary": "",
|
||||||
"Show": "Show",
|
"Show": "",
|
||||||
"Show Additional Params": "Show Additional Params",
|
"Show Additional Params": "",
|
||||||
"Show shortcuts": "Show shortcuts",
|
"Show shortcuts": "",
|
||||||
"sidebar": "sidebar",
|
"sidebar": "",
|
||||||
"Sign in": "Sign in",
|
"Sign in": "",
|
||||||
"Sign Out": "Sign Out",
|
"Sign Out": "",
|
||||||
"Sign up": "Sign up",
|
"Sign up": "",
|
||||||
"Speech recognition error: {{error}}": "Speech recognition error: {{error}}",
|
"Speech recognition error: {{error}}": "",
|
||||||
"Speech-to-Text Engine": "Speech-to-Text Engine",
|
"Speech-to-Text Engine": "",
|
||||||
"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API is not supported in this browser.",
|
"SpeechRecognition API is not supported in this browser.": "",
|
||||||
"Stop Sequence": "Stop Sequence",
|
"Stop Sequence": "",
|
||||||
"STT Settings": "STT Settings",
|
"STT Settings": "",
|
||||||
"Submit": "Submit",
|
"Submit": "",
|
||||||
"Success": "Success",
|
"Success": "",
|
||||||
"Successfully updated.": "Successfully updated.",
|
"Successfully updated.": "",
|
||||||
"Sync All": "Sync All",
|
"Sync All": "",
|
||||||
"System": "System",
|
"System": "",
|
||||||
"System Prompt": "System Prompt",
|
"System Prompt": "",
|
||||||
"Tags": "Tags",
|
"Tags": "",
|
||||||
"Temperature": "Temperature",
|
"Temperature": "",
|
||||||
"Template": "Template",
|
"Template": "",
|
||||||
"Text Completion": "Text Completion",
|
"Text Completion": "",
|
||||||
"Text-to-Speech Engine": "Text-to-Speech Engine",
|
"Text-to-Speech Engine": "",
|
||||||
"Tfs Z": "Tfs Z",
|
"Tfs Z": "",
|
||||||
"Theme": "Theme",
|
"Theme": "",
|
||||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "This ensures that your valuable conversations are securely saved to your backend database. Thank you!",
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "",
|
||||||
"This setting does not sync across browsers or devices.": "This setting does not sync across browsers or devices.",
|
"This setting does not sync across browsers or devices.": "",
|
||||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.",
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "",
|
||||||
"Title": "Title",
|
"Title": "",
|
||||||
"Title Auto-Generation": "Title Auto-Generation",
|
"Title Auto-Generation": "",
|
||||||
"Title Generation Prompt": "Title Generation Prompt",
|
"Title Generation Prompt": "",
|
||||||
"to": "to",
|
"to": "",
|
||||||
"To access the available model names for downloading,": "To access the available model names for downloading,",
|
"To access the available model names for downloading,": "",
|
||||||
"To access the GGUF models available for downloading,": "To access the GGUF models available for downloading,",
|
"To access the GGUF models available for downloading,": "",
|
||||||
"to chat input.": "to chat input.",
|
"to chat input.": "",
|
||||||
"Toggle settings": "Toggle settings",
|
"Toggle settings": "",
|
||||||
"Toggle sidebar": "Toggle sidebar",
|
"Toggle sidebar": "",
|
||||||
"Top K": "Top K",
|
"Top K": "",
|
||||||
"Top P": "Top P",
|
"Top P": "",
|
||||||
"Trouble accessing Ollama?": "Trouble accessing Ollama?",
|
"Trouble accessing Ollama?": "",
|
||||||
"TTS Settings": "TTS Settings",
|
"TTS Settings": "",
|
||||||
"Type Hugging Face Resolve (Download) URL": "",
|
"Type Hugging Face Resolve (Download) URL": "",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! There was an issue connecting to {{provider}}.",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Unknown File Type '{{file_type}}', but accepting and treating as plain text",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "",
|
||||||
"Update password": "Update password",
|
"Update password": "",
|
||||||
"Upload a GGUF model": "Upload a GGUF model",
|
"Upload a GGUF model": "",
|
||||||
"Upload files": "Upload files",
|
"Upload files": "",
|
||||||
"Upload Progress": "Upload Progress",
|
"Upload Progress": "",
|
||||||
"URL Mode": "URL Mode",
|
"URL Mode": "",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "Use '#' in the prompt input to load and select your documents.",
|
"Use '#' in the prompt input to load and select your documents.": "",
|
||||||
"Use Gravatar": "",
|
"Use Gravatar": "",
|
||||||
"user": "user",
|
"user": "",
|
||||||
"User Permissions": "User Permissions",
|
"User Permissions": "",
|
||||||
"Users": "Users",
|
"Users": "",
|
||||||
"Utilize": "Utilize",
|
"Utilize": "",
|
||||||
"Valid time units:": "Valid time units:",
|
"Valid time units:": "",
|
||||||
"variable": "variable",
|
"variable": "",
|
||||||
"variable to have them replaced with clipboard content.": "variable to have them replaced with clipboard content.",
|
"variable to have them replaced with clipboard content.": "",
|
||||||
"Version": "Version",
|
"Version": "",
|
||||||
"Web": "Web",
|
"Web": "",
|
||||||
"WebUI Add-ons": "WebUI Add-ons",
|
"WebUI Add-ons": "",
|
||||||
"WebUI Settings": "WebUI Settings",
|
"WebUI Settings": "",
|
||||||
"WebUI will make requests to": "WebUI will make requests to",
|
"WebUI will make requests to": "",
|
||||||
"What’s New in": "What’s New in",
|
"What’s New in": "",
|
||||||
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "When history is turned off, new chats on this browser won't appear in your history on any of your devices.",
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "",
|
||||||
"Whisper (Local)": "Whisper (Local)",
|
"Whisper (Local)": "",
|
||||||
"Write a prompt suggestion (e.g. Who are you?)": "Write a prompt suggestion (e.g. Who are you?)",
|
"Write a prompt suggestion (e.g. Who are you?)": "",
|
||||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Write a summary in 50 words that summarizes [topic or keyword].",
|
"Write a summary in 50 words that summarizes [topic or keyword].": "",
|
||||||
"You": "You",
|
"You": "",
|
||||||
"You're a helpful assistant.": "You're a helpful assistant.",
|
"You're a helpful assistant.": "",
|
||||||
"You're now logged in.": "You're now logged in."
|
"You're now logged in.": ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,363 +1,363 @@
|
||||||
{
|
{
|
||||||
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' o '-1' per nessuna scadenza.",
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' o '-1' per nessuna scadenza.",
|
||||||
"(Beta)": "(Beta)",
|
"(Beta)": "(Beta)",
|
||||||
"(e.g. sh webui.sh --api)": "(ad esempio sh webui.sh --api)",
|
"(e.g. sh webui.sh --api)": "(ad esempio sh webui.sh --api)",
|
||||||
"(latest)": "(ultima)",
|
"(latest)": "(ultima)",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} sta pensando...",
|
"{{modelName}} is thinking...": "{{modelName}} sta pensando...",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} Backend richiesto",
|
"{{webUIName}} Backend Required": "{{webUIName}} Backend richiesto",
|
||||||
"a user": "un utente",
|
"a user": "un utente",
|
||||||
"About": "Informazioni",
|
"About": "Informazioni",
|
||||||
"Account": "Account",
|
"Account": "Account",
|
||||||
"Action": "Azione",
|
"Action": "Azione",
|
||||||
"Add a model": "Aggiungi un modello",
|
"Add a model": "Aggiungi un modello",
|
||||||
"Add a model tag name": "Aggiungi un nome tag del modello",
|
"Add a model tag name": "Aggiungi un nome tag del modello",
|
||||||
"Add a short description about what this modelfile does": "Aggiungi una breve descrizione di ciò che fa questo file modello",
|
"Add a short description about what this modelfile does": "Aggiungi una breve descrizione di ciò che fa questo file modello",
|
||||||
"Add a short title for this prompt": "Aggiungi un titolo breve per questo prompt",
|
"Add a short title for this prompt": "Aggiungi un titolo breve per questo prompt",
|
||||||
"Add a tag": "Aggiungi un tag",
|
"Add a tag": "Aggiungi un tag",
|
||||||
"Add Docs": "Aggiungi documenti",
|
"Add Docs": "Aggiungi documenti",
|
||||||
"Add Files": "Aggiungi file",
|
"Add Files": "Aggiungi file",
|
||||||
"Add message": "Aggiungi messaggio",
|
"Add message": "Aggiungi messaggio",
|
||||||
"add tags": "aggiungi tag",
|
"add tags": "aggiungi tag",
|
||||||
"Adjusting these settings will apply changes universally to all users.": "La modifica di queste impostazioni applicherà le modifiche universalmente a tutti gli utenti.",
|
"Adjusting these settings will apply changes universally to all users.": "La modifica di queste impostazioni applicherà le modifiche universalmente a tutti gli utenti.",
|
||||||
"admin": "amministratore",
|
"admin": "amministratore",
|
||||||
"Admin Panel": "Pannello di amministrazione",
|
"Admin Panel": "Pannello di amministrazione",
|
||||||
"Admin Settings": "Impostazioni amministratore",
|
"Admin Settings": "Impostazioni amministratore",
|
||||||
"Advanced Parameters": "Parametri avanzati",
|
"Advanced Parameters": "Parametri avanzati",
|
||||||
"all": "tutti",
|
"all": "tutti",
|
||||||
"All Users": "Tutti gli utenti",
|
"All Users": "Tutti gli utenti",
|
||||||
"Allow": "Consenti",
|
"Allow": "Consenti",
|
||||||
"Allow Chat Deletion": "Consenti l'eliminazione della chat",
|
"Allow Chat Deletion": "Consenti l'eliminazione della chat",
|
||||||
"alphanumeric characters and hyphens": "caratteri alfanumerici e trattini",
|
"alphanumeric characters and hyphens": "caratteri alfanumerici e trattini",
|
||||||
"Already have an account?": "Hai già un account?",
|
"Already have an account?": "Hai già un account?",
|
||||||
"an assistant": "un assistente",
|
"an assistant": "un assistente",
|
||||||
"and": "e",
|
"and": "e",
|
||||||
"API Base URL": "URL base API",
|
"API Base URL": "URL base API",
|
||||||
"API Key": "Chiave API",
|
"API Key": "Chiave API",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "API RPM",
|
||||||
"are allowed - Activate this command by typing": "sono consentiti - Attiva questo comando digitando",
|
"are allowed - Activate this command by typing": "sono consentiti - Attiva questo comando digitando",
|
||||||
"Are you sure?": "Sei sicuro?",
|
"Are you sure?": "Sei sicuro?",
|
||||||
"Audio": "Audio",
|
"Audio": "Audio",
|
||||||
"Auto-playback response": "Riproduzione automatica della risposta",
|
"Auto-playback response": "Riproduzione automatica della risposta",
|
||||||
"Auto-send input after 3 sec.": "Invio automatico dell'input dopo 3 secondi.",
|
"Auto-send input after 3 sec.": "Invio automatico dell'input dopo 3 secondi.",
|
||||||
"AUTOMATIC1111 Base URL": "URL base AUTOMATIC1111",
|
"AUTOMATIC1111 Base URL": "URL base AUTOMATIC1111",
|
||||||
"AUTOMATIC1111 Base URL is required.": "L'URL base AUTOMATIC1111 è obbligatorio.",
|
"AUTOMATIC1111 Base URL is required.": "L'URL base AUTOMATIC1111 è obbligatorio.",
|
||||||
"available!": "disponibile!",
|
"available!": "disponibile!",
|
||||||
"Back": "Indietro",
|
"Back": "Indietro",
|
||||||
"Builder Mode": "Modalità costruttore",
|
"Builder Mode": "Modalità costruttore",
|
||||||
"Cancel": "Annulla",
|
"Cancel": "Annulla",
|
||||||
"Categories": "Categorie",
|
"Categories": "Categorie",
|
||||||
"Change Password": "Cambia password",
|
"Change Password": "Cambia password",
|
||||||
"Chat": "Chat",
|
"Chat": "Chat",
|
||||||
"Chat History": "Cronologia chat",
|
"Chat History": "Cronologia chat",
|
||||||
"Chat History is off for this browser.": "La cronologia chat è disattivata per questo browser.",
|
"Chat History is off for this browser.": "La cronologia chat è disattivata per questo browser.",
|
||||||
"Chats": "Chat",
|
"Chats": "Chat",
|
||||||
"Check Again": "Controlla di nuovo",
|
"Check Again": "Controlla di nuovo",
|
||||||
"Check for updates": "Controlla aggiornamenti",
|
"Check for updates": "Controlla aggiornamenti",
|
||||||
"Checking for updates...": "Controllo aggiornamenti...",
|
"Checking for updates...": "Controllo aggiornamenti...",
|
||||||
"Choose a model before saving...": "Scegli un modello prima di salvare...",
|
"Choose a model before saving...": "Scegli un modello prima di salvare...",
|
||||||
"Chunk Overlap": "Sovrapposizione chunk",
|
"Chunk Overlap": "Sovrapposizione chunk",
|
||||||
"Chunk Params": "Parametri chunk",
|
"Chunk Params": "Parametri chunk",
|
||||||
"Chunk Size": "Dimensione chunk",
|
"Chunk Size": "Dimensione chunk",
|
||||||
"Click here for help.": "Clicca qui per aiuto.",
|
"Click here for help.": "Clicca qui per aiuto.",
|
||||||
"Click here to check other modelfiles.": "Clicca qui per controllare altri file modello.",
|
"Click here to check other modelfiles.": "Clicca qui per controllare altri file modello.",
|
||||||
"Click here to select": "Clicca qui per selezionare",
|
"Click here to select": "Clicca qui per selezionare",
|
||||||
"Click here to select documents.": "Clicca qui per selezionare i documenti.",
|
"Click here to select documents.": "Clicca qui per selezionare i documenti.",
|
||||||
"click here.": "clicca qui.",
|
"click here.": "clicca qui.",
|
||||||
"Click on the user role button to change a user's role.": "Clicca sul pulsante del ruolo utente per modificare il ruolo di un utente.",
|
"Click on the user role button to change a user's role.": "Clicca sul pulsante del ruolo utente per modificare il ruolo di un utente.",
|
||||||
"Close": "Chiudi",
|
"Close": "Chiudi",
|
||||||
"Collection": "Collezione",
|
"Collection": "Collezione",
|
||||||
"Command": "Comando",
|
"Command": "Comando",
|
||||||
"Confirm Password": "Conferma password",
|
"Confirm Password": "Conferma password",
|
||||||
"Connections": "Connessioni",
|
"Connections": "Connessioni",
|
||||||
"Content": "Contenuto",
|
"Content": "Contenuto",
|
||||||
"Context Length": "Lunghezza contesto",
|
"Context Length": "Lunghezza contesto",
|
||||||
"Conversation Mode": "Modalità conversazione",
|
"Conversation Mode": "Modalità conversazione",
|
||||||
"Copy last code block": "Copia ultimo blocco di codice",
|
"Copy last code block": "Copia ultimo blocco di codice",
|
||||||
"Copy last response": "Copia ultima risposta",
|
"Copy last response": "Copia ultima risposta",
|
||||||
"Copying to clipboard was successful!": "Copia negli appunti riuscita!",
|
"Copying to clipboard was successful!": "Copia negli appunti riuscita!",
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crea una frase concisa di 3-5 parole come intestazione per la seguente query, aderendo rigorosamente al limite di 3-5 parole ed evitando l'uso della parola 'titolo':",
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crea una frase concisa di 3-5 parole come intestazione per la seguente query, aderendo rigorosamente al limite di 3-5 parole ed evitando l'uso della parola 'titolo':",
|
||||||
"Create a modelfile": "Crea un file modello",
|
"Create a modelfile": "Crea un file modello",
|
||||||
"Create Account": "Crea account",
|
"Create Account": "Crea account",
|
||||||
"Created at": "Creato il",
|
"Created at": "Creato il",
|
||||||
"Created by": "Creato da",
|
"Created by": "Creato da",
|
||||||
"Current Model": "Modello corrente",
|
"Current Model": "Modello corrente",
|
||||||
"Current Password": "Password corrente",
|
"Current Password": "Password corrente",
|
||||||
"Custom": "Personalizzato",
|
"Custom": "Personalizzato",
|
||||||
"Customize Ollama models for a specific purpose": "Personalizza i modelli Ollama per uno scopo specifico",
|
"Customize Ollama models for a specific purpose": "Personalizza i modelli Ollama per uno scopo specifico",
|
||||||
"Dark": "Scuro",
|
"Dark": "Scuro",
|
||||||
"Database": "Database",
|
"Database": "Database",
|
||||||
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
||||||
"Default": "Predefinito",
|
"Default": "Predefinito",
|
||||||
"Default (Automatic1111)": "Predefinito (Automatic1111)",
|
"Default (Automatic1111)": "Predefinito (Automatic1111)",
|
||||||
"Default (Web API)": "Predefinito (API Web)",
|
"Default (Web API)": "Predefinito (API Web)",
|
||||||
"Default model updated": "Modello predefinito aggiornato",
|
"Default model updated": "Modello predefinito aggiornato",
|
||||||
"Default Prompt Suggestions": "Suggerimenti prompt predefiniti",
|
"Default Prompt Suggestions": "Suggerimenti prompt predefiniti",
|
||||||
"Default User Role": "Ruolo utente predefinito",
|
"Default User Role": "Ruolo utente predefinito",
|
||||||
"delete": "elimina",
|
"delete": "elimina",
|
||||||
"Delete a model": "Elimina un modello",
|
"Delete a model": "Elimina un modello",
|
||||||
"Delete chat": "Elimina chat",
|
"Delete chat": "Elimina chat",
|
||||||
"Delete Chats": "Elimina chat",
|
"Delete Chats": "Elimina chat",
|
||||||
"Deleted {{deleteModelTag}}": "Eliminato {{deleteModelTag}}",
|
"Deleted {{deleteModelTag}}": "Eliminato {{deleteModelTag}}",
|
||||||
"Deleted {tagName}": "Eliminato {tagName}",
|
"Deleted {tagName}": "Eliminato {tagName}",
|
||||||
"Description": "Descrizione",
|
"Description": "Descrizione",
|
||||||
"Desktop Notifications": "Notifiche desktop",
|
"Desktop Notifications": "Notifiche desktop",
|
||||||
"Disabled": "Disabilitato",
|
"Disabled": "Disabilitato",
|
||||||
"Discover a modelfile": "Scopri un file modello",
|
"Discover a modelfile": "Scopri un file modello",
|
||||||
"Discover a prompt": "Scopri un prompt",
|
"Discover a prompt": "Scopri un prompt",
|
||||||
"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
|
"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
|
||||||
"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
|
"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
|
||||||
"Display the username instead of You in the Chat": "Visualizza il nome utente invece di Tu nella chat",
|
"Display the username instead of You in the Chat": "Visualizza il nome utente invece di Tu nella chat",
|
||||||
"Document": "Documento",
|
"Document": "Documento",
|
||||||
"Document Settings": "Impostazioni documento",
|
"Document Settings": "Impostazioni documento",
|
||||||
"Documents": "Documenti",
|
"Documents": "Documenti",
|
||||||
"does not make any external connections, and your data stays securely on your locally hosted server.": "non effettua connessioni esterne e i tuoi dati rimangono al sicuro sul tuo server ospitato localmente.",
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "non effettua connessioni esterne e i tuoi dati rimangono al sicuro sul tuo server ospitato localmente.",
|
||||||
"Don't Allow": "Non consentire",
|
"Don't Allow": "Non consentire",
|
||||||
"Don't have an account?": "Non hai un account?",
|
"Don't have an account?": "Non hai un account?",
|
||||||
"Download as a File": "Scarica come file",
|
"Download as a File": "Scarica come file",
|
||||||
"Download Database": "Scarica database",
|
"Download Database": "Scarica database",
|
||||||
"Drop any files here to add to the conversation": "Trascina qui i file da aggiungere alla conversazione",
|
"Drop any files here to add to the conversation": "Trascina qui i file da aggiungere alla conversazione",
|
||||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "ad esempio '30s','10m'. Le unità di tempo valide sono 's', 'm', 'h'.",
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "ad esempio '30s','10m'. Le unità di tempo valide sono 's', 'm', 'h'.",
|
||||||
"Edit Doc": "Modifica documento",
|
"Edit Doc": "Modifica documento",
|
||||||
"Edit User": "Modifica utente",
|
"Edit User": "Modifica utente",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"Enable Chat History": "Abilita cronologia chat",
|
"Enable Chat History": "Abilita cronologia chat",
|
||||||
"Enable New Sign Ups": "Abilita nuove iscrizioni",
|
"Enable New Sign Ups": "Abilita nuove iscrizioni",
|
||||||
"Enabled": "Abilitato",
|
"Enabled": "Abilitato",
|
||||||
"Enter {{role}} message here": "Inserisci il messaggio per {{role}} qui",
|
"Enter {{role}} message here": "Inserisci il messaggio per {{role}} qui",
|
||||||
"Enter API Key": "Inserisci la chiave API",
|
"Enter API Key": "Inserisci la chiave API",
|
||||||
"Enter Chunk Overlap": "Inserisci la sovrapposizione chunk",
|
"Enter Chunk Overlap": "Inserisci la sovrapposizione chunk",
|
||||||
"Enter Chunk Size": "Inserisci la dimensione chunk",
|
"Enter Chunk Size": "Inserisci la dimensione chunk",
|
||||||
"Enter Image Size (e.g. 512x512)": "Inserisci la dimensione dell'immagine (ad esempio 512x512)",
|
"Enter Image Size (e.g. 512x512)": "Inserisci la dimensione dell'immagine (ad esempio 512x512)",
|
||||||
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Inserisci l'URL base dell'API LiteLLM (litellm_params.api_base)",
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Inserisci l'URL base dell'API LiteLLM (litellm_params.api_base)",
|
||||||
"Enter LiteLLM API Key (litellm_params.api_key)": "Inserisci la chiave API LiteLLM (litellm_params.api_key)",
|
"Enter LiteLLM API Key (litellm_params.api_key)": "Inserisci la chiave API LiteLLM (litellm_params.api_key)",
|
||||||
"Enter LiteLLM API RPM (litellm_params.rpm)": "Inserisci LiteLLM API RPM (litellm_params.rpm)",
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "Inserisci LiteLLM API RPM (litellm_params.rpm)",
|
||||||
"Enter LiteLLM Model (litellm_params.model)": "Inserisci il modello LiteLLM (litellm_params.model)",
|
"Enter LiteLLM Model (litellm_params.model)": "Inserisci il modello LiteLLM (litellm_params.model)",
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "Inserisci Max Tokens (litellm_params.max_tokens)",
|
"Enter Max Tokens (litellm_params.max_tokens)": "Inserisci Max Tokens (litellm_params.max_tokens)",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "Inserisci il tag del modello (ad esempio {{modelTag}})",
|
"Enter model tag (e.g. {{modelTag}})": "Inserisci il tag del modello (ad esempio {{modelTag}})",
|
||||||
"Enter Number of Steps (e.g. 50)": "Inserisci il numero di passaggi (ad esempio 50)",
|
"Enter Number of Steps (e.g. 50)": "Inserisci il numero di passaggi (ad esempio 50)",
|
||||||
"Enter stop sequence": "Inserisci la sequenza di arresto",
|
"Enter stop sequence": "Inserisci la sequenza di arresto",
|
||||||
"Enter Top K": "Inserisci Top K",
|
"Enter Top K": "Inserisci Top K",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "Inserisci URL (ad esempio http://127.0.0.1:7860/)",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "Inserisci URL (ad esempio http://127.0.0.1:7860/)",
|
||||||
"Enter Your Email": "Inserisci la tua email",
|
"Enter Your Email": "Inserisci la tua email",
|
||||||
"Enter Your Full Name": "Inserisci il tuo nome completo",
|
"Enter Your Full Name": "Inserisci il tuo nome completo",
|
||||||
"Enter Your Password": "Inserisci la tua password",
|
"Enter Your Password": "Inserisci la tua password",
|
||||||
"Experimental": "Sperimentale",
|
"Experimental": "Sperimentale",
|
||||||
"Export All Chats (All Users)": "Esporta tutte le chat (tutti gli utenti)",
|
"Export All Chats (All Users)": "Esporta tutte le chat (tutti gli utenti)",
|
||||||
"Export Chats": "Esporta chat",
|
"Export Chats": "Esporta chat",
|
||||||
"Export Documents Mapping": "Esporta mappatura documenti",
|
"Export Documents Mapping": "Esporta mappatura documenti",
|
||||||
"Export Modelfiles": "Esporta file modello",
|
"Export Modelfiles": "Esporta file modello",
|
||||||
"Export Prompts": "Esporta prompt",
|
"Export Prompts": "Esporta prompt",
|
||||||
"Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti",
|
"Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti",
|
||||||
"File Mode": "Modalità file",
|
"File Mode": "Modalità file",
|
||||||
"File not found.": "File non trovato.",
|
"File not found.": "File non trovato.",
|
||||||
"Focus chat input": "Metti a fuoco l'input della chat",
|
"Focus chat input": "Metti a fuoco l'input della chat",
|
||||||
"Format your variables using square brackets like this:": "Formatta le tue variabili usando parentesi quadre come questa:",
|
"Format your variables using square brackets like this:": "Formatta le tue variabili usando parentesi quadre come questa:",
|
||||||
"From (Base Model)": "Da (modello base)",
|
"From (Base Model)": "Da (modello base)",
|
||||||
"Full Screen Mode": "Modalità a schermo intero",
|
"Full Screen Mode": "Modalità a schermo intero",
|
||||||
"General": "Generale",
|
"General": "Generale",
|
||||||
"General Settings": "Impostazioni generali",
|
"General Settings": "Impostazioni generali",
|
||||||
"Hello, {{name}}": "Ciao, {{name}}",
|
"Hello, {{name}}": "Ciao, {{name}}",
|
||||||
"Hide": "Nascondi",
|
"Hide": "Nascondi",
|
||||||
"Hide Additional Params": "Nascondi parametri aggiuntivi",
|
"Hide Additional Params": "Nascondi parametri aggiuntivi",
|
||||||
"How can I help you today?": "Come posso aiutarti oggi?",
|
"How can I help you today?": "Come posso aiutarti oggi?",
|
||||||
"Image Generation (Experimental)": "Generazione di immagini (sperimentale)",
|
"Image Generation (Experimental)": "Generazione di immagini (sperimentale)",
|
||||||
"Image Generation Engine": "Motore di generazione immagini",
|
"Image Generation Engine": "Motore di generazione immagini",
|
||||||
"Image Settings": "Impostazioni immagine",
|
"Image Settings": "Impostazioni immagine",
|
||||||
"Images": "Immagini",
|
"Images": "Immagini",
|
||||||
"Import Chats": "Importa chat",
|
"Import Chats": "Importa chat",
|
||||||
"Import Documents Mapping": "Importa mappatura documenti",
|
"Import Documents Mapping": "Importa mappatura documenti",
|
||||||
"Import Modelfiles": "Importa file modello",
|
"Import Modelfiles": "Importa file modello",
|
||||||
"Import Prompts": "Importa prompt",
|
"Import Prompts": "Importa prompt",
|
||||||
"Include --api flag when running stable-diffusion-webui": "Includi il flag --api quando esegui stable-diffusion-webui",
|
"Include --api flag when running stable-diffusion-webui": "Includi il flag --api quando esegui stable-diffusion-webui",
|
||||||
"Interface": "Interfaccia",
|
"Interface": "Interfaccia",
|
||||||
"join our Discord for help.": "unisciti al nostro Discord per ricevere aiuto.",
|
"join our Discord for help.": "unisciti al nostro Discord per ricevere aiuto.",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"JWT Expiration": "Scadenza JWT",
|
"JWT Expiration": "Scadenza JWT",
|
||||||
"JWT Token": "Token JWT",
|
"JWT Token": "Token JWT",
|
||||||
"Keep Alive": "Mantieni attivo",
|
"Keep Alive": "Mantieni attivo",
|
||||||
"Keyboard shortcuts": "Scorciatoie da tastiera",
|
"Keyboard shortcuts": "Scorciatoie da tastiera",
|
||||||
"Language": "Lingua",
|
"Language": "Lingua",
|
||||||
"Light": "Chiaro",
|
"Light": "Chiaro",
|
||||||
"Listening...": "Ascolto...",
|
"Listening...": "Ascolto...",
|
||||||
"LLMs can make mistakes. Verify important information.": "Gli LLM possono commettere errori. Verifica le informazioni importanti.",
|
"LLMs can make mistakes. Verify important information.": "Gli LLM possono commettere errori. Verifica le informazioni importanti.",
|
||||||
"Made by OpenWebUI Community": "Realizzato dalla comunità OpenWebUI",
|
"Made by OpenWebUI Community": "Realizzato dalla comunità OpenWebUI",
|
||||||
"Make sure to enclose them with": "Assicurati di racchiuderli con",
|
"Make sure to enclose them with": "Assicurati di racchiuderli con",
|
||||||
"Manage LiteLLM Models": "Gestisci modelli LiteLLM",
|
"Manage LiteLLM Models": "Gestisci modelli LiteLLM",
|
||||||
"Manage Models": "Gestisci modelli",
|
"Manage Models": "Gestisci modelli",
|
||||||
"Manage Ollama Models": "Gestisci modelli Ollama",
|
"Manage Ollama Models": "Gestisci modelli Ollama",
|
||||||
"Max Tokens": "Max token",
|
"Max Tokens": "Max token",
|
||||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "È possibile scaricare un massimo di 3 modelli contemporaneamente. Riprova più tardi.",
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "È possibile scaricare un massimo di 3 modelli contemporaneamente. Riprova più tardi.",
|
||||||
"Mirostat": "Mirostat",
|
"Mirostat": "Mirostat",
|
||||||
"Mirostat Eta": "Mirostat Eta",
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
"Mirostat Tau": "Mirostat Tau",
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
||||||
"Model '{{modelName}}' has been successfully downloaded.": "Il modello '{{modelName}}' è stato scaricato con successo.",
|
"Model '{{modelName}}' has been successfully downloaded.": "Il modello '{{modelName}}' è stato scaricato con successo.",
|
||||||
"Model '{{modelTag}}' is already in queue for downloading.": "Il modello '{{modelTag}}' è già in coda per il download.",
|
"Model '{{modelTag}}' is already in queue for downloading.": "Il modello '{{modelTag}}' è già in coda per il download.",
|
||||||
"Model {{modelId}} not found": "Modello {{modelId}} non trovato",
|
"Model {{modelId}} not found": "Modello {{modelId}} non trovato",
|
||||||
"Model {{modelName}} already exists.": "Il modello {{modelName}} esiste già.",
|
"Model {{modelName}} already exists.": "Il modello {{modelName}} esiste già.",
|
||||||
"Model Name": "Nome modello",
|
"Model Name": "Nome modello",
|
||||||
"Model not selected": "Modello non selezionato",
|
"Model not selected": "Modello non selezionato",
|
||||||
"Model Tag Name": "Nome tag del modello",
|
"Model Tag Name": "Nome tag del modello",
|
||||||
"Model Whitelisting": "Whitelisting del modello",
|
"Model Whitelisting": "Whitelisting del modello",
|
||||||
"Model(s) Whitelisted": "Modello/i in whitelist",
|
"Model(s) Whitelisted": "Modello/i in whitelist",
|
||||||
"Modelfile": "File modello",
|
"Modelfile": "File modello",
|
||||||
"Modelfile Advanced Settings": "Impostazioni avanzate del file modello",
|
"Modelfile Advanced Settings": "Impostazioni avanzate del file modello",
|
||||||
"Modelfile Content": "Contenuto del file modello",
|
"Modelfile Content": "Contenuto del file modello",
|
||||||
"Modelfiles": "File modello",
|
"Modelfiles": "File modello",
|
||||||
"Models": "Modelli",
|
"Models": "Modelli",
|
||||||
"My Documents": "I miei documenti",
|
"My Documents": "I miei documenti",
|
||||||
"My Modelfiles": "I miei file modello",
|
"My Modelfiles": "I miei file modello",
|
||||||
"My Prompts": "I miei prompt",
|
"My Prompts": "I miei prompt",
|
||||||
"Name": "Nome",
|
"Name": "Nome",
|
||||||
"Name Tag": "Nome tag",
|
"Name Tag": "Nome tag",
|
||||||
"Name your modelfile": "Assegna un nome al tuo file modello",
|
"Name your modelfile": "Assegna un nome al tuo file modello",
|
||||||
"New Chat": "Nuova chat",
|
"New Chat": "Nuova chat",
|
||||||
"New Password": "Nuova password",
|
"New Password": "Nuova password",
|
||||||
"Not sure what to add?": "Non sei sicuro di cosa aggiungere?",
|
"Not sure what to add?": "Non sei sicuro di cosa aggiungere?",
|
||||||
"Not sure what to write? Switch to": "Non sei sicuro di cosa scrivere? Passa a",
|
"Not sure what to write? Switch to": "Non sei sicuro di cosa scrivere? Passa a",
|
||||||
"Off": "Disattivato",
|
"Off": "Disattivato",
|
||||||
"Okay, Let's Go!": "Ok, andiamo!",
|
"Okay, Let's Go!": "Ok, andiamo!",
|
||||||
"Ollama Base URL": "URL base Ollama",
|
"Ollama Base URL": "URL base Ollama",
|
||||||
"Ollama Version": "Versione Ollama",
|
"Ollama Version": "Versione Ollama",
|
||||||
"On": "Attivato",
|
"On": "Attivato",
|
||||||
"Only": "Solo",
|
"Only": "Solo",
|
||||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Nella stringa di comando sono consentiti solo caratteri alfanumerici e trattini.",
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "Nella stringa di comando sono consentiti solo caratteri alfanumerici e trattini.",
|
||||||
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Ops! Aspetta! I tuoi file sono ancora in fase di elaborazione. Li stiamo cucinando alla perfezione. Per favore sii paziente e ti faremo sapere quando saranno pronti.",
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Ops! Aspetta! I tuoi file sono ancora in fase di elaborazione. Li stiamo cucinando alla perfezione. Per favore sii paziente e ti faremo sapere quando saranno pronti.",
|
||||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ops! Sembra che l'URL non sia valido. Si prega di ricontrollare e riprovare.",
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ops! Sembra che l'URL non sia valido. Si prega di ricontrollare e riprovare.",
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ops! Stai utilizzando un metodo non supportato (solo frontend). Si prega di servire la WebUI dal backend.",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ops! Stai utilizzando un metodo non supportato (solo frontend). Si prega di servire la WebUI dal backend.",
|
||||||
"Open": "Apri",
|
"Open": "Apri",
|
||||||
"Open AI": "Open AI",
|
"Open AI": "Open AI",
|
||||||
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
||||||
"Open new chat": "Apri nuova chat",
|
"Open new chat": "Apri nuova chat",
|
||||||
"OpenAI API": "API OpenAI",
|
"OpenAI API": "API OpenAI",
|
||||||
"OpenAI API Key": "Chiave API OpenAI",
|
"OpenAI API Key": "Chiave API OpenAI",
|
||||||
"OpenAI API Key is required.": "La chiave API OpenAI è obbligatoria.",
|
"OpenAI API Key is required.": "La chiave API OpenAI è obbligatoria.",
|
||||||
"or": "o",
|
"or": "o",
|
||||||
"Parameters": "Parametri",
|
"Parameters": "Parametri",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
"PDF Extract Images (OCR)": "Estrazione immagini PDF (OCR)",
|
"PDF Extract Images (OCR)": "Estrazione immagini PDF (OCR)",
|
||||||
"pending": "in sospeso",
|
"pending": "in sospeso",
|
||||||
"Permission denied when accessing microphone: {{error}}": "Autorizzazione negata durante l'accesso al microfono: {{error}}",
|
"Permission denied when accessing microphone: {{error}}": "Autorizzazione negata durante l'accesso al microfono: {{error}}",
|
||||||
"Playground": "Playground",
|
"Playground": "Playground",
|
||||||
"Profile": "Profilo",
|
"Profile": "Profilo",
|
||||||
"Prompt Content": "Contenuto del prompt",
|
"Prompt Content": "Contenuto del prompt",
|
||||||
"Prompt suggestions": "Suggerimenti prompt",
|
"Prompt suggestions": "Suggerimenti prompt",
|
||||||
"Prompts": "Prompt",
|
"Prompts": "Prompt",
|
||||||
"Pull a model from Ollama.com": "Estrai un modello da Ollama.com",
|
"Pull a model from Ollama.com": "Estrai un modello da Ollama.com",
|
||||||
"Pull Progress": "Avanzamento estrazione",
|
"Pull Progress": "Avanzamento estrazione",
|
||||||
"Query Params": "Parametri query",
|
"Query Params": "Parametri query",
|
||||||
"RAG Template": "Modello RAG",
|
"RAG Template": "Modello RAG",
|
||||||
"Raw Format": "Formato raw",
|
"Raw Format": "Formato raw",
|
||||||
"Record voice": "Registra voce",
|
"Record voice": "Registra voce",
|
||||||
"Redirecting you to OpenWebUI Community": "Reindirizzamento alla comunità OpenWebUI",
|
"Redirecting you to OpenWebUI Community": "Reindirizzamento alla comunità OpenWebUI",
|
||||||
"Release Notes": "Note di rilascio",
|
"Release Notes": "Note di rilascio",
|
||||||
"Repeat Last N": "Ripeti ultimi N",
|
"Repeat Last N": "Ripeti ultimi N",
|
||||||
"Repeat Penalty": "Penalità di ripetizione",
|
"Repeat Penalty": "Penalità di ripetizione",
|
||||||
"Request Mode": "Modalità richiesta",
|
"Request Mode": "Modalità richiesta",
|
||||||
"Reset Vector Storage": "Reimposta archivio vettoriale",
|
"Reset Vector Storage": "Reimposta archivio vettoriale",
|
||||||
"Response AutoCopy to Clipboard": "Copia automatica della risposta negli appunti",
|
"Response AutoCopy to Clipboard": "Copia automatica della risposta negli appunti",
|
||||||
"Role": "Ruolo",
|
"Role": "Ruolo",
|
||||||
"Rosé Pine": "Rosé Pine",
|
"Rosé Pine": "Rosé Pine",
|
||||||
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
"Save": "Salva",
|
"Save": "Salva",
|
||||||
"Save & Create": "Salva e crea",
|
"Save & Create": "Salva e crea",
|
||||||
"Save & Submit": "Salva e invia",
|
"Save & Submit": "Salva e invia",
|
||||||
"Save & Update": "Salva e aggiorna",
|
"Save & Update": "Salva e aggiorna",
|
||||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Il salvataggio dei registri della chat direttamente nell'archivio del browser non è più supportato. Si prega di dedicare un momento per scaricare ed eliminare i registri della chat facendo clic sul pulsante in basso. Non preoccuparti, puoi facilmente reimportare i registri della chat nel backend tramite",
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Il salvataggio dei registri della chat direttamente nell'archivio del browser non è più supportato. Si prega di dedicare un momento per scaricare ed eliminare i registri della chat facendo clic sul pulsante in basso. Non preoccuparti, puoi facilmente reimportare i registri della chat nel backend tramite",
|
||||||
"Scan": "Scansione",
|
"Scan": "Scansione",
|
||||||
"Scan complete!": "Scansione completata!",
|
"Scan complete!": "Scansione completata!",
|
||||||
"Scan for documents from {{path}}": "Cerca documenti da {{path}}",
|
"Scan for documents from {{path}}": "Cerca documenti da {{path}}",
|
||||||
"Search": "Cerca",
|
"Search": "Cerca",
|
||||||
"Search Documents": "Cerca documenti",
|
"Search Documents": "Cerca documenti",
|
||||||
"Search Prompts": "Cerca prompt",
|
"Search Prompts": "Cerca prompt",
|
||||||
"See readme.md for instructions": "Vedi readme.md per le istruzioni",
|
"See readme.md for instructions": "Vedi readme.md per le istruzioni",
|
||||||
"See what's new": "Guarda le novità",
|
"See what's new": "Guarda le novità",
|
||||||
"Seed": "Seme",
|
"Seed": "Seme",
|
||||||
"Select a mode": "Seleziona una modalità",
|
"Select a mode": "Seleziona una modalità",
|
||||||
"Select a model": "Seleziona un modello",
|
"Select a model": "Seleziona un modello",
|
||||||
"Select an Ollama instance": "Seleziona un'istanza Ollama",
|
"Select an Ollama instance": "Seleziona un'istanza Ollama",
|
||||||
"Send a Message": "Invia un messaggio",
|
"Send a Message": "Invia un messaggio",
|
||||||
"Send message": "Invia messaggio",
|
"Send message": "Invia messaggio",
|
||||||
"Server connection verified": "Connessione al server verificata",
|
"Server connection verified": "Connessione al server verificata",
|
||||||
"Set as default": "Imposta come predefinito",
|
"Set as default": "Imposta come predefinito",
|
||||||
"Set Default Model": "Imposta modello predefinito",
|
"Set Default Model": "Imposta modello predefinito",
|
||||||
"Set Image Size": "Imposta dimensione immagine",
|
"Set Image Size": "Imposta dimensione immagine",
|
||||||
"Set Steps": "Imposta passaggi",
|
"Set Steps": "Imposta passaggi",
|
||||||
"Set Title Auto-Generation Model": "Imposta modello di generazione automatica del titolo",
|
"Set Title Auto-Generation Model": "Imposta modello di generazione automatica del titolo",
|
||||||
"Set Voice": "Imposta voce",
|
"Set Voice": "Imposta voce",
|
||||||
"Settings": "Impostazioni",
|
"Settings": "Impostazioni",
|
||||||
"Settings saved successfully!": "Impostazioni salvate con successo!",
|
"Settings saved successfully!": "Impostazioni salvate con successo!",
|
||||||
"Share to OpenWebUI Community": "Condividi con la comunità OpenWebUI",
|
"Share to OpenWebUI Community": "Condividi con la comunità OpenWebUI",
|
||||||
"short-summary": "riassunto-breve",
|
"short-summary": "riassunto-breve",
|
||||||
"Show": "Mostra",
|
"Show": "Mostra",
|
||||||
"Show Additional Params": "Mostra parametri aggiuntivi",
|
"Show Additional Params": "Mostra parametri aggiuntivi",
|
||||||
"Show shortcuts": "Mostra",
|
"Show shortcuts": "Mostra",
|
||||||
"sidebar": "barra laterale",
|
"sidebar": "barra laterale",
|
||||||
"Sign in": "Accedi",
|
"Sign in": "Accedi",
|
||||||
"Sign Out": "Esci",
|
"Sign Out": "Esci",
|
||||||
"Sign up": "Registrati",
|
"Sign up": "Registrati",
|
||||||
"Speech recognition error: {{error}}": "Errore di riconoscimento vocale: {{error}}",
|
"Speech recognition error: {{error}}": "Errore di riconoscimento vocale: {{error}}",
|
||||||
"Speech-to-Text Engine": "Motore da voce a testo",
|
"Speech-to-Text Engine": "Motore da voce a testo",
|
||||||
"SpeechRecognition API is not supported in this browser.": "L'API SpeechRecognition non è supportata in questo browser.",
|
"SpeechRecognition API is not supported in this browser.": "L'API SpeechRecognition non è supportata in questo browser.",
|
||||||
"Stop Sequence": "Sequenza di arresto",
|
"Stop Sequence": "Sequenza di arresto",
|
||||||
"STT Settings": "Impostazioni STT",
|
"STT Settings": "Impostazioni STT",
|
||||||
"Submit": "Invia",
|
"Submit": "Invia",
|
||||||
"Success": "Successo",
|
"Success": "Successo",
|
||||||
"Successfully updated.": "Aggiornato con successo.",
|
"Successfully updated.": "Aggiornato con successo.",
|
||||||
"Sync All": "Sincronizza tutto",
|
"Sync All": "Sincronizza tutto",
|
||||||
"System": "Sistema",
|
"System": "Sistema",
|
||||||
"System Prompt": "Prompt di sistema",
|
"System Prompt": "Prompt di sistema",
|
||||||
"Tags": "Tag",
|
"Tags": "Tag",
|
||||||
"Temperature": "Temperatura",
|
"Temperature": "Temperatura",
|
||||||
"Template": "Modello",
|
"Template": "Modello",
|
||||||
"Text Completion": "Completamento del testo",
|
"Text Completion": "Completamento del testo",
|
||||||
"Text-to-Speech Engine": "Motore da testo a voce",
|
"Text-to-Speech Engine": "Motore da testo a voce",
|
||||||
"Tfs Z": "Tfs Z",
|
"Tfs Z": "Tfs Z",
|
||||||
"Theme": "Tema",
|
"Theme": "Tema",
|
||||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Ciò garantisce che le tue preziose conversazioni siano salvate in modo sicuro nel tuo database backend. Grazie!",
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Ciò garantisce che le tue preziose conversazioni siano salvate in modo sicuro nel tuo database backend. Grazie!",
|
||||||
"This setting does not sync across browsers or devices.": "Questa impostazione non si sincronizza tra browser o dispositivi.",
|
"This setting does not sync across browsers or devices.": "Questa impostazione non si sincronizza tra browser o dispositivi.",
|
||||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Suggerimento: aggiorna più slot di variabili consecutivamente premendo il tasto tab nell'input della chat dopo ogni sostituzione.",
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Suggerimento: aggiorna più slot di variabili consecutivamente premendo il tasto tab nell'input della chat dopo ogni sostituzione.",
|
||||||
"Title": "Titolo",
|
"Title": "Titolo",
|
||||||
"Title Auto-Generation": "Generazione automatica del titolo",
|
"Title Auto-Generation": "Generazione automatica del titolo",
|
||||||
"Title Generation Prompt": "Prompt di generazione del titolo",
|
"Title Generation Prompt": "Prompt di generazione del titolo",
|
||||||
"to": "a",
|
"to": "a",
|
||||||
"To access the available model names for downloading,": "Per accedere ai nomi dei modelli disponibili per il download,",
|
"To access the available model names for downloading,": "Per accedere ai nomi dei modelli disponibili per il download,",
|
||||||
"To access the GGUF models available for downloading,": "Per accedere ai modelli GGUF disponibili per il download,",
|
"To access the GGUF models available for downloading,": "Per accedere ai modelli GGUF disponibili per il download,",
|
||||||
"to chat input.": "all'input della chat.",
|
"to chat input.": "all'input della chat.",
|
||||||
"Toggle settings": "Attiva/disattiva impostazioni",
|
"Toggle settings": "Attiva/disattiva impostazioni",
|
||||||
"Toggle sidebar": "Attiva/disattiva barra laterale",
|
"Toggle sidebar": "Attiva/disattiva barra laterale",
|
||||||
"Top K": "Top K",
|
"Top K": "Top K",
|
||||||
"Top P": "Top P",
|
"Top P": "Top P",
|
||||||
"Trouble accessing Ollama?": "Problemi di accesso a Ollama?",
|
"Trouble accessing Ollama?": "Problemi di accesso a Ollama?",
|
||||||
"TTS Settings": "Impostazioni TTS",
|
"TTS Settings": "Impostazioni TTS",
|
||||||
"Type Hugging Face Resolve (Download) URL": "Digita l'URL di Hugging Face Resolve (Download)",
|
"Type Hugging Face Resolve (Download) URL": "Digita l'URL di Hugging Face Resolve (Download)",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Si è verificato un problema durante la connessione a {{provider}}.",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Si è verificato un problema durante la connessione a {{provider}}.",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Tipo di file sconosciuto '{{file_type}}', ma accettato e trattato come testo normale",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Tipo di file sconosciuto '{{file_type}}', ma accettato e trattato come testo normale",
|
||||||
"Update password": "Aggiorna password",
|
"Update password": "Aggiorna password",
|
||||||
"Upload a GGUF model": "Carica un modello GGUF",
|
"Upload a GGUF model": "Carica un modello GGUF",
|
||||||
"Upload files": "Carica file",
|
"Upload files": "Carica file",
|
||||||
"Upload Progress": "Avanzamento caricamento",
|
"Upload Progress": "Avanzamento caricamento",
|
||||||
"URL Mode": "Modalità URL",
|
"URL Mode": "Modalità URL",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "Usa '#' nell'input del prompt per caricare e selezionare i tuoi documenti.",
|
"Use '#' in the prompt input to load and select your documents.": "Usa '#' nell'input del prompt per caricare e selezionare i tuoi documenti.",
|
||||||
"Use Gravatar": "Usa Gravatar",
|
"Use Gravatar": "Usa Gravatar",
|
||||||
"user": "utente",
|
"user": "utente",
|
||||||
"User Permissions": "Autorizzazioni utente",
|
"User Permissions": "Autorizzazioni utente",
|
||||||
"Users": "Utenti",
|
"Users": "Utenti",
|
||||||
"Utilize": "Utilizza",
|
"Utilize": "Utilizza",
|
||||||
"Valid time units:": "Unità di tempo valide:",
|
"Valid time units:": "Unità di tempo valide:",
|
||||||
"variable": "variabile",
|
"variable": "variabile",
|
||||||
"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
|
"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
|
||||||
"Version": "Versione",
|
"Version": "Versione",
|
||||||
"Web": "Web",
|
"Web": "Web",
|
||||||
"WebUI Add-ons": "Componenti aggiuntivi WebUI",
|
"WebUI Add-ons": "Componenti aggiuntivi WebUI",
|
||||||
"WebUI Settings": "Impostazioni WebUI",
|
"WebUI Settings": "Impostazioni WebUI",
|
||||||
"WebUI will make requests to": "WebUI effettuerà richieste a",
|
"WebUI will make requests to": "WebUI effettuerà richieste a",
|
||||||
"What’s New in": "Novità in",
|
"What’s New in": "Novità in",
|
||||||
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando la cronologia è disattivata, le nuove chat su questo browser non verranno visualizzate nella cronologia su nessuno dei tuoi dispositivi.",
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando la cronologia è disattivata, le nuove chat su questo browser non verranno visualizzate nella cronologia su nessuno dei tuoi dispositivi.",
|
||||||
"Whisper (Local)": "Whisper (locale)",
|
"Whisper (Local)": "Whisper (locale)",
|
||||||
"Write a prompt suggestion (e.g. Who are you?)": "Scrivi un suggerimento per il prompt (ad esempio Chi sei?)",
|
"Write a prompt suggestion (e.g. Who are you?)": "Scrivi un suggerimento per il prompt (ad esempio Chi sei?)",
|
||||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Scrivi un riassunto in 50 parole che riassume [argomento o parola chiave].",
|
"Write a summary in 50 words that summarizes [topic or keyword].": "Scrivi un riassunto in 50 parole che riassume [argomento o parola chiave].",
|
||||||
"You": "Tu",
|
"You": "Tu",
|
||||||
"You're a helpful assistant.": "Sei un assistente utile.",
|
"You're a helpful assistant.": "Sei un assistente utile.",
|
||||||
"You're now logged in.": "Ora hai effettuato l'accesso."
|
"You're now logged in.": "Ora hai effettuato l'accesso."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,363 +1,363 @@
|
||||||
{
|
{
|
||||||
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'秒', '分', '時間', '日', '週' または '-1' で無期限。",
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'秒', '分', '時間', '日', '週' または '-1' で無期限。",
|
||||||
"(Beta)": "(ベータ版)",
|
"(Beta)": "(ベータ版)",
|
||||||
"(e.g. sh webui.sh --api)": "(例: sh webui.sh --api)",
|
"(e.g. sh webui.sh --api)": "(例: sh webui.sh --api)",
|
||||||
"(latest)": "(最新)",
|
"(latest)": "(最新)",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} は思考中です...",
|
"{{modelName}} is thinking...": "{{modelName}} は思考中です...",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} バックエンドが必要です",
|
"{{webUIName}} Backend Required": "{{webUIName}} バックエンドが必要です",
|
||||||
"a user": "ユーザー",
|
"a user": "ユーザー",
|
||||||
"About": "概要",
|
"About": "概要",
|
||||||
"Account": "アカウント",
|
"Account": "アカウント",
|
||||||
"Action": "アクション",
|
"Action": "アクション",
|
||||||
"Add a model": "モデルを追加",
|
"Add a model": "モデルを追加",
|
||||||
"Add a model tag name": "モデルタグ名を追加",
|
"Add a model tag name": "モデルタグ名を追加",
|
||||||
"Add a short description about what this modelfile does": "このモデルファイルの機能に関する簡単な説明を追加",
|
"Add a short description about what this modelfile does": "このモデルファイルの機能に関する簡単な説明を追加",
|
||||||
"Add a short title for this prompt": "このプロンプトの短いタイトルを追加",
|
"Add a short title for this prompt": "このプロンプトの短いタイトルを追加",
|
||||||
"Add a tag": "タグを追加",
|
"Add a tag": "タグを追加",
|
||||||
"Add Docs": "ドキュメントを追加",
|
"Add Docs": "ドキュメントを追加",
|
||||||
"Add Files": "ファイルを追加",
|
"Add Files": "ファイルを追加",
|
||||||
"Add message": "メッセージを追加",
|
"Add message": "メッセージを追加",
|
||||||
"add tags": "タグを追加",
|
"add tags": "タグを追加",
|
||||||
"Adjusting these settings will apply changes universally to all users.": "これらの設定を調整すると、すべてのユーザーに普遍的に変更が適用されます。",
|
"Adjusting these settings will apply changes universally to all users.": "これらの設定を調整すると、すべてのユーザーに普遍的に変更が適用されます。",
|
||||||
"admin": "管理者",
|
"admin": "管理者",
|
||||||
"Admin Panel": "管理者パネル",
|
"Admin Panel": "管理者パネル",
|
||||||
"Admin Settings": "管理者設定",
|
"Admin Settings": "管理者設定",
|
||||||
"Advanced Parameters": "詳細パラメーター",
|
"Advanced Parameters": "詳細パラメーター",
|
||||||
"all": "すべて",
|
"all": "すべて",
|
||||||
"All Users": "すべてのユーザー",
|
"All Users": "すべてのユーザー",
|
||||||
"Allow": "許可",
|
"Allow": "許可",
|
||||||
"Allow Chat Deletion": "チャットの削除を許可",
|
"Allow Chat Deletion": "チャットの削除を許可",
|
||||||
"alphanumeric characters and hyphens": "英数字とハイフン",
|
"alphanumeric characters and hyphens": "英数字とハイフン",
|
||||||
"Already have an account?": "すでにアカウントをお持ちですか?",
|
"Already have an account?": "すでにアカウントをお持ちですか?",
|
||||||
"an assistant": "アシスタント",
|
"an assistant": "アシスタント",
|
||||||
"and": "および",
|
"and": "および",
|
||||||
"API Base URL": "API ベース URL",
|
"API Base URL": "API ベース URL",
|
||||||
"API Key": "API キー",
|
"API Key": "API キー",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "API RPM",
|
||||||
"are allowed - Activate this command by typing": "が許可されています - 次のように入力してこのコマンドをアクティブ化します",
|
"are allowed - Activate this command by typing": "が許可されています - 次のように入力してこのコマンドをアクティブ化します",
|
||||||
"Are you sure?": "よろしいですか?",
|
"Are you sure?": "よろしいですか?",
|
||||||
"Audio": "オーディオ",
|
"Audio": "オーディオ",
|
||||||
"Auto-playback response": "応答の自動再生",
|
"Auto-playback response": "応答の自動再生",
|
||||||
"Auto-send input after 3 sec.": "3 秒後に自動的に出力を送信",
|
"Auto-send input after 3 sec.": "3 秒後に自動的に出力を送信",
|
||||||
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 ベース URL",
|
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 ベース URL",
|
||||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。",
|
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。",
|
||||||
"available!": "利用可能!",
|
"available!": "利用可能!",
|
||||||
"Back": "戻る",
|
"Back": "戻る",
|
||||||
"Builder Mode": "ビルダーモード",
|
"Builder Mode": "ビルダーモード",
|
||||||
"Cancel": "キャンセル",
|
"Cancel": "キャンセル",
|
||||||
"Categories": "カテゴリ",
|
"Categories": "カテゴリ",
|
||||||
"Change Password": "パスワードを変更",
|
"Change Password": "パスワードを変更",
|
||||||
"Chat": "チャット",
|
"Chat": "チャット",
|
||||||
"Chat History": "チャット履歴",
|
"Chat History": "チャット履歴",
|
||||||
"Chat History is off for this browser.": "このブラウザではチャット履歴が無効になっています。",
|
"Chat History is off for this browser.": "このブラウザではチャット履歴が無効になっています。",
|
||||||
"Chats": "チャット",
|
"Chats": "チャット",
|
||||||
"Check Again": "再確認",
|
"Check Again": "再確認",
|
||||||
"Check for updates": "アップデートを確認",
|
"Check for updates": "アップデートを確認",
|
||||||
"Checking for updates...": "アップデートを確認しています...",
|
"Checking for updates...": "アップデートを確認しています...",
|
||||||
"Choose a model before saving...": "保存する前にモデルを選択してください...",
|
"Choose a model before saving...": "保存する前にモデルを選択してください...",
|
||||||
"Chunk Overlap": "チャンクオーバーラップ",
|
"Chunk Overlap": "チャンクオーバーラップ",
|
||||||
"Chunk Params": "チャンクパラメーター",
|
"Chunk Params": "チャンクパラメーター",
|
||||||
"Chunk Size": "チャンクサイズ",
|
"Chunk Size": "チャンクサイズ",
|
||||||
"Click here for help.": "ヘルプについてはここをクリックしてください。",
|
"Click here for help.": "ヘルプについてはここをクリックしてください。",
|
||||||
"Click here to check other modelfiles.": "他のモデルファイルを確認するにはここをクリックしてください。",
|
"Click here to check other modelfiles.": "他のモデルファイルを確認するにはここをクリックしてください。",
|
||||||
"Click here to select": "選択するにはここをクリックしてください",
|
"Click here to select": "選択するにはここをクリックしてください",
|
||||||
"Click here to select documents.": "ドキュメントを選択するにはここをクリックしてください。",
|
"Click here to select documents.": "ドキュメントを選択するにはここをクリックしてください。",
|
||||||
"click here.": "ここをクリックしてください。",
|
"click here.": "ここをクリックしてください。",
|
||||||
"Click on the user role button to change a user's role.": "ユーザーの役割を変更するには、ユーザー役割ボタンをクリックしてください。",
|
"Click on the user role button to change a user's role.": "ユーザーの役割を変更するには、ユーザー役割ボタンをクリックしてください。",
|
||||||
"Close": "閉じる",
|
"Close": "閉じる",
|
||||||
"Collection": "コレクション",
|
"Collection": "コレクション",
|
||||||
"Command": "コマンド",
|
"Command": "コマンド",
|
||||||
"Confirm Password": "パスワードを確認",
|
"Confirm Password": "パスワードを確認",
|
||||||
"Connections": "接続",
|
"Connections": "接続",
|
||||||
"Content": "コンテンツ",
|
"Content": "コンテンツ",
|
||||||
"Context Length": "コンテキストの長さ",
|
"Context Length": "コンテキストの長さ",
|
||||||
"Conversation Mode": "会話モード",
|
"Conversation Mode": "会話モード",
|
||||||
"Copy last code block": "最後のコードブロックをコピー",
|
"Copy last code block": "最後のコードブロックをコピー",
|
||||||
"Copy last response": "最後の応答をコピー",
|
"Copy last response": "最後の応答をコピー",
|
||||||
"Copying to clipboard was successful!": "クリップボードへのコピーが成功しました!",
|
"Copying to clipboard was successful!": "クリップボードへのコピーが成功しました!",
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "次のクエリの見出しとして、3〜5語の簡潔なフレーズを作成してください。3〜5語の制限を厳守し、「タイトル」という単語の使用を避けてください。",
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "次のクエリの見出しとして、3〜5語の簡潔なフレーズを作成してください。3〜5語の制限を厳守し、「タイトル」という単語の使用を避けてください。",
|
||||||
"Create a modelfile": "モデルファイルを作成",
|
"Create a modelfile": "モデルファイルを作成",
|
||||||
"Create Account": "アカウントを作成",
|
"Create Account": "アカウントを作成",
|
||||||
"Created at": "作成日時",
|
"Created at": "作成日時",
|
||||||
"Created by": "作成者",
|
"Created by": "作成者",
|
||||||
"Current Model": "現在のモデル",
|
"Current Model": "現在のモデル",
|
||||||
"Current Password": "現在のパスワード",
|
"Current Password": "現在のパスワード",
|
||||||
"Custom": "カスタム",
|
"Custom": "カスタム",
|
||||||
"Customize Ollama models for a specific purpose": "特定の目的に合わせて Ollama モデルをカスタマイズ",
|
"Customize Ollama models for a specific purpose": "特定の目的に合わせて Ollama モデルをカスタマイズ",
|
||||||
"Dark": "ダーク",
|
"Dark": "ダーク",
|
||||||
"Database": "データベース",
|
"Database": "データベース",
|
||||||
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
||||||
"Default": "デフォルト",
|
"Default": "デフォルト",
|
||||||
"Default (Automatic1111)": "デフォルト (Automatic1111)",
|
"Default (Automatic1111)": "デフォルト (Automatic1111)",
|
||||||
"Default (Web API)": "デフォルト (Web API)",
|
"Default (Web API)": "デフォルト (Web API)",
|
||||||
"Default model updated": "デフォルトモデルが更新されました",
|
"Default model updated": "デフォルトモデルが更新されました",
|
||||||
"Default Prompt Suggestions": "デフォルトのプロンプトの提案",
|
"Default Prompt Suggestions": "デフォルトのプロンプトの提案",
|
||||||
"Default User Role": "デフォルトのユーザー役割",
|
"Default User Role": "デフォルトのユーザー役割",
|
||||||
"delete": "削除",
|
"delete": "削除",
|
||||||
"Delete a model": "モデルを削除",
|
"Delete a model": "モデルを削除",
|
||||||
"Delete chat": "チャットを削除",
|
"Delete chat": "チャットを削除",
|
||||||
"Delete Chats": "チャットを削除",
|
"Delete Chats": "チャットを削除",
|
||||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} を削除しました",
|
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} を削除しました",
|
||||||
"Deleted {tagName}": "{tagName} を削除しました",
|
"Deleted {tagName}": "{tagName} を削除しました",
|
||||||
"Description": "説明",
|
"Description": "説明",
|
||||||
"Desktop Notifications": "デスクトップ通知",
|
"Desktop Notifications": "デスクトップ通知",
|
||||||
"Disabled": "無効",
|
"Disabled": "無効",
|
||||||
"Discover a modelfile": "モデルファイルを見つける",
|
"Discover a modelfile": "モデルファイルを見つける",
|
||||||
"Discover a prompt": "プロンプトを見つける",
|
"Discover a prompt": "プロンプトを見つける",
|
||||||
"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
|
"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
|
||||||
"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
|
"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
|
||||||
"Display the username instead of You in the Chat": "チャットで「あなた」の代わりにユーザー名を表示",
|
"Display the username instead of You in the Chat": "チャットで「あなた」の代わりにユーザー名を表示",
|
||||||
"Document": "ドキュメント",
|
"Document": "ドキュメント",
|
||||||
"Document Settings": "ドキュメント設定",
|
"Document Settings": "ドキュメント設定",
|
||||||
"Documents": "ドキュメント",
|
"Documents": "ドキュメント",
|
||||||
"does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。",
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。",
|
||||||
"Don't Allow": "許可しない",
|
"Don't Allow": "許可しない",
|
||||||
"Don't have an account?": "アカウントをお持ちではありませんか?",
|
"Don't have an account?": "アカウントをお持ちではありませんか?",
|
||||||
"Download as a File": "ファイルとしてダウンロード",
|
"Download as a File": "ファイルとしてダウンロード",
|
||||||
"Download Database": "データベースをダウンロード",
|
"Download Database": "データベースをダウンロード",
|
||||||
"Drop any files here to add to the conversation": "会話を追加するには、ここにファイルをドロップしてください",
|
"Drop any files here to add to the conversation": "会話を追加するには、ここにファイルをドロップしてください",
|
||||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例: '30秒'、'10分'。有効な時間単位は '秒'、'分'、'時間' です。",
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "例: '30秒'、'10分'。有効な時間単位は '秒'、'分'、'時間' です。",
|
||||||
"Edit Doc": "ドキュメントを編集",
|
"Edit Doc": "ドキュメントを編集",
|
||||||
"Edit User": "ユーザーを編集",
|
"Edit User": "ユーザーを編集",
|
||||||
"Email": "メールアドレス",
|
"Email": "メールアドレス",
|
||||||
"Enable Chat History": "チャット履歴を有効化",
|
"Enable Chat History": "チャット履歴を有効化",
|
||||||
"Enable New Sign Ups": "新規登録を有効化",
|
"Enable New Sign Ups": "新規登録を有効化",
|
||||||
"Enabled": "有効",
|
"Enabled": "有効",
|
||||||
"Enter {{role}} message here": "{{role}} メッセージをここに入力してください",
|
"Enter {{role}} message here": "{{role}} メッセージをここに入力してください",
|
||||||
"Enter API Key": "API キーを入力してください",
|
"Enter API Key": "API キーを入力してください",
|
||||||
"Enter Chunk Overlap": "チャンクオーバーラップを入力してください",
|
"Enter Chunk Overlap": "チャンクオーバーラップを入力してください",
|
||||||
"Enter Chunk Size": "チャンクサイズを入力してください",
|
"Enter Chunk Size": "チャンクサイズを入力してください",
|
||||||
"Enter Image Size (e.g. 512x512)": "画像サイズを入力してください (例: 512x512)",
|
"Enter Image Size (e.g. 512x512)": "画像サイズを入力してください (例: 512x512)",
|
||||||
"Enter LiteLLM API Base URL (litellm_params.api_base)": "LiteLLM API ベース URL を入力してください (litellm_params.api_base)",
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "LiteLLM API ベース URL を入力してください (litellm_params.api_base)",
|
||||||
"Enter LiteLLM API Key (litellm_params.api_key)": "LiteLLM API キーを入力してください (litellm_params.api_key)",
|
"Enter LiteLLM API Key (litellm_params.api_key)": "LiteLLM API キーを入力してください (litellm_params.api_key)",
|
||||||
"Enter LiteLLM API RPM (litellm_params.rpm)": "LiteLLM API RPM を入力してください (litellm_params.rpm)",
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "LiteLLM API RPM を入力してください (litellm_params.rpm)",
|
||||||
"Enter LiteLLM Model (litellm_params.model)": "LiteLLM モデルを入力してください (litellm_params.model)",
|
"Enter LiteLLM Model (litellm_params.model)": "LiteLLM モデルを入力してください (litellm_params.model)",
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "最大トークン数を入力してください (litellm_params.max_tokens)",
|
"Enter Max Tokens (litellm_params.max_tokens)": "最大トークン数を入力してください (litellm_params.max_tokens)",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "モデルタグを入力してください (例: {{modelTag}})",
|
"Enter model tag (e.g. {{modelTag}})": "モデルタグを入力してください (例: {{modelTag}})",
|
||||||
"Enter Number of Steps (e.g. 50)": "ステップ数を入力してください (例: 50)",
|
"Enter Number of Steps (e.g. 50)": "ステップ数を入力してください (例: 50)",
|
||||||
"Enter stop sequence": "ストップシーケンスを入力してください",
|
"Enter stop sequence": "ストップシーケンスを入力してください",
|
||||||
"Enter Top K": "トップ K を入力してください",
|
"Enter Top K": "トップ K を入力してください",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "URL を入力してください (例: http://127.0.0.1:7860/)",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "URL を入力してください (例: http://127.0.0.1:7860/)",
|
||||||
"Enter Your Email": "メールアドレスを入力してください",
|
"Enter Your Email": "メールアドレスを入力してください",
|
||||||
"Enter Your Full Name": "フルネームを入力してください",
|
"Enter Your Full Name": "フルネームを入力してください",
|
||||||
"Enter Your Password": "パスワードを入力してください",
|
"Enter Your Password": "パスワードを入力してください",
|
||||||
"Experimental": "実験的",
|
"Experimental": "実験的",
|
||||||
"Export All Chats (All Users)": "すべてのチャットをエクスポート (すべてのユーザー)",
|
"Export All Chats (All Users)": "すべてのチャットをエクスポート (すべてのユーザー)",
|
||||||
"Export Chats": "チャットをエクスポート",
|
"Export Chats": "チャットをエクスポート",
|
||||||
"Export Documents Mapping": "ドキュメントマッピングをエクスポート",
|
"Export Documents Mapping": "ドキュメントマッピングをエクスポート",
|
||||||
"Export Modelfiles": "モデルファイルをエクスポート",
|
"Export Modelfiles": "モデルファイルをエクスポート",
|
||||||
"Export Prompts": "プロンプトをエクスポート",
|
"Export Prompts": "プロンプトをエクスポート",
|
||||||
"Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした",
|
"Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした",
|
||||||
"File Mode": "ファイルモード",
|
"File Mode": "ファイルモード",
|
||||||
"File not found.": "ファイルが見つかりません。",
|
"File not found.": "ファイルが見つかりません。",
|
||||||
"Focus chat input": "チャット入力をフォーカス",
|
"Focus chat input": "チャット入力をフォーカス",
|
||||||
"Format your variables using square brackets like this:": "次のように角括弧を使用して変数をフォーマットします。",
|
"Format your variables using square brackets like this:": "次のように角括弧を使用して変数をフォーマットします。",
|
||||||
"From (Base Model)": "From (ベースモデル)",
|
"From (Base Model)": "From (ベースモデル)",
|
||||||
"Full Screen Mode": "フルスクリーンモード",
|
"Full Screen Mode": "フルスクリーンモード",
|
||||||
"General": "一般",
|
"General": "一般",
|
||||||
"General Settings": "一般設定",
|
"General Settings": "一般設定",
|
||||||
"Hello, {{name}}": "こんにちは、{{name}} さん",
|
"Hello, {{name}}": "こんにちは、{{name}} さん",
|
||||||
"Hide": "非表示",
|
"Hide": "非表示",
|
||||||
"Hide Additional Params": "追加パラメーターを非表示",
|
"Hide Additional Params": "追加パラメーターを非表示",
|
||||||
"How can I help you today?": "今日はどのようにお手伝いしましょうか?",
|
"How can I help you today?": "今日はどのようにお手伝いしましょうか?",
|
||||||
"Image Generation (Experimental)": "画像生成 (実験的)",
|
"Image Generation (Experimental)": "画像生成 (実験的)",
|
||||||
"Image Generation Engine": "画像生成エンジン",
|
"Image Generation Engine": "画像生成エンジン",
|
||||||
"Image Settings": "画像設定",
|
"Image Settings": "画像設定",
|
||||||
"Images": "画像",
|
"Images": "画像",
|
||||||
"Import Chats": "チャットをインポート",
|
"Import Chats": "チャットをインポート",
|
||||||
"Import Documents Mapping": "ドキュメントマッピングをインポート",
|
"Import Documents Mapping": "ドキュメントマッピングをインポート",
|
||||||
"Import Modelfiles": "モデルファイルをインポート",
|
"Import Modelfiles": "モデルファイルをインポート",
|
||||||
"Import Prompts": "プロンプトをインポート",
|
"Import Prompts": "プロンプトをインポート",
|
||||||
"Include --api flag when running stable-diffusion-webui": "stable-diffusion-webui を実行するときに --api フラグを含める",
|
"Include --api flag when running stable-diffusion-webui": "stable-diffusion-webui を実行するときに --api フラグを含める",
|
||||||
"Interface": "インターフェース",
|
"Interface": "インターフェース",
|
||||||
"join our Discord for help.": "ヘルプについては、Discord に参加してください。",
|
"join our Discord for help.": "ヘルプについては、Discord に参加してください。",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"JWT Expiration": "JWT 有効期限",
|
"JWT Expiration": "JWT 有効期限",
|
||||||
"JWT Token": "JWT トークン",
|
"JWT Token": "JWT トークン",
|
||||||
"Keep Alive": "キープアライブ",
|
"Keep Alive": "キープアライブ",
|
||||||
"Keyboard shortcuts": "キーボードショートカット",
|
"Keyboard shortcuts": "キーボードショートカット",
|
||||||
"Language": "言語",
|
"Language": "言語",
|
||||||
"Light": "ライト",
|
"Light": "ライト",
|
||||||
"Listening...": "聞いています...",
|
"Listening...": "聞いています...",
|
||||||
"LLMs can make mistakes. Verify important information.": "LLM は間違いを犯す可能性があります。重要な情報を検証してください。",
|
"LLMs can make mistakes. Verify important information.": "LLM は間違いを犯す可能性があります。重要な情報を検証してください。",
|
||||||
"Made by OpenWebUI Community": "OpenWebUI コミュニティによって作成",
|
"Made by OpenWebUI Community": "OpenWebUI コミュニティによって作成",
|
||||||
"Make sure to enclose them with": "必ず次で囲んでください",
|
"Make sure to enclose them with": "必ず次で囲んでください",
|
||||||
"Manage LiteLLM Models": "LiteLLM モデルを管理",
|
"Manage LiteLLM Models": "LiteLLM モデルを管理",
|
||||||
"Manage Models": "モデルを管理",
|
"Manage Models": "モデルを管理",
|
||||||
"Manage Ollama Models": "Ollama モデルを管理",
|
"Manage Ollama Models": "Ollama モデルを管理",
|
||||||
"Max Tokens": "最大トークン数",
|
"Max Tokens": "最大トークン数",
|
||||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。",
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。",
|
||||||
"Mirostat": "ミロスタット",
|
"Mirostat": "ミロスタット",
|
||||||
"Mirostat Eta": "ミロスタット Eta",
|
"Mirostat Eta": "ミロスタット Eta",
|
||||||
"Mirostat Tau": "ミロスタット Tau",
|
"Mirostat Tau": "ミロスタット Tau",
|
||||||
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
||||||
"Model '{{modelName}}' has been successfully downloaded.": "モデル '{{modelName}}' が正常にダウンロードされました。",
|
"Model '{{modelName}}' has been successfully downloaded.": "モデル '{{modelName}}' が正常にダウンロードされました。",
|
||||||
"Model '{{modelTag}}' is already in queue for downloading.": "モデル '{{modelTag}}' はすでにダウンロード待ち行列に入っています。",
|
"Model '{{modelTag}}' is already in queue for downloading.": "モデル '{{modelTag}}' はすでにダウンロード待ち行列に入っています。",
|
||||||
"Model {{modelId}} not found": "モデル {{modelId}} が見つかりません",
|
"Model {{modelId}} not found": "モデル {{modelId}} が見つかりません",
|
||||||
"Model {{modelName}} already exists.": "モデル {{modelName}} はすでに存在します。",
|
"Model {{modelName}} already exists.": "モデル {{modelName}} はすでに存在します。",
|
||||||
"Model Name": "モデル名",
|
"Model Name": "モデル名",
|
||||||
"Model not selected": "モデルが選択されていません",
|
"Model not selected": "モデルが選択されていません",
|
||||||
"Model Tag Name": "モデルタグ名",
|
"Model Tag Name": "モデルタグ名",
|
||||||
"Model Whitelisting": "モデルホワイトリスト",
|
"Model Whitelisting": "モデルホワイトリスト",
|
||||||
"Model(s) Whitelisted": "ホワイトリストに登録されたモデル",
|
"Model(s) Whitelisted": "ホワイトリストに登録されたモデル",
|
||||||
"Modelfile": "モデルファイル",
|
"Modelfile": "モデルファイル",
|
||||||
"Modelfile Advanced Settings": "モデルファイルの詳細設定",
|
"Modelfile Advanced Settings": "モデルファイルの詳細設定",
|
||||||
"Modelfile Content": "モデルファイルの内容",
|
"Modelfile Content": "モデルファイルの内容",
|
||||||
"Modelfiles": "モデルファイル",
|
"Modelfiles": "モデルファイル",
|
||||||
"Models": "モデル",
|
"Models": "モデル",
|
||||||
"My Documents": "マイ ドキュメント",
|
"My Documents": "マイ ドキュメント",
|
||||||
"My Modelfiles": "マイ モデルファイル",
|
"My Modelfiles": "マイ モデルファイル",
|
||||||
"My Prompts": "マイ プロンプト",
|
"My Prompts": "マイ プロンプト",
|
||||||
"Name": "名前",
|
"Name": "名前",
|
||||||
"Name Tag": "名前タグ",
|
"Name Tag": "名前タグ",
|
||||||
"Name your modelfile": "モデルファイルに名前を付ける",
|
"Name your modelfile": "モデルファイルに名前を付ける",
|
||||||
"New Chat": "新しいチャット",
|
"New Chat": "新しいチャット",
|
||||||
"New Password": "新しいパスワード",
|
"New Password": "新しいパスワード",
|
||||||
"Not sure what to add?": "何を追加すればよいかわからない?",
|
"Not sure what to add?": "何を追加すればよいかわからない?",
|
||||||
"Not sure what to write? Switch to": "何を書けばよいかわからない? 次に切り替える",
|
"Not sure what to write? Switch to": "何を書けばよいかわからない? 次に切り替える",
|
||||||
"Off": "オフ",
|
"Off": "オフ",
|
||||||
"Okay, Let's Go!": "OK、始めましょう!",
|
"Okay, Let's Go!": "OK、始めましょう!",
|
||||||
"Ollama Base URL": "Ollama ベース URL",
|
"Ollama Base URL": "Ollama ベース URL",
|
||||||
"Ollama Version": "Ollama バージョン",
|
"Ollama Version": "Ollama バージョン",
|
||||||
"On": "オン",
|
"On": "オン",
|
||||||
"Only": "のみ",
|
"Only": "のみ",
|
||||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "コマンド文字列には英数字とハイフンのみが許可されています。",
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "コマンド文字列には英数字とハイフンのみが許可されています。",
|
||||||
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "おっと! しばらくお待ちください! ファイルはまだ処理中です。完璧に仕上げていますので、しばらくお待ちください。準備ができたらお知らせします。",
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "おっと! しばらくお待ちください! ファイルはまだ処理中です。完璧に仕上げていますので、しばらくお待ちください。準備ができたらお知らせします。",
|
||||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "おっと! URL が無効なようです。もう一度確認してやり直してください。",
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "おっと! URL が無効なようです。もう一度確認してやり直してください。",
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "おっと! サポートされていない方法 (フロントエンドのみ) を使用しています。バックエンドから WebUI を提供してください。",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "おっと! サポートされていない方法 (フロントエンドのみ) を使用しています。バックエンドから WebUI を提供してください。",
|
||||||
"Open": "開く",
|
"Open": "開く",
|
||||||
"Open AI": "Open AI",
|
"Open AI": "Open AI",
|
||||||
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
||||||
"Open new chat": "新しいチャットを開く",
|
"Open new chat": "新しいチャットを開く",
|
||||||
"OpenAI API": "OpenAI API",
|
"OpenAI API": "OpenAI API",
|
||||||
"OpenAI API Key": "OpenAI API キー",
|
"OpenAI API Key": "OpenAI API キー",
|
||||||
"OpenAI API Key is required.": "OpenAI API キーが必要です。",
|
"OpenAI API Key is required.": "OpenAI API キーが必要です。",
|
||||||
"or": "または",
|
"or": "または",
|
||||||
"Parameters": "パラメーター",
|
"Parameters": "パラメーター",
|
||||||
"Password": "パスワード",
|
"Password": "パスワード",
|
||||||
"PDF Extract Images (OCR)": "PDF 画像抽出 (OCR)",
|
"PDF Extract Images (OCR)": "PDF 画像抽出 (OCR)",
|
||||||
"pending": "保留中",
|
"pending": "保留中",
|
||||||
"Permission denied when accessing microphone: {{error}}": "マイクへのアクセス時に権限が拒否されました: {{error}}",
|
"Permission denied when accessing microphone: {{error}}": "マイクへのアクセス時に権限が拒否されました: {{error}}",
|
||||||
"Playground": "プレイグラウンド",
|
"Playground": "プレイグラウンド",
|
||||||
"Profile": "プロフィール",
|
"Profile": "プロフィール",
|
||||||
"Prompt Content": "プロンプトの内容",
|
"Prompt Content": "プロンプトの内容",
|
||||||
"Prompt suggestions": "プロンプトの提案",
|
"Prompt suggestions": "プロンプトの提案",
|
||||||
"Prompts": "プロンプト",
|
"Prompts": "プロンプト",
|
||||||
"Pull a model from Ollama.com": "Ollama.com からモデルをプル",
|
"Pull a model from Ollama.com": "Ollama.com からモデルをプル",
|
||||||
"Pull Progress": "プルの進行状況",
|
"Pull Progress": "プルの進行状況",
|
||||||
"Query Params": "クエリパラメーター",
|
"Query Params": "クエリパラメーター",
|
||||||
"RAG Template": "RAG テンプレート",
|
"RAG Template": "RAG テンプレート",
|
||||||
"Raw Format": "Raw 形式",
|
"Raw Format": "Raw 形式",
|
||||||
"Record voice": "音声を録音",
|
"Record voice": "音声を録音",
|
||||||
"Redirecting you to OpenWebUI Community": "OpenWebUI コミュニティにリダイレクトしています",
|
"Redirecting you to OpenWebUI Community": "OpenWebUI コミュニティにリダイレクトしています",
|
||||||
"Release Notes": "リリースノート",
|
"Release Notes": "リリースノート",
|
||||||
"Repeat Last N": "最後の N を繰り返す",
|
"Repeat Last N": "最後の N を繰り返す",
|
||||||
"Repeat Penalty": "繰り返しペナルティ",
|
"Repeat Penalty": "繰り返しペナルティ",
|
||||||
"Request Mode": "リクエストモード",
|
"Request Mode": "リクエストモード",
|
||||||
"Reset Vector Storage": "ベクトルストレージをリセット",
|
"Reset Vector Storage": "ベクトルストレージをリセット",
|
||||||
"Response AutoCopy to Clipboard": "クリップボードへの応答の自動コピー",
|
"Response AutoCopy to Clipboard": "クリップボードへの応答の自動コピー",
|
||||||
"Role": "役割",
|
"Role": "役割",
|
||||||
"Rosé Pine": "Rosé Pine",
|
"Rosé Pine": "Rosé Pine",
|
||||||
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
"Save": "保存",
|
"Save": "保存",
|
||||||
"Save & Create": "保存して作成",
|
"Save & Create": "保存して作成",
|
||||||
"Save & Submit": "保存して送信",
|
"Save & Submit": "保存して送信",
|
||||||
"Save & Update": "保存して更新",
|
"Save & Update": "保存して更新",
|
||||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "チャットログをブラウザのストレージに直接保存する機能はサポートされなくなりました。下のボタンをクリックして、チャットログをダウンロードして削除してください。ご心配なく。チャットログは、次の方法でバックエンドに簡単に再インポートできます。",
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "チャットログをブラウザのストレージに直接保存する機能はサポートされなくなりました。下のボタンをクリックして、チャットログをダウンロードして削除してください。ご心配なく。チャットログは、次の方法でバックエンドに簡単に再インポートできます。",
|
||||||
"Scan": "スキャン",
|
"Scan": "スキャン",
|
||||||
"Scan complete!": "スキャン完了!",
|
"Scan complete!": "スキャン完了!",
|
||||||
"Scan for documents from {{path}}": "{{path}} からドキュメントをスキャン",
|
"Scan for documents from {{path}}": "{{path}} からドキュメントをスキャン",
|
||||||
"Search": "検索",
|
"Search": "検索",
|
||||||
"Search Documents": "ドキュメントを検索",
|
"Search Documents": "ドキュメントを検索",
|
||||||
"Search Prompts": "プロンプトを検索",
|
"Search Prompts": "プロンプトを検索",
|
||||||
"See readme.md for instructions": "手順については readme.md を参照してください",
|
"See readme.md for instructions": "手順については readme.md を参照してください",
|
||||||
"See what's new": "新機能を見る",
|
"See what's new": "新機能を見る",
|
||||||
"Seed": "シード",
|
"Seed": "シード",
|
||||||
"Select a mode": "モードを選択",
|
"Select a mode": "モードを選択",
|
||||||
"Select a model": "モデルを選択",
|
"Select a model": "モデルを選択",
|
||||||
"Select an Ollama instance": "Ollama インスタンスを選択",
|
"Select an Ollama instance": "Ollama インスタンスを選択",
|
||||||
"Send a Message": "メッセージを送信",
|
"Send a Message": "メッセージを送信",
|
||||||
"Send message": "メッセージを送信",
|
"Send message": "メッセージを送信",
|
||||||
"Server connection verified": "サーバー接続が確認されました",
|
"Server connection verified": "サーバー接続が確認されました",
|
||||||
"Set as default": "デフォルトに設定",
|
"Set as default": "デフォルトに設定",
|
||||||
"Set Default Model": "デフォルトモデルを設定",
|
"Set Default Model": "デフォルトモデルを設定",
|
||||||
"Set Image Size": "画像サイズを設定",
|
"Set Image Size": "画像サイズを設定",
|
||||||
"Set Steps": "ステップを設定",
|
"Set Steps": "ステップを設定",
|
||||||
"Set Title Auto-Generation Model": "タイトル自動生成モデルを設定",
|
"Set Title Auto-Generation Model": "タイトル自動生成モデルを設定",
|
||||||
"Set Voice": "音声を設定",
|
"Set Voice": "音声を設定",
|
||||||
"Settings": "設定",
|
"Settings": "設定",
|
||||||
"Settings saved successfully!": "設定が正常に保存されました!",
|
"Settings saved successfully!": "設定が正常に保存されました!",
|
||||||
"Share to OpenWebUI Community": "OpenWebUI コミュニティに共有",
|
"Share to OpenWebUI Community": "OpenWebUI コミュニティに共有",
|
||||||
"short-summary": "short-summary",
|
"short-summary": "short-summary",
|
||||||
"Show": "表示",
|
"Show": "表示",
|
||||||
"Show Additional Params": "追加パラメーターを表示",
|
"Show Additional Params": "追加パラメーターを表示",
|
||||||
"Show shortcuts": "表示",
|
"Show shortcuts": "表示",
|
||||||
"sidebar": "サイドバー",
|
"sidebar": "サイドバー",
|
||||||
"Sign in": "サインイン",
|
"Sign in": "サインイン",
|
||||||
"Sign Out": "サインアウト",
|
"Sign Out": "サインアウト",
|
||||||
"Sign up": "サインアップ",
|
"Sign up": "サインアップ",
|
||||||
"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
|
"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
|
||||||
"Speech-to-Text Engine": "音声テキスト変換エンジン",
|
"Speech-to-Text Engine": "音声テキスト変換エンジン",
|
||||||
"SpeechRecognition API is not supported in this browser.": "このブラウザでは SpeechRecognition API がサポートされていません。",
|
"SpeechRecognition API is not supported in this browser.": "このブラウザでは SpeechRecognition API がサポートされていません。",
|
||||||
"Stop Sequence": "ストップシーケンス",
|
"Stop Sequence": "ストップシーケンス",
|
||||||
"STT Settings": "STT 設定",
|
"STT Settings": "STT 設定",
|
||||||
"Submit": "送信",
|
"Submit": "送信",
|
||||||
"Success": "成功",
|
"Success": "成功",
|
||||||
"Successfully updated.": "正常に更新されました。",
|
"Successfully updated.": "正常に更新されました。",
|
||||||
"Sync All": "すべてを同期",
|
"Sync All": "すべてを同期",
|
||||||
"System": "システム",
|
"System": "システム",
|
||||||
"System Prompt": "システムプロンプト",
|
"System Prompt": "システムプロンプト",
|
||||||
"Tags": "タグ",
|
"Tags": "タグ",
|
||||||
"Temperature": "温度",
|
"Temperature": "温度",
|
||||||
"Template": "テンプレート",
|
"Template": "テンプレート",
|
||||||
"Text Completion": "テキスト補完",
|
"Text Completion": "テキスト補完",
|
||||||
"Text-to-Speech Engine": "テキスト音声変換エンジン",
|
"Text-to-Speech Engine": "テキスト音声変換エンジン",
|
||||||
"Tfs Z": "Tfs Z",
|
"Tfs Z": "Tfs Z",
|
||||||
"Theme": "テーマ",
|
"Theme": "テーマ",
|
||||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "これは、貴重な会話がバックエンドデータベースに安全に保存されることを保証します。ありがとうございます!",
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "これは、貴重な会話がバックエンドデータベースに安全に保存されることを保証します。ありがとうございます!",
|
||||||
"This setting does not sync across browsers or devices.": "この設定は、ブラウザやデバイス間で同期されません。",
|
"This setting does not sync across browsers or devices.": "この設定は、ブラウザやデバイス間で同期されません。",
|
||||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "ヒント: 各置換後にチャット入力で Tab キーを押すことで、複数の変数スロットを連続して更新できます。",
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "ヒント: 各置換後にチャット入力で Tab キーを押すことで、複数の変数スロットを連続して更新できます。",
|
||||||
"Title": "タイトル",
|
"Title": "タイトル",
|
||||||
"Title Auto-Generation": "タイトル自動生成",
|
"Title Auto-Generation": "タイトル自動生成",
|
||||||
"Title Generation Prompt": "タイトル生成プロンプト",
|
"Title Generation Prompt": "タイトル生成プロンプト",
|
||||||
"to": "まで",
|
"to": "まで",
|
||||||
"To access the available model names for downloading,": "ダウンロード可能なモデル名にアクセスするには、",
|
"To access the available model names for downloading,": "ダウンロード可能なモデル名にアクセスするには、",
|
||||||
"To access the GGUF models available for downloading,": "ダウンロード可能な GGUF モデルにアクセスするには、",
|
"To access the GGUF models available for downloading,": "ダウンロード可能な GGUF モデルにアクセスするには、",
|
||||||
"to chat input.": "チャット入力へ。",
|
"to chat input.": "チャット入力へ。",
|
||||||
"Toggle settings": "設定を切り替え",
|
"Toggle settings": "設定を切り替え",
|
||||||
"Toggle sidebar": "サイドバーを切り替え",
|
"Toggle sidebar": "サイドバーを切り替え",
|
||||||
"Top K": "トップ K",
|
"Top K": "トップ K",
|
||||||
"Top P": "トップ P",
|
"Top P": "トップ P",
|
||||||
"Trouble accessing Ollama?": "Ollama へのアクセスに問題がありますか?",
|
"Trouble accessing Ollama?": "Ollama へのアクセスに問題がありますか?",
|
||||||
"TTS Settings": "TTS 設定",
|
"TTS Settings": "TTS 設定",
|
||||||
"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ダウンロード) URL を入力してください",
|
"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ダウンロード) URL を入力してください",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "おっと! {{provider}} への接続に問題が発生しました。",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "おっと! {{provider}} への接続に問題が発生しました。",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "不明なファイルタイプ '{{file_type}}' ですが、プレーンテキストとして受け入れて処理します",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "不明なファイルタイプ '{{file_type}}' ですが、プレーンテキストとして受け入れて処理します",
|
||||||
"Update password": "パスワードを更新",
|
"Update password": "パスワードを更新",
|
||||||
"Upload a GGUF model": "GGUF モデルをアップロード",
|
"Upload a GGUF model": "GGUF モデルをアップロード",
|
||||||
"Upload files": "ファイルをアップロード",
|
"Upload files": "ファイルをアップロード",
|
||||||
"Upload Progress": "アップロードの進行状況",
|
"Upload Progress": "アップロードの進行状況",
|
||||||
"URL Mode": "URL モード",
|
"URL Mode": "URL モード",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "プロンプト入力で '#' を使用して、ドキュメントを読み込んで選択します。",
|
"Use '#' in the prompt input to load and select your documents.": "プロンプト入力で '#' を使用して、ドキュメントを読み込んで選択します。",
|
||||||
"Use Gravatar": "Gravatar を使用する",
|
"Use Gravatar": "Gravatar を使用する",
|
||||||
"user": "ユーザー",
|
"user": "ユーザー",
|
||||||
"User Permissions": "ユーザー権限",
|
"User Permissions": "ユーザー権限",
|
||||||
"Users": "ユーザー",
|
"Users": "ユーザー",
|
||||||
"Utilize": "活用",
|
"Utilize": "活用",
|
||||||
"Valid time units:": "有効な時間単位:",
|
"Valid time units:": "有効な時間単位:",
|
||||||
"variable": "変数",
|
"variable": "変数",
|
||||||
"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
|
"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
|
||||||
"Version": "バージョン",
|
"Version": "バージョン",
|
||||||
"Web": "ウェブ",
|
"Web": "ウェブ",
|
||||||
"WebUI Add-ons": "WebUI アドオン",
|
"WebUI Add-ons": "WebUI アドオン",
|
||||||
"WebUI Settings": "WebUI 設定",
|
"WebUI Settings": "WebUI 設定",
|
||||||
"WebUI will make requests to": "WebUI は次に対してリクエストを行います",
|
"WebUI will make requests to": "WebUI は次に対してリクエストを行います",
|
||||||
"What’s New in": "新機能",
|
"What’s New in": "新機能",
|
||||||
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "履歴が無効になっている場合、このブラウザでの新しいチャットは、どのデバイスの履歴にも表示されません。",
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "履歴が無効になっている場合、このブラウザでの新しいチャットは、どのデバイスの履歴にも表示されません。",
|
||||||
"Whisper (Local)": "Whisper (ローカル)",
|
"Whisper (Local)": "Whisper (ローカル)",
|
||||||
"Write a prompt suggestion (e.g. Who are you?)": "プロンプトの提案を書いてください (例: あなたは誰ですか?)",
|
"Write a prompt suggestion (e.g. Who are you?)": "プロンプトの提案を書いてください (例: あなたは誰ですか?)",
|
||||||
"Write a summary in 50 words that summarizes [topic or keyword].": "[トピックまたはキーワード] を要約する 50 語の概要を書いてください。",
|
"Write a summary in 50 words that summarizes [topic or keyword].": "[トピックまたはキーワード] を要約する 50 語の概要を書いてください。",
|
||||||
"You": "あなた",
|
"You": "あなた",
|
||||||
"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
|
"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
|
||||||
"You're now logged in.": "ログインしました。"
|
"You're now logged in.": "ログインしました。"
|
||||||
}
|
}
|
||||||
|
|
362
src/lib/i18n/locales/ko-KR/translation.json
Normal file
362
src/lib/i18n/locales/ko-KR/translation.json
Normal file
|
@ -0,0 +1,362 @@
|
||||||
|
{
|
||||||
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'초', '분', '시간', '일', '주' 또는 만료 없음 '-1'",
|
||||||
|
"(Beta)": "(Beta)",
|
||||||
|
"(e.g. `sh webui.sh --api`)": "(예: `sh webui.sh --api`)",
|
||||||
|
"(latest)": "(latest)",
|
||||||
|
"{{modelName}} is thinking...": "{{modelName}} 이(가) 생각중입니다....",
|
||||||
|
"{{webUIName}} Backend Required": "{{webUIName}} 백엔드가 필요합니다.",
|
||||||
|
"a user": "사용자",
|
||||||
|
"About": "소개",
|
||||||
|
"Account": "계정",
|
||||||
|
"Action": "액션",
|
||||||
|
"Add a model": "모델 추가",
|
||||||
|
"Add a model tag name": "모델 태그명 추가",
|
||||||
|
"Add a short description about what this modelfile does": "이 모델파일이 하는 일에 대한 간단한 설명 추가",
|
||||||
|
"Add a short title for this prompt": "이 프롬프트에 대한 간단한 제목 추가",
|
||||||
|
"Add a tag": "태그 추가",
|
||||||
|
"Add Docs": "문서 추가",
|
||||||
|
"Add Files": "파일 추가",
|
||||||
|
"Add message": "메시지 추가",
|
||||||
|
"add tags": "태그들 추가",
|
||||||
|
"Adjusting these settings will apply changes universally to all users.": "이 설정을 조정하면 모든 사용자에게 적용됩니다.",
|
||||||
|
"admin": "관리자",
|
||||||
|
"Admin Panel": "관리자 패널",
|
||||||
|
"Admin Settings": "관리자 설정",
|
||||||
|
"Advanced Parameters": "고급 매개변수",
|
||||||
|
"all": "모두",
|
||||||
|
"All Users": "모든 사용자",
|
||||||
|
"Allow": "허용",
|
||||||
|
"Allow Chat Deletion": "채팅 삭제 허용",
|
||||||
|
"alphanumeric characters and hyphens": "영문자,숫자 및 하이픈",
|
||||||
|
"Already have an account?": "이미 계정이 있으신가요?",
|
||||||
|
"an assistant": "어시스턴트",
|
||||||
|
"and": "그리고",
|
||||||
|
"API Base URL": "API 기본 URL",
|
||||||
|
"API Key": "API키",
|
||||||
|
"API RPM": "API RPM",
|
||||||
|
"are allowed - Activate this command by typing": "허용됩니다 - 이 명령을 활성화하려면 입력하세요.",
|
||||||
|
"Are you sure?": "확실합니까?",
|
||||||
|
"Audio": "오디오",
|
||||||
|
"Auto-playback response": "응답 자동 재생",
|
||||||
|
"Auto-send input after 3 sec.": "3초 후 입력 자동 전송",
|
||||||
|
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
|
||||||
|
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Base URL이 필요합니다.",
|
||||||
|
"available!": "사용 가능!",
|
||||||
|
"Back": "뒤로가기",
|
||||||
|
"Builder Mode": "빌더 모드",
|
||||||
|
"Cancel": "취소",
|
||||||
|
"Categories": "분류",
|
||||||
|
"Change Password": "비밀번호 변경",
|
||||||
|
"Chat": "채팅",
|
||||||
|
"Chat History": "채팅 기록",
|
||||||
|
"Chat History is off for this browser.": "이 브라우저에서 채팅 기록이 꺼져 있습니다.",
|
||||||
|
"Chats": "채팅",
|
||||||
|
"Check Again": "다시 확인",
|
||||||
|
"Check for updates": "업데이트 확인",
|
||||||
|
"Checking for updates...": "업데이트 확인중...",
|
||||||
|
"Choose a model before saving...": "저장하기 전에 모델을 선택하세요...",
|
||||||
|
"Chunk Overlap": "Chunk Overlap",
|
||||||
|
"Chunk Params": "Chunk Params",
|
||||||
|
"Chunk Size": "Chunk Size",
|
||||||
|
"Click here for help.": "도움말을 보려면 여기를 클릭하세요.",
|
||||||
|
"Click here to check other modelfiles.": "다른 모델파일을 확인하려면 여기를 클릭하세요.",
|
||||||
|
"Click here to select": "선택하려면 여기를 클릭하세요.",
|
||||||
|
"Click here to select documents.": "문서를 선택하려면 여기를 클릭하세요.",
|
||||||
|
"click here.": "여기를 클릭하세요.",
|
||||||
|
"Click on the user role button to change a user's role.": "사용자 역할 버튼을 클릭하여 사용자의 역할을 변경하세요.",
|
||||||
|
"Close": "닫기",
|
||||||
|
"Collection": "컬렉션",
|
||||||
|
"Command": "명령",
|
||||||
|
"Confirm Password": "비밀번호 확인",
|
||||||
|
"Connections": "연결",
|
||||||
|
"Content": "내용",
|
||||||
|
"Context Length": "내용 길이",
|
||||||
|
"Conversation Mode": "대화 모드",
|
||||||
|
"Copy last code block": "마지막 코드 블록 복사",
|
||||||
|
"Copy last response": "마지막 응답 복사",
|
||||||
|
"Copying to clipboard was successful!": "클립보드에 복사되었습니다!",
|
||||||
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "다음 질문에 대한 제목으로 간결한 3-5 단어 문구를 만드되 3-5 단어 제한을 엄격히 준수하고 'title' 단어 사용을 피하세요:",
|
||||||
|
"Create a modelfile": "모델파일 만들기",
|
||||||
|
"Create Account": "계정 만들기",
|
||||||
|
"Created at": "생성일",
|
||||||
|
"Created by": "생성자",
|
||||||
|
"Current Model": "현재 모델",
|
||||||
|
"Current Password": "현재 비밀번호",
|
||||||
|
"Custom": "사용자 정의",
|
||||||
|
"Customize Ollama models for a specific purpose": "특정 목적으로 Ollama 모델 사용자 정의",
|
||||||
|
"Dark": "어두운",
|
||||||
|
"Database": "데이터베이스",
|
||||||
|
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
||||||
|
"Default": "기본값",
|
||||||
|
"Default (Automatic1111)": "기본값 (Automatic1111)",
|
||||||
|
"Default (Web API)": "기본값 (Web API)",
|
||||||
|
"Default model updated": "기본 모델이 업데이트되었습니다.",
|
||||||
|
"Default Prompt Suggestions": "기본 프롬프트 제안",
|
||||||
|
"Default User Role": "기본 사용자 역할",
|
||||||
|
"delete": "삭제",
|
||||||
|
"Delete a model": "모델 삭제",
|
||||||
|
"Delete chat": "채팅 삭제",
|
||||||
|
"Delete Chats": "채팅들 삭제",
|
||||||
|
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} 삭제됨",
|
||||||
|
"Deleted {tagName}": "{tagName} 삭제됨",
|
||||||
|
"Description": "설명",
|
||||||
|
"Desktop Notifications": "알림",
|
||||||
|
"Disabled": "비활성화",
|
||||||
|
"Discover a modelfile": "모델파일 검색",
|
||||||
|
"Discover a prompt": "프롬프트 검색",
|
||||||
|
"Discover, download, and explore custom prompts": "사용자 정의 프롬프트 검색, 다운로드 및 탐색",
|
||||||
|
"Discover, download, and explore model presets": "모델 사전 설정 검색, 다운로드 및 탐색",
|
||||||
|
"Display the username instead of You in the Chat": "채팅에서 'You' 대신 사용자 이름 표시",
|
||||||
|
"Document": "문서",
|
||||||
|
"Document Settings": "문서 설정",
|
||||||
|
"Documents": "문서들",
|
||||||
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "어떠한 외부 연결도 하지 않으며, 데이터는 로컬에서 호스팅되는 서버에 안전하게 유지됩니다.",
|
||||||
|
"Don't Allow": "허용 안 함",
|
||||||
|
"Don't have an account?": "계정이 없으신가요?",
|
||||||
|
"Download as a File": "파일로 다운로드",
|
||||||
|
"Download Database": "데이터베이스 다운로드",
|
||||||
|
"Drop any files here to add to the conversation": "대화에 추가할 파일을 여기에 드롭하세요.",
|
||||||
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "예: '30s','10m'. 유효한 시간 단위는 's', 'm', 'h'입니다.",
|
||||||
|
"Edit Doc": "문서 편집",
|
||||||
|
"Edit User": "사용자 편집",
|
||||||
|
"Email": "이메일",
|
||||||
|
"Enable Chat History": "채팅 기록 활성화",
|
||||||
|
"Enable New Sign Ups": "새 회원가입 활성화",
|
||||||
|
"Enabled": "활성화",
|
||||||
|
"Enter {{role}} message here": "여기에 {{role}} 메시지 입력",
|
||||||
|
"Enter API Key": "API 키 입력",
|
||||||
|
"Enter Chunk Overlap": "청크 오버랩 입력",
|
||||||
|
"Enter Chunk Size": "청크 크기 입력",
|
||||||
|
"Enter Image Size (e.g. 512x512)": "이미지 크기 입력(예: 512x512)",
|
||||||
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "LiteLLM API 기본 URL 입력(litellm_params.api_base)",
|
||||||
|
"Enter LiteLLM API Key (litellm_params.api_key)": "LiteLLM API 키 입력(litellm_params.api_key)",
|
||||||
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "LiteLLM API RPM 입력(litellm_params.rpm)",
|
||||||
|
"Enter LiteLLM Model (litellm_params.model)": "LiteLLM 모델 입력(litellm_params.model)",
|
||||||
|
"Enter Max Tokens (litellm_params.max_tokens)": "최대 토큰 수 입력(litellm_params.max_tokens)",
|
||||||
|
"Enter model tag (e.g. {{modelTag}})": "모델 태그 입력(예: {{modelTag}})",
|
||||||
|
"Enter Number of Steps (e.g. 50)": "단계 수 입력(예: 50)",
|
||||||
|
"Enter stop sequence": "중지 시퀀스 입력",
|
||||||
|
"Enter Top K": "Top K 입력",
|
||||||
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "URL 입력(예: http://127.0.0.1:7860/)",
|
||||||
|
"Enter Your Email": "이메일 입력",
|
||||||
|
"Enter Your Full Name": "전체 이름 입력",
|
||||||
|
"Enter Your Password": "비밀번호 입력",
|
||||||
|
"Experimental": "실험적",
|
||||||
|
"Export All Chats (All Users)": "모든 채팅 내보내기 (모든 사용자)",
|
||||||
|
"Export Chats": "채팅 내보내기",
|
||||||
|
"Export Documents Mapping": "문서 매핑 내보내기",
|
||||||
|
"Export Modelfiles": "모델파일 내보내기",
|
||||||
|
"Export Prompts": "프롬프트 내보내기",
|
||||||
|
"Failed to read clipboard contents": "클립보드 내용을 읽는 데 실패했습니다.",
|
||||||
|
"File Mode": "파일 모드",
|
||||||
|
"File not found.": "파일을 찾을 수 없습니다.",
|
||||||
|
"Focus chat input": "채팅 입력 포커스",
|
||||||
|
"Format your variables using square brackets like this:": "이렇게 대괄호를 사용하여 변수를 형식화하세요:",
|
||||||
|
"From (Base Model)": "출처(기본 모델)",
|
||||||
|
"Full Screen Mode": "전체 화면 모드",
|
||||||
|
"General": "일반",
|
||||||
|
"General Settings": "일반 설정",
|
||||||
|
"Hello, {{name}}": "안녕하세요, {{name}}",
|
||||||
|
"Hide": "숨기기",
|
||||||
|
"Hide Additional Params": "추가 매개변수 숨기기",
|
||||||
|
"How can I help you today?": "오늘 어떻게 도와드릴까요?",
|
||||||
|
"Image Generation (Experimental)": "이미지 생성(실험적)",
|
||||||
|
"Image Generation Engine": "이미지 생성 엔진",
|
||||||
|
"Image Settings": "이미지 설정",
|
||||||
|
"Images": "이미지",
|
||||||
|
"Import Chats": "채팅 가져오기",
|
||||||
|
"Import Documents Mapping": "문서 매핑 가져오기",
|
||||||
|
"Import Modelfiles": "모델파일 가져오기",
|
||||||
|
"Import Prompts": "프롬프트 가져오기",
|
||||||
|
"Include --api flag when running stable-diffusion-webui": "stable-diffusion-webui를 실행할 때 --api 플래그 포함",
|
||||||
|
"Interface": "인터페이스",
|
||||||
|
"join our Discord for help.": "도움말을 보려면 Discord에 가입하세요.",
|
||||||
|
"JSON": "JSON",
|
||||||
|
"JWT Expiration": "JWT 만료",
|
||||||
|
"JWT Token": "JWT 토큰",
|
||||||
|
"Keep Alive": "계속 유지하기",
|
||||||
|
"Keyboard shortcuts": "키보드 단축키",
|
||||||
|
"Language": "언어",
|
||||||
|
"Light": "밝음",
|
||||||
|
"Listening...": "청취 중...",
|
||||||
|
"LLMs can make mistakes. Verify important information.": "LLM은 실수를 할 수 있습니다. 중요한 정보를 확인하세요.",
|
||||||
|
"Made by OpenWebUI Community": "OpenWebUI 커뮤니티에서 제작",
|
||||||
|
"Make sure to enclose them with": "다음으로 묶는 것을 잊지 마세요:",
|
||||||
|
"Manage LiteLLM Models": "LiteLLM 모델 관리",
|
||||||
|
"Manage Models": "모델 관리",
|
||||||
|
"Manage Ollama Models": "Ollama 모델 관리",
|
||||||
|
"Max Tokens": "최대 토큰 수",
|
||||||
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "최대 3개의 모델을 동시에 다운로드할 수 있습니다. 나중에 다시 시도하세요.",
|
||||||
|
"Mirostat": "Mirostat",
|
||||||
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
|
"Model '{{modelName}}' has been successfully downloaded.": "모델 '{{modelName}}'이(가) 성공적으로 다운로드되었습니다.",
|
||||||
|
"Model '{{modelTag}}' is already in queue for downloading.": "모델 '{{modelTag}}'이(가) 이미 다운로드 대기열에 있습니다.",
|
||||||
|
"Model {{modelId}} not found": "모델 {{modelId}}를 찾을 수 없습니다.",
|
||||||
|
"Model {{modelName}} already exists.": "모델 {{modelName}}이(가) 이미 존재합니다.",
|
||||||
|
"Model Name": "모델 이름",
|
||||||
|
"Model not selected": "모델이 선택되지 않았습니다.",
|
||||||
|
"Model Tag Name": "모델 태그 이름",
|
||||||
|
"Model Whitelisting": "모델 허용 목록",
|
||||||
|
"Model(s) Whitelisted": "허용된 모델",
|
||||||
|
"Modelfile": "모델파일",
|
||||||
|
"Modelfile Advanced Settings": "모델파일 고급 설정",
|
||||||
|
"Modelfile Content": "모델파일 내용",
|
||||||
|
"Modelfiles": "모델파일",
|
||||||
|
"Models": "모델",
|
||||||
|
"My Documents": "내 문서",
|
||||||
|
"My Modelfiles": "내 모델파일",
|
||||||
|
"My Prompts": "내 프롬프트",
|
||||||
|
"Name": "이름",
|
||||||
|
"Name Tag": "이름 태그",
|
||||||
|
"Name your modelfile": "모델파일 이름 지정",
|
||||||
|
"New Chat": "새 채팅",
|
||||||
|
"New Password": "새 비밀번호",
|
||||||
|
"Not sure what to add?": "추가할 것이 궁금하세요?",
|
||||||
|
"Not sure what to write? Switch to": "무엇을 쓸지 모르겠나요? 전환하세요.",
|
||||||
|
"Off": "끄기",
|
||||||
|
"Okay, Let's Go!": "그렇습니다, 시작합시다!",
|
||||||
|
"Ollama Base URL": "Ollama 기본 URL",
|
||||||
|
"Ollama Version": "Ollama 버전",
|
||||||
|
"On": "켜기",
|
||||||
|
"Only": "오직",
|
||||||
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "명령어 문자열에는 영문자, 숫자 및 하이픈만 허용됩니다.",
|
||||||
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "이런! 잠시만 기다려 주세요! 파일이 아직 처리 중입니다. 완벽하게 준비하고 있습니다. 잠시만 기다려주시면 준비가 되면 알려드리겠습니다.",
|
||||||
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "이런! URL이 잘못된 것 같습니다. 다시 한번 확인하고 다시 시도해주세요.",
|
||||||
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "이런! 지원되지 않는 방식(프론트엔드 전용)을 사용하고 계십니다. 백엔드에서 WebUI를 제공해주세요.",
|
||||||
|
"Open": "열기",
|
||||||
|
"Open AI": "Open AI",
|
||||||
|
"Open AI (Dall-E)": "OpenAI (Dall-E)",
|
||||||
|
"Open new chat": "새 채팅 열기",
|
||||||
|
"OpenAI API": "OpenAI API",
|
||||||
|
"OpenAI API Key": "OpenAI API 키",
|
||||||
|
"OpenAI API Key is required.": "OpenAI API 키가 필요합니다.",
|
||||||
|
"or": "또는",
|
||||||
|
"Parameters": "매개변수",
|
||||||
|
"Password": "비밀번호",
|
||||||
|
"PDF Extract Images (OCR)": "PDF에서 이미지 추출 (OCR)",
|
||||||
|
"pending": "보류 중",
|
||||||
|
"Permission denied when accessing microphone: {{error}}": "마이크 액세스가 거부되었습니다: {{error}}",
|
||||||
|
"Playground": "놀이터",
|
||||||
|
"Profile": "프로필",
|
||||||
|
"Prompt Content": "프롬프트 내용",
|
||||||
|
"Prompt suggestions": "프롬프트 제안",
|
||||||
|
"Prompts": "프롬프트",
|
||||||
|
"Pull a model from Ollama.com": "Ollama.com에서 모델 가져오기",
|
||||||
|
"Pull Progress": "가져오기 진행 상황",
|
||||||
|
"Query Params": "쿼리 매개변수",
|
||||||
|
"RAG Template": "RAG 템플릿",
|
||||||
|
"Raw Format": "Raw 형식",
|
||||||
|
"Record voice": "음성 녹음",
|
||||||
|
"Redirecting you to OpenWebUI Community": "OpenWebUI 커뮤니티로 리디렉션하는 중",
|
||||||
|
"Release Notes": "릴리스 노트",
|
||||||
|
"Repeat Last N": "마지막 N 반복",
|
||||||
|
"Repeat Penalty": "반복 패널티",
|
||||||
|
"Request Mode": "요청 모드",
|
||||||
|
"Reset Vector Storage": "벡터 스토리지 초기화",
|
||||||
|
"Response AutoCopy to Clipboard": "응답 자동 클립보드 복사",
|
||||||
|
"Role": "역할",
|
||||||
|
"Rosé Pine": "로제 파인",
|
||||||
|
"Rosé Pine Dawn": "로제 파인 던",
|
||||||
|
"Save": "저장",
|
||||||
|
"Save & Create": "저장 및 생성",
|
||||||
|
"Save & Submit": "저장 및 제출",
|
||||||
|
"Save & Update": "저장 및 업데이트",
|
||||||
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "브라우저의 저장소에 채팅 로그를 직접 저장하는 것은 더 이상 지원되지 않습니다. 아래 버튼을 클릭하여 채팅 로그를 다운로드하고 삭제하세요. 걱정 마세요. 백엔드를 통해 채팅 로그를 쉽게 다시 가져올 수 있습니다.",
|
||||||
|
"Scan": "스캔",
|
||||||
|
"Scan complete!": "스캔 완료!",
|
||||||
|
"Scan for documents from {{path}}": "{{path}}에서 문서 스캔",
|
||||||
|
"Search": "검색",
|
||||||
|
"Search Documents": "문서 검색",
|
||||||
|
"Search Prompts": "프롬프트 검색",
|
||||||
|
"See readme.md for instructions": "설명은 readme.md를 참조하세요.",
|
||||||
|
"See what's new": "새로운 기능 보기",
|
||||||
|
"Seed": "시드",
|
||||||
|
"Select a mode": "모드 선택",
|
||||||
|
"Select a model": "모델 선택",
|
||||||
|
"Select an Ollama instance": "Ollama 인스턴스 선택",
|
||||||
|
"Send a Message": "메시지 보내기",
|
||||||
|
"Send message": "메시지 보내기",
|
||||||
|
"Server connection verified": "서버 연결 확인됨",
|
||||||
|
"Set as default": "기본값으로 설정",
|
||||||
|
"Set Default Model": "기본 모델 설정",
|
||||||
|
"Set Image Size": "이미지 크기 설정",
|
||||||
|
"Set Steps": "단계 설정",
|
||||||
|
"Set Title Auto-Generation Model": "제목 자동 생성 모델 설정",
|
||||||
|
"Set Voice": "음성 설정",
|
||||||
|
"Settings": "설정",
|
||||||
|
"Settings saved successfully!": "설정이 성공적으로 저장되었습니다!",
|
||||||
|
"Share to OpenWebUI Community": "OpenWebUI 커뮤니티에 공유",
|
||||||
|
"short-summary": "간단한 요약",
|
||||||
|
"Show": "보이기",
|
||||||
|
"Show Additional Params": "추가 매개변수 보기",
|
||||||
|
"Show shortcuts": "단축키 보기",
|
||||||
|
"sidebar": "사이드바",
|
||||||
|
"Sign in": "로그인",
|
||||||
|
"Sign Out": "로그아웃",
|
||||||
|
"Sign up": "가입",
|
||||||
|
"Speech recognition error: {{error}}": "음성 인식 오류: {{error}}",
|
||||||
|
"Speech-to-Text Engine": "음성-텍스트 엔진",
|
||||||
|
"SpeechRecognition API is not supported in this browser.": "이 브라우저에서는 SpeechRecognition API를 지원하지 않습니다.",
|
||||||
|
"Stop Sequence": "중지 시퀀스",
|
||||||
|
"STT Settings": "STT 설정",
|
||||||
|
"Submit": "제출",
|
||||||
|
"Success": "성공",
|
||||||
|
"Successfully updated.": "성공적으로 업데이트되었습니다.",
|
||||||
|
"Sync All": "모두 동기화",
|
||||||
|
"System": "시스템",
|
||||||
|
"System Prompt": "시스템 프롬프트",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Temperature": "Temperature",
|
||||||
|
"Template": "Template",
|
||||||
|
"Text Completion": "텍스트 완성",
|
||||||
|
"Text-to-Speech Engine": "텍스트-음성 엔진",
|
||||||
|
"Tfs Z": "Tfs Z",
|
||||||
|
"Theme": "테마",
|
||||||
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "이렇게 하면 소중한 대화 내용이 백엔드 데이터베이스에 안전하게 저장됩니다. 감사합니다!",
|
||||||
|
"This setting does not sync across browsers or devices.": "이 설정은 브라우저 또는 장치 간에 동기화되지 않습니다.",
|
||||||
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "팁: 각 대체 후 채팅 입력에서 탭 키를 눌러 여러 개의 변수 슬롯을 연속적으로 업데이트하세요.",
|
||||||
|
"Title": "제목",
|
||||||
|
"Title Auto-Generation": "제목 자동 생성",
|
||||||
|
"Title Generation Prompt": "제목 생성 프롬프트",
|
||||||
|
"to": "~까지",
|
||||||
|
"To access the available model names for downloading,": "다운로드 가능한 모델명을 확인하려면,",
|
||||||
|
"To access the GGUF models available for downloading,": "다운로드 가능한 GGUF 모델을 확인하려면,",
|
||||||
|
"to chat input.": "채팅 입력으로.",
|
||||||
|
"Toggle settings": "설정 전환",
|
||||||
|
"Toggle sidebar": "사이드바 전환",
|
||||||
|
"Top K": "Top K",
|
||||||
|
"Top P": "Top P",
|
||||||
|
"Trouble accessing Ollama?": "Ollama에 접근하는 데 문제가 있나요?",
|
||||||
|
"TTS Settings": "TTS 설정",
|
||||||
|
"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (다운로드) URL 입력",
|
||||||
|
"Uh-oh! There was an issue connecting to {{provider}}.": "앗! {{provider}}에 연결하는 데 문제가 있었습니다.",
|
||||||
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "알 수 없는 파일 유형 '{{file_type}}', 하지만 일반 텍스트로 허용하고 처리합니다.",
|
||||||
|
"Update password": "비밀번호 업데이트",
|
||||||
|
"Upload a GGUF model": "GGUF 모델 업로드",
|
||||||
|
"Upload files": "파일 업로드",
|
||||||
|
"Upload Progress": "업로드 진행 상황",
|
||||||
|
"URL Mode": "URL 모드",
|
||||||
|
"Use '#' in the prompt input to load and select your documents.": "프롬프트 입력에서 '#'를 사용하여 문서를 로드하고 선택하세요.",
|
||||||
|
"Use Gravatar": "Gravatar 사용",
|
||||||
|
"user": "사용자",
|
||||||
|
"User Permissions": "사용자 권한",
|
||||||
|
"Users": "사용자",
|
||||||
|
"Utilize": "활용",
|
||||||
|
"Valid time units:": "유효한 시간 단위:",
|
||||||
|
"variable": "변수",
|
||||||
|
"variable to have them replaced with clipboard content.": "변수를 사용하여 클립보드 내용으로 바꾸세요.",
|
||||||
|
"Version": "버전",
|
||||||
|
"Web": "웹",
|
||||||
|
"WebUI Add-ons": "WebUI 애드온",
|
||||||
|
"WebUI Settings": "WebUI 설정",
|
||||||
|
"WebUI will make requests to": "WebUI가 요청할 대상:",
|
||||||
|
"What's New in": "새로운 기능",
|
||||||
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "기록 기능이 꺼져 있으면 이 브라우저의 새 채팅이 다른 장치의 채팅 기록에 나타나지 않습니다.",
|
||||||
|
"Whisper (Local)": "위스퍼 (Local)",
|
||||||
|
"Write a prompt suggestion (e.g. Who are you?)": "프롬프트 제안 작성 (예: 당신은 누구인가요?)",
|
||||||
|
"Write a summary in 50 words that summarizes [topic or keyword].": "[주제 또는 키워드]에 대한 50단어 요약문 작성.",
|
||||||
|
"You": "당신",
|
||||||
|
"You're a helpful assistant.": "당신은 유용한 어시스턴트입니다.",
|
||||||
|
"You're now logged in.": "로그인되었습니다."
|
||||||
|
}
|
|
@ -39,6 +39,10 @@
|
||||||
"code": "ja-JP",
|
"code": "ja-JP",
|
||||||
"title": "Japanese"
|
"title": "Japanese"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "ko-KR",
|
||||||
|
"title": "Korean"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "nl-NL",
|
"code": "nl-NL",
|
||||||
"title": "Dutch (Netherlands)"
|
"title": "Dutch (Netherlands)"
|
||||||
|
@ -47,10 +51,18 @@
|
||||||
"code": "pt-PT",
|
"code": "pt-PT",
|
||||||
"title": "Portuguese (Portugal)"
|
"title": "Portuguese (Portugal)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "pt-BR",
|
||||||
|
"title": "Portuguese (Brazil)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "ru-RU",
|
"code": "ru-RU",
|
||||||
"title": "Russian (Russia)"
|
"title": "Russian (Russia)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "tr-TR",
|
||||||
|
"title": "Turkish"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "uk-UA",
|
"code": "uk-UA",
|
||||||
"title": "Ukrainian"
|
"title": "Ukrainian"
|
||||||
|
@ -67,4 +79,4 @@
|
||||||
"code": "zh-TW",
|
"code": "zh-TW",
|
||||||
"title": "Chinese (Traditional)"
|
"title": "Chinese (Traditional)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"(latest)": "(nieuwste)",
|
"(latest)": "(nieuwste)",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} is aan het denken...",
|
"{{modelName}} is thinking...": "{{modelName}} is aan het denken...",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} Backend Verlpicht",
|
"{{webUIName}} Backend Required": "{{webUIName}} Backend Verlpicht",
|
||||||
"a user": "",
|
"a user": "een gebruiker",
|
||||||
"About": "Over",
|
"About": "Over",
|
||||||
"Account": "Account",
|
"Account": "Account",
|
||||||
"Action": "Actie",
|
"Action": "Actie",
|
||||||
|
@ -35,12 +35,12 @@
|
||||||
"API Key": "API Key",
|
"API Key": "API Key",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "API RPM",
|
||||||
"are allowed - Activate this command by typing": "zijn toegestaan - Activeer deze commando door te typen",
|
"are allowed - Activate this command by typing": "zijn toegestaan - Activeer deze commando door te typen",
|
||||||
"Are you sure?": "",
|
"Are you sure?": "Zeker weten?",
|
||||||
"Audio": "Audio",
|
"Audio": "Audio",
|
||||||
"Auto-playback response": "Automatisch afspelen van antwoord",
|
"Auto-playback response": "Automatisch afspelen van antwoord",
|
||||||
"Auto-send input after 3 sec.": "Automatisch verzenden van input na 3 sec.",
|
"Auto-send input after 3 sec.": "Automatisch verzenden van input na 3 sec.",
|
||||||
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
|
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Base URL",
|
||||||
"AUTOMATIC1111 Base URL is required.": "",
|
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Basis URL is verplicht",
|
||||||
"available!": "beschikbaar!",
|
"available!": "beschikbaar!",
|
||||||
"Back": "Terug",
|
"Back": "Terug",
|
||||||
"Builder Mode": "Bouwer Modus",
|
"Builder Mode": "Bouwer Modus",
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
"Chunk Size": "Chunk Grootte",
|
"Chunk Size": "Chunk Grootte",
|
||||||
"Click here for help.": "Klik hier voor help.",
|
"Click here for help.": "Klik hier voor help.",
|
||||||
"Click here to check other modelfiles.": "Klik hier om andere modelfiles te controleren.",
|
"Click here to check other modelfiles.": "Klik hier om andere modelfiles te controleren.",
|
||||||
"Click here to select": "",
|
"Click here to select": "Klik hier om te selecteren",
|
||||||
"Click here to select documents.": "",
|
"Click here to select documents.": "Klik hier om documenten te selecteren",
|
||||||
"click here.": "click here.",
|
"click here.": "click here.",
|
||||||
"Click on the user role button to change a user's role.": "Klik op de gebruikersrol knop om de rol van een gebruiker te wijzigen.",
|
"Click on the user role button to change a user's role.": "Klik op de gebruikersrol knop om de rol van een gebruiker te wijzigen.",
|
||||||
"Close": "Sluiten",
|
"Close": "Sluiten",
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
"Database": "Database",
|
"Database": "Database",
|
||||||
"DD/MM/YYYY HH:mm": "YYYY/MM/DD HH:mm",
|
"DD/MM/YYYY HH:mm": "YYYY/MM/DD HH:mm",
|
||||||
"Default": "Standaard",
|
"Default": "Standaard",
|
||||||
"Default (Automatic1111)": "",
|
"Default (Automatic1111)": "Standaard (Automatic1111)",
|
||||||
"Default (Web API)": "Standaard (Web API)",
|
"Default (Web API)": "Standaard (Web API)",
|
||||||
"Default model updated": "Standaard model bijgewerkt",
|
"Default model updated": "Standaard model bijgewerkt",
|
||||||
"Default Prompt Suggestions": "Standaard Prompt Suggesties",
|
"Default Prompt Suggestions": "Standaard Prompt Suggesties",
|
||||||
|
@ -123,21 +123,21 @@
|
||||||
"Enable Chat History": "Schakel Chat Geschiedenis in",
|
"Enable Chat History": "Schakel Chat Geschiedenis in",
|
||||||
"Enable New Sign Ups": "Schakel Nieuwe Registraties in",
|
"Enable New Sign Ups": "Schakel Nieuwe Registraties in",
|
||||||
"Enabled": "Ingeschakeld",
|
"Enabled": "Ingeschakeld",
|
||||||
"Enter {{role}} message here": "",
|
"Enter {{role}} message here": "Voeg {{role}} bericht hier toe",
|
||||||
"Enter API Key": "",
|
"Enter API Key": "Voeg API Key toe",
|
||||||
"Enter Chunk Overlap": "",
|
"Enter Chunk Overlap": "Voeg Chunk Overlap toe",
|
||||||
"Enter Chunk Size": "",
|
"Enter Chunk Size": "Voeg Chunk Size toe",
|
||||||
"Enter Image Size (e.g. 512x512)": "",
|
"Enter Image Size (e.g. 512x512)": "Voeg afbeelding formaat toe (Bijv. 512x512)",
|
||||||
"Enter LiteLLM API Base URL (litellm_params.api_base)": "",
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Voeg LiteLLM API Base URL toe (litellm_params.api_base)",
|
||||||
"Enter LiteLLM API Key (litellm_params.api_key)": "",
|
"Enter LiteLLM API Key (litellm_params.api_key)": "Voeg LiteLLM API Sleutel toe (litellm_params.api_key)",
|
||||||
"Enter LiteLLM API RPM (litellm_params.rpm)": "",
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "Voeg LiteLLM API RPM toe (litellm_params.rpm)",
|
||||||
"Enter LiteLLM Model (litellm_params.model)": "",
|
"Enter LiteLLM Model (litellm_params.model)": "Voeg LiteLLM Model toe (litellm_params.model)",
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "",
|
"Enter Max Tokens (litellm_params.max_tokens)": "Voeg maximum aantal tokens toe (litellm_params.max_tokens)",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "",
|
"Enter model tag (e.g. {{modelTag}})": "Voeg model tag toe (Bijv. {{modelTag}})",
|
||||||
"Enter Number of Steps (e.g. 50)": "",
|
"Enter Number of Steps (e.g. 50)": "Voeg aantal stappen toe (Bijv. 50)",
|
||||||
"Enter stop sequence": "Zet stop sequentie",
|
"Enter stop sequence": "Zet stop sequentie",
|
||||||
"Enter Top K": "",
|
"Enter Top K": "Voeg Top K toe",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "Zet URL (Bijv. http://127.0.0.1:7860/)",
|
||||||
"Enter Your Email": "Voer je Email in",
|
"Enter Your Email": "Voer je Email in",
|
||||||
"Enter Your Full Name": "Voer je Volledige Naam in",
|
"Enter Your Full Name": "Voer je Volledige Naam in",
|
||||||
"Enter Your Password": "Voer je Wachtwoord in",
|
"Enter Your Password": "Voer je Wachtwoord in",
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
"Hide Additional Params": "Verberg Extra Params",
|
"Hide Additional Params": "Verberg Extra Params",
|
||||||
"How can I help you today?": "Hoe kan ik je vandaag helpen?",
|
"How can I help you today?": "Hoe kan ik je vandaag helpen?",
|
||||||
"Image Generation (Experimental)": "Afbeelding Generatie (Experimenteel)",
|
"Image Generation (Experimental)": "Afbeelding Generatie (Experimenteel)",
|
||||||
"Image Generation Engine": "",
|
"Image Generation Engine": "Afbeelding Generatie Engine",
|
||||||
"Image Settings": "Afbeelding Instellingen",
|
"Image Settings": "Afbeelding Instellingen",
|
||||||
"Images": "Afbeeldingen",
|
"Images": "Afbeeldingen",
|
||||||
"Import Chats": "Importeer Chats",
|
"Import Chats": "Importeer Chats",
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
"Not sure what to write? Switch to": "Niet zeker wat te schrijven? Schakel over naar",
|
"Not sure what to write? Switch to": "Niet zeker wat te schrijven? Schakel over naar",
|
||||||
"Off": "Uit",
|
"Off": "Uit",
|
||||||
"Okay, Let's Go!": "Okay, Laten we gaan!",
|
"Okay, Let's Go!": "Okay, Laten we gaan!",
|
||||||
"Ollama Base URL": "",
|
"Ollama Base URL": "Ollama Basis URL",
|
||||||
"Ollama Version": "Ollama Versie",
|
"Ollama Version": "Ollama Versie",
|
||||||
"On": "Aan",
|
"On": "Aan",
|
||||||
"Only": "Alleen",
|
"Only": "Alleen",
|
||||||
|
@ -227,11 +227,11 @@
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! Je gebruikt een niet-ondersteunde methode (alleen frontend). Serveer de WebUI vanuit de backend.",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oops! Je gebruikt een niet-ondersteunde methode (alleen frontend). Serveer de WebUI vanuit de backend.",
|
||||||
"Open": "Open",
|
"Open": "Open",
|
||||||
"Open AI": "Open AI",
|
"Open AI": "Open AI",
|
||||||
"Open AI (Dall-E)": "",
|
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
||||||
"Open new chat": "Open nieuwe chat",
|
"Open new chat": "Open nieuwe chat",
|
||||||
"OpenAI API": "OpenAI API",
|
"OpenAI API": "OpenAI API",
|
||||||
"OpenAI API Key": "",
|
"OpenAI API Key": "OpenAI API Sleutel",
|
||||||
"OpenAI API Key is required.": "",
|
"OpenAI API Key is required.": "OpenAI API Sleutel is verplicht",
|
||||||
"or": "of",
|
"or": "of",
|
||||||
"Parameters": "Parameters",
|
"Parameters": "Parameters",
|
||||||
"Password": "Wachtwoord",
|
"Password": "Wachtwoord",
|
||||||
|
@ -273,9 +273,9 @@
|
||||||
"See readme.md for instructions": "Zie readme.md voor instructies",
|
"See readme.md for instructions": "Zie readme.md voor instructies",
|
||||||
"See what's new": "Zie wat er nieuw is",
|
"See what's new": "Zie wat er nieuw is",
|
||||||
"Seed": "Seed",
|
"Seed": "Seed",
|
||||||
"Select a mode": "",
|
"Select a mode": "Selecteer een modus",
|
||||||
"Select a model": "Selecteer een model",
|
"Select a model": "Selecteer een model",
|
||||||
"Select an Ollama instance": "",
|
"Select an Ollama instance": "Selecteer een Ollama instantie",
|
||||||
"Send a Message": "Stuur een Bericht",
|
"Send a Message": "Stuur een Bericht",
|
||||||
"Send message": "Stuur bericht",
|
"Send message": "Stuur bericht",
|
||||||
"Server connection verified": "Server verbinding geverifieerd",
|
"Server connection verified": "Server verbinding geverifieerd",
|
||||||
|
@ -330,7 +330,7 @@
|
||||||
"Top P": "Top P",
|
"Top P": "Top P",
|
||||||
"Trouble accessing Ollama?": "Problemen met toegang tot Ollama?",
|
"Trouble accessing Ollama?": "Problemen met toegang tot Ollama?",
|
||||||
"TTS Settings": "TTS instellingen",
|
"TTS Settings": "TTS instellingen",
|
||||||
"Type Hugging Face Resolve (Download) URL": "",
|
"Type Hugging Face Resolve (Download) URL": "Type Hugging Face Resolve (Download) URL",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Er was een probleem met verbinden met {{provider}}.",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Er was een probleem met verbinden met {{provider}}.",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Onbekend Bestandstype '{{file_type}}', maar accepteren en behandelen als platte tekst",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Onbekend Bestandstype '{{file_type}}', maar accepteren en behandelen als platte tekst",
|
||||||
"Update password": "Wijzig wachtwoord",
|
"Update password": "Wijzig wachtwoord",
|
||||||
|
@ -339,7 +339,7 @@
|
||||||
"Upload Progress": "Upload Voortgang",
|
"Upload Progress": "Upload Voortgang",
|
||||||
"URL Mode": "URL Modus",
|
"URL Mode": "URL Modus",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "Gebruik '#' in de prompt input om je documenten te laden en te selecteren.",
|
"Use '#' in the prompt input to load and select your documents.": "Gebruik '#' in de prompt input om je documenten te laden en te selecteren.",
|
||||||
"Use Gravatar": "",
|
"Use Gravatar": "Gebruik Gravatar",
|
||||||
"user": "user",
|
"user": "user",
|
||||||
"User Permissions": "Gebruikers Rechten",
|
"User Permissions": "Gebruikers Rechten",
|
||||||
"Users": "Gebruikers",
|
"Users": "Gebruikers",
|
||||||
|
|
363
src/lib/i18n/locales/pt-BR/translation.json
Normal file
363
src/lib/i18n/locales/pt-BR/translation.json
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
{
|
||||||
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 's' ou '-1' para não expirar.",
|
||||||
|
"(Beta)": "(Beta)",
|
||||||
|
"(e.g. `sh webui.sh --api`)": "(por exemplo, `sh webui.sh --api`)",
|
||||||
|
"(latest)": "(mais recente)",
|
||||||
|
"{{modelName}} is thinking...": "{{modelName}} está pensando...",
|
||||||
|
"{{webUIName}} Backend Required": "{{webUIName}} Backend Necessário",
|
||||||
|
"a user": "um usuário",
|
||||||
|
"About": "Sobre",
|
||||||
|
"Account": "Conta",
|
||||||
|
"Action": "Ação",
|
||||||
|
"Add a model": "Adicionar um modelo",
|
||||||
|
"Add a model tag name": "Adicionar um nome de tag de modelo",
|
||||||
|
"Add a short description about what this modelfile does": "Adicione uma breve descrição sobre o que este arquivo de modelo faz",
|
||||||
|
"Add a short title for this prompt": "Adicione um título curto para este prompt",
|
||||||
|
"Add a tag": "Adicionar uma tag",
|
||||||
|
"Add Docs": "Adicionar Documentos",
|
||||||
|
"Add Files": "Adicionar Arquivos",
|
||||||
|
"Add message": "Adicionar mensagem",
|
||||||
|
"add tags": "adicionar tags",
|
||||||
|
"Adjusting these settings will apply changes universally to all users.": "Ajustar essas configurações aplicará alterações universalmente a todos os usuários.",
|
||||||
|
"admin": "administrador",
|
||||||
|
"Admin Panel": "Painel do Administrador",
|
||||||
|
"Admin Settings": "Configurações do Administrador",
|
||||||
|
"Advanced Parameters": "Parâmetros Avançados",
|
||||||
|
"all": "todos",
|
||||||
|
"All Users": "Todos os Usuários",
|
||||||
|
"Allow": "Permitir",
|
||||||
|
"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
|
||||||
|
"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
|
||||||
|
"Already have an account?": "Já tem uma conta?",
|
||||||
|
"an assistant": "um assistente",
|
||||||
|
"and": "e",
|
||||||
|
"API Base URL": "URL Base da API",
|
||||||
|
"API Key": "Chave da API",
|
||||||
|
"API RPM": "API RPM",
|
||||||
|
"are allowed - Activate this command by typing": "são permitidos - Ative este comando digitando",
|
||||||
|
"Are you sure?": "Tem certeza?",
|
||||||
|
"Audio": "Áudio",
|
||||||
|
"Auto-playback response": "Reprodução automática da resposta",
|
||||||
|
"Auto-send input after 3 sec.": "Enviar entrada automaticamente após 3 segundos.",
|
||||||
|
"AUTOMATIC1111 Base URL": "URL Base do AUTOMATIC1111",
|
||||||
|
"AUTOMATIC1111 Base URL is required.": "A URL Base do AUTOMATIC1111 é obrigatória.",
|
||||||
|
"available!": "disponível!",
|
||||||
|
"Back": "Voltar",
|
||||||
|
"Builder Mode": "Modo de Construtor",
|
||||||
|
"Cancel": "Cancelar",
|
||||||
|
"Categories": "Categorias",
|
||||||
|
"Change Password": "Alterar Senha",
|
||||||
|
"Chat": "Bate-papo",
|
||||||
|
"Chat History": "Histórico de Bate-papo",
|
||||||
|
"Chat History is off for this browser.": "O histórico de bate-papo está desativado para este navegador.",
|
||||||
|
"Chats": "Bate-papos",
|
||||||
|
"Check Again": "Verifique novamente",
|
||||||
|
"Check for updates": "Verificar atualizações",
|
||||||
|
"Checking for updates...": "Verificando atualizações...",
|
||||||
|
"Choose a model before saving...": "Escolha um modelo antes de salvar...",
|
||||||
|
"Chunk Overlap": "Sobreposição de Fragmento",
|
||||||
|
"Chunk Params": "Parâmetros de Fragmento",
|
||||||
|
"Chunk Size": "Tamanho do Fragmento",
|
||||||
|
"Click here for help.": "Clique aqui para obter ajuda.",
|
||||||
|
"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
|
||||||
|
"Click here to select": "Clique aqui para selecionar",
|
||||||
|
"Click here to select documents.": "Clique aqui para selecionar documentos.",
|
||||||
|
"click here.": "clique aqui.",
|
||||||
|
"Click on the user role button to change a user's role.": "Clique no botão de função do usuário para alterar a função de um usuário.",
|
||||||
|
"Close": "Fechar",
|
||||||
|
"Collection": "Coleção",
|
||||||
|
"Command": "Comando",
|
||||||
|
"Confirm Password": "Confirmar Senha",
|
||||||
|
"Connections": "Conexões",
|
||||||
|
"Content": "Conteúdo",
|
||||||
|
"Context Length": "Comprimento do Contexto",
|
||||||
|
"Conversation Mode": "Modo de Conversa",
|
||||||
|
"Copy last code block": "Copiar último bloco de código",
|
||||||
|
"Copy last response": "Copiar última resposta",
|
||||||
|
"Copying to clipboard was successful!": "Cópia para a área de transferência bem-sucedida!",
|
||||||
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crie uma frase concisa de 3 a 5 palavras como cabeçalho para a seguinte consulta, aderindo estritamente ao limite de 3 a 5 palavras e evitando o uso da palavra 'título':",
|
||||||
|
"Create a modelfile": "Criar um arquivo de modelo",
|
||||||
|
"Create Account": "Criar Conta",
|
||||||
|
"Created at": "Criado em",
|
||||||
|
"Created by": "Criado por",
|
||||||
|
"Current Model": "Modelo Atual",
|
||||||
|
"Current Password": "Senha Atual",
|
||||||
|
"Custom": "Personalizado",
|
||||||
|
"Customize Ollama models for a specific purpose": "Personalize os modelos Ollama para um propósito específico",
|
||||||
|
"Dark": "Escuro",
|
||||||
|
"Database": "Banco de dados",
|
||||||
|
"DD/MM/YYYY HH:mm": "DD/MM/AAAA HH:mm",
|
||||||
|
"Default": "Padrão",
|
||||||
|
"Default (Automatic1111)": "Padrão (Automatic1111)",
|
||||||
|
"Default (Web API)": "Padrão (API Web)",
|
||||||
|
"Default model updated": "Modelo padrão atualizado",
|
||||||
|
"Default Prompt Suggestions": "Sugestões de Prompt Padrão",
|
||||||
|
"Default User Role": "Função de Usuário Padrão",
|
||||||
|
"delete": "excluir",
|
||||||
|
"Delete a model": "Excluir um modelo",
|
||||||
|
"Delete chat": "Excluir bate-papo",
|
||||||
|
"Delete Chats": "Excluir Bate-papos",
|
||||||
|
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} excluído",
|
||||||
|
"Deleted {tagName}": "{tagName} excluído",
|
||||||
|
"Description": "Descrição",
|
||||||
|
"Desktop Notifications": "Notificações da Área de Trabalho",
|
||||||
|
"Disabled": "Desativado",
|
||||||
|
"Discover a modelfile": "Descobrir um arquivo de modelo",
|
||||||
|
"Discover a prompt": "Descobrir um prompt",
|
||||||
|
"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
|
||||||
|
"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
|
||||||
|
"Display the username instead of You in the Chat": "Exibir o nome de usuário em vez de Você no Bate-papo",
|
||||||
|
"Document": "Documento",
|
||||||
|
"Document Settings": "Configurações de Documento",
|
||||||
|
"Documents": "Documentos",
|
||||||
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e seus dados permanecem seguros em seu servidor hospedado localmente.",
|
||||||
|
"Don't Allow": "Não Permitir",
|
||||||
|
"Don't have an account?": "Não tem uma conta?",
|
||||||
|
"Download as a File": "Baixar como Arquivo",
|
||||||
|
"Download Database": "Baixar Banco de Dados",
|
||||||
|
"Drop any files here to add to the conversation": "Solte os arquivos aqui para adicionar à conversa",
|
||||||
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.",
|
||||||
|
"Edit Doc": "Editar Documento",
|
||||||
|
"Edit User": "Editar Usuário",
|
||||||
|
"Email": "E-mail",
|
||||||
|
"Enable Chat History": "Ativar Histórico de Bate-papo",
|
||||||
|
"Enable New Sign Ups": "Ativar Novas Inscrições",
|
||||||
|
"Enabled": "Ativado",
|
||||||
|
"Enter {{role}} message here": "Digite a mensagem de {{role}} aqui",
|
||||||
|
"Enter API Key": "Digite a Chave da API",
|
||||||
|
"Enter Chunk Overlap": "Digite a Sobreposição de Fragmento",
|
||||||
|
"Enter Chunk Size": "Digite o Tamanho do Fragmento",
|
||||||
|
"Enter Image Size (e.g. 512x512)": "Digite o Tamanho da Imagem (por exemplo, 512x512)",
|
||||||
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Digite a URL Base da API LiteLLM (litellm_params.api_base)",
|
||||||
|
"Enter LiteLLM API Key (litellm_params.api_key)": "Digite a Chave da API LiteLLM (litellm_params.api_key)",
|
||||||
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "Digite o RPM da API LiteLLM (litellm_params.rpm)",
|
||||||
|
"Enter LiteLLM Model (litellm_params.model)": "Digite o Modelo LiteLLM (litellm_params.model)",
|
||||||
|
"Enter Max Tokens (litellm_params.max_tokens)": "Digite o Máximo de Tokens (litellm_params.max_tokens)",
|
||||||
|
"Enter model tag (e.g. {{modelTag}})": "Digite a tag do modelo (por exemplo, {{modelTag}})",
|
||||||
|
"Enter Number of Steps (e.g. 50)": "Digite o Número de Etapas (por exemplo, 50)",
|
||||||
|
"Enter stop sequence": "Digite a sequência de parada",
|
||||||
|
"Enter Top K": "Digite o Top K",
|
||||||
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "Digite a URL (por exemplo, http://127.0.0.1:7860/)",
|
||||||
|
"Enter Your Email": "Digite seu E-mail",
|
||||||
|
"Enter Your Full Name": "Digite seu Nome Completo",
|
||||||
|
"Enter Your Password": "Digite sua Senha",
|
||||||
|
"Experimental": "Experimental",
|
||||||
|
"Export All Chats (All Users)": "Exportar Todos os Bate-papos (Todos os Usuários)",
|
||||||
|
"Export Chats": "Exportar Bate-papos",
|
||||||
|
"Export Documents Mapping": "Exportar Mapeamento de Documentos",
|
||||||
|
"Export Modelfiles": "Exportar Arquivos de Modelo",
|
||||||
|
"Export Prompts": "Exportar Prompts",
|
||||||
|
"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
|
||||||
|
"File Mode": "Modo de Arquivo",
|
||||||
|
"File not found.": "Arquivo não encontrado.",
|
||||||
|
"Focus chat input": "Focar entrada de bate-papo",
|
||||||
|
"Format your variables using square brackets like this:": "Formate suas variáveis usando colchetes como este:",
|
||||||
|
"From (Base Model)": "De (Modelo Base)",
|
||||||
|
"Full Screen Mode": "Modo de Tela Cheia",
|
||||||
|
"General": "Geral",
|
||||||
|
"General Settings": "Configurações Gerais",
|
||||||
|
"Hello, {{name}}": "Olá, {{name}}",
|
||||||
|
"Hide": "Ocultar",
|
||||||
|
"Hide Additional Params": "Ocultar Parâmetros Adicionais",
|
||||||
|
"How can I help you today?": "Como posso ajudá-lo hoje?",
|
||||||
|
"Image Generation (Experimental)": "Geração de Imagens (Experimental)",
|
||||||
|
"Image Generation Engine": "Mecanismo de Geração de Imagens",
|
||||||
|
"Image Settings": "Configurações de Imagem",
|
||||||
|
"Images": "Imagens",
|
||||||
|
"Import Chats": "Importar Bate-papos",
|
||||||
|
"Import Documents Mapping": "Importar Mapeamento de Documentos",
|
||||||
|
"Import Modelfiles": "Importar Arquivos de Modelo",
|
||||||
|
"Import Prompts": "Importar Prompts",
|
||||||
|
"Include `--api` flag when running stable-diffusion-webui": "Inclua a flag `--api` ao executar stable-diffusion-webui",
|
||||||
|
"Interface": "Interface",
|
||||||
|
"join our Discord for help.": "junte-se ao nosso Discord para obter ajuda.",
|
||||||
|
"JSON": "JSON",
|
||||||
|
"JWT Expiration": "Expiração JWT",
|
||||||
|
"JWT Token": "Token JWT",
|
||||||
|
"Keep Alive": "Manter Vivo",
|
||||||
|
"Keyboard shortcuts": "Atalhos de teclado",
|
||||||
|
"Language": "Idioma",
|
||||||
|
"Light": "Claro",
|
||||||
|
"Listening...": "Ouvindo...",
|
||||||
|
"LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.",
|
||||||
|
"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
|
||||||
|
"Make sure to enclose them with": "Certifique-se de colocá-los entre",
|
||||||
|
"Manage LiteLLM Models": "Gerenciar Modelos LiteLLM",
|
||||||
|
"Manage Models": "Gerenciar Modelos",
|
||||||
|
"Manage Ollama Models": "Gerenciar Modelos Ollama",
|
||||||
|
"Max Tokens": "Máximo de Tokens",
|
||||||
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Máximo de 3 modelos podem ser baixados simultaneamente. Tente novamente mais tarde.",
|
||||||
|
"Mirostat": "Mirostat",
|
||||||
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
|
"MMMM DD, YYYY": "MMMM DD, AAAA",
|
||||||
|
"Model '{{modelName}}' has been successfully downloaded.": "O modelo '{{modelName}}' foi baixado com sucesso.",
|
||||||
|
"Model '{{modelTag}}' is already in queue for downloading.": "O modelo '{{modelTag}}' já está na fila para download.",
|
||||||
|
"Model {{modelId}} not found": "Modelo {{modelId}} não encontrado",
|
||||||
|
"Model {{modelName}} already exists.": "O modelo {{modelName}} já existe.",
|
||||||
|
"Model Name": "Nome do Modelo",
|
||||||
|
"Model not selected": "Modelo não selecionado",
|
||||||
|
"Model Tag Name": "Nome da Tag do Modelo",
|
||||||
|
"Model Whitelisting": "Lista de Permissões de Modelo",
|
||||||
|
"Model(s) Whitelisted": "Modelo(s) na Lista de Permissões",
|
||||||
|
"Modelfile": "Arquivo de Modelo",
|
||||||
|
"Modelfile Advanced Settings": "Configurações Avançadas do Arquivo de Modelo",
|
||||||
|
"Modelfile Content": "Conteúdo do Arquivo de Modelo",
|
||||||
|
"Modelfiles": "Arquivos de Modelo",
|
||||||
|
"Models": "Modelos",
|
||||||
|
"My Documents": "Meus Documentos",
|
||||||
|
"My Modelfiles": "Meus Arquivos de Modelo",
|
||||||
|
"My Prompts": "Meus Prompts",
|
||||||
|
"Name": "Nome",
|
||||||
|
"Name Tag": "Nome da Tag",
|
||||||
|
"Name your modelfile": "Nomeie seu arquivo de modelo",
|
||||||
|
"New Chat": "Novo Bate-papo",
|
||||||
|
"New Password": "Nova Senha",
|
||||||
|
"Not sure what to add?": "Não tem certeza do que adicionar?",
|
||||||
|
"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
|
||||||
|
"Off": "Desligado",
|
||||||
|
"Okay, Let's Go!": "Ok, Vamos Lá!",
|
||||||
|
"Ollama Base URL": "URL Base do Ollama",
|
||||||
|
"Ollama Version": "Versão do Ollama",
|
||||||
|
"On": "Ligado",
|
||||||
|
"Only": "Somente",
|
||||||
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "Somente caracteres alfanuméricos e hífens são permitidos na string de comando.",
|
||||||
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Opa! Aguente firme! Seus arquivos ainda estão no forno de processamento. Estamos cozinhando-os com perfeição. Por favor, seja paciente e avisaremos quando estiverem prontos.",
|
||||||
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Opa! Parece que a URL é inválida. Verifique novamente e tente outra vez.",
|
||||||
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Opa! Você está usando um método não suportado (somente frontend). Por favor, sirva o WebUI a partir do backend.",
|
||||||
|
"Open": "Abrir",
|
||||||
|
"Open AI": "OpenAI",
|
||||||
|
"Open AI (Dall-E)": "OpenAI (Dall-E)",
|
||||||
|
"Open new chat": "Abrir novo bate-papo",
|
||||||
|
"OpenAI API": "API OpenAI",
|
||||||
|
"OpenAI API Key": "Chave da API OpenAI",
|
||||||
|
"OpenAI API Key is required.": "A Chave da API OpenAI é obrigatória.",
|
||||||
|
"or": "ou",
|
||||||
|
"Parameters": "Parâmetros",
|
||||||
|
"Password": "Senha",
|
||||||
|
"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
|
||||||
|
"pending": "pendente",
|
||||||
|
"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
|
||||||
|
"Playground": "Playground",
|
||||||
|
"Profile": "Perfil",
|
||||||
|
"Prompt Content": "Conteúdo do Prompt",
|
||||||
|
"Prompt suggestions": "Sugestões de Prompt",
|
||||||
|
"Prompts": "Prompts",
|
||||||
|
"Pull a model from Ollama.com": "Extrair um modelo do Ollama.com",
|
||||||
|
"Pull Progress": "Progresso da Extração",
|
||||||
|
"Query Params": "Parâmetros de Consulta",
|
||||||
|
"RAG Template": "Modelo RAG",
|
||||||
|
"Raw Format": "Formato Bruto",
|
||||||
|
"Record voice": "Gravar voz",
|
||||||
|
"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
|
||||||
|
"Release Notes": "Notas de Lançamento",
|
||||||
|
"Repeat Last N": "Repetir Últimos N",
|
||||||
|
"Repeat Penalty": "Penalidade de Repetição",
|
||||||
|
"Request Mode": "Modo de Solicitação",
|
||||||
|
"Reset Vector Storage": "Redefinir Armazenamento de Vetor",
|
||||||
|
"Response AutoCopy to Clipboard": "Cópia Automática da Resposta para a Área de Transferência",
|
||||||
|
"Role": "Função",
|
||||||
|
"Rosé Pine": "Rosé Pine",
|
||||||
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
|
"Save": "Salvar",
|
||||||
|
"Save & Create": "Salvar e Criar",
|
||||||
|
"Save & Submit": "Salvar e Enviar",
|
||||||
|
"Save & Update": "Salvar e Atualizar",
|
||||||
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Salvar logs de bate-papo diretamente no armazenamento do seu navegador não é mais suportado. Reserve um momento para baixar e excluir seus logs de bate-papo clicando no botão abaixo. Não se preocupe, você pode facilmente reimportar seus logs de bate-papo para o backend através de",
|
||||||
|
"Scan": "Digitalizar",
|
||||||
|
"Scan complete!": "Digitalização concluída!",
|
||||||
|
"Scan for documents from {{path}}": "Digitalizar documentos de {{path}}",
|
||||||
|
"Search": "Pesquisar",
|
||||||
|
"Search Documents": "Pesquisar Documentos",
|
||||||
|
"Search Prompts": "Pesquisar Prompts",
|
||||||
|
"See readme.md for instructions": "Consulte readme.md para obter instruções",
|
||||||
|
"See what's new": "Veja o que há de novo",
|
||||||
|
"Seed": "Semente",
|
||||||
|
"Select a mode": "Selecione um modo",
|
||||||
|
"Select a model": "Selecione um modelo",
|
||||||
|
"Select an Ollama instance": "Selecione uma instância Ollama",
|
||||||
|
"Send a Message": "Enviar uma Mensagem",
|
||||||
|
"Send message": "Enviar mensagem",
|
||||||
|
"Server connection verified": "Conexão com o servidor verificada",
|
||||||
|
"Set as default": "Definir como padrão",
|
||||||
|
"Set Default Model": "Definir Modelo Padrão",
|
||||||
|
"Set Image Size": "Definir Tamanho da Imagem",
|
||||||
|
"Set Steps": "Definir Etapas",
|
||||||
|
"Set Title Auto-Generation Model": "Definir Modelo de Geração Automática de Título",
|
||||||
|
"Set Voice": "Definir Voz",
|
||||||
|
"Settings": "Configurações",
|
||||||
|
"Settings saved successfully!": "Configurações salvas com sucesso!",
|
||||||
|
"Share to OpenWebUI Community": "Compartilhar com a Comunidade OpenWebUI",
|
||||||
|
"short-summary": "resumo-curto",
|
||||||
|
"Show": "Mostrar",
|
||||||
|
"Show Additional Params": "Mostrar Parâmetros Adicionais",
|
||||||
|
"Show shortcuts": "Mostrar",
|
||||||
|
"sidebar": "barra lateral",
|
||||||
|
"Sign in": "Entrar",
|
||||||
|
"Sign Out": "Sair",
|
||||||
|
"Sign up": "Inscrever-se",
|
||||||
|
"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
|
||||||
|
"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
|
||||||
|
"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
|
||||||
|
"Stop Sequence": "Sequência de Parada",
|
||||||
|
"STT Settings": "Configurações STT",
|
||||||
|
"Submit": "Enviar",
|
||||||
|
"Success": "Sucesso",
|
||||||
|
"Successfully updated.": "Atualizado com sucesso.",
|
||||||
|
"Sync All": "Sincronizar Tudo",
|
||||||
|
"System": "Sistema",
|
||||||
|
"System Prompt": "Prompt do Sistema",
|
||||||
|
"Tags": "Tags",
|
||||||
|
"Temperature": "Temperatura",
|
||||||
|
"Template": "Modelo",
|
||||||
|
"Text Completion": "Complemento de Texto",
|
||||||
|
"Text-to-Speech Engine": "Mecanismo de Texto para Fala",
|
||||||
|
"Tfs Z": "Tfs Z",
|
||||||
|
"Theme": "Tema",
|
||||||
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isso garante que suas conversas valiosas sejam salvas com segurança em seu banco de dados de backend. Obrigado!",
|
||||||
|
"This setting does not sync across browsers or devices.": "Esta configuração não sincroniza entre navegadores ou dispositivos.",
|
||||||
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Dica: Atualize vários slots de variáveis consecutivamente pressionando a tecla Tab na entrada de bate-papo após cada substituição.",
|
||||||
|
"Title": "Título",
|
||||||
|
"Title Auto-Generation": "Geração Automática de Título",
|
||||||
|
"Title Generation Prompt": "Prompt de Geração de Título",
|
||||||
|
"to": "para",
|
||||||
|
"To access the available model names for downloading,": "Para acessar os nomes de modelo disponíveis para download,",
|
||||||
|
"To access the GGUF models available for downloading,": "Para acessar os modelos GGUF disponíveis para download,",
|
||||||
|
"to chat input.": "para a entrada de bate-papo.",
|
||||||
|
"Toggle settings": "Alternar configurações",
|
||||||
|
"Toggle sidebar": "Alternar barra lateral",
|
||||||
|
"Top K": "Top K",
|
||||||
|
"Top P": "Top P",
|
||||||
|
"Trouble accessing Ollama?": "Problemas para acessar o Ollama?",
|
||||||
|
"TTS Settings": "Configurações TTS",
|
||||||
|
"Type Hugging Face Resolve (Download) URL": "Digite a URL do Hugging Face Resolve (Download)",
|
||||||
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Opa! Houve um problema ao conectar-se a {{provider}}.",
|
||||||
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Tipo de arquivo desconhecido '{{file_type}}', mas aceitando e tratando como texto simples",
|
||||||
|
"Update password": "Atualizar senha",
|
||||||
|
"Upload a GGUF model": "Carregar um modelo GGUF",
|
||||||
|
"Upload files": "Carregar arquivos",
|
||||||
|
"Upload Progress": "Progresso do Carregamento",
|
||||||
|
"URL Mode": "Modo de URL",
|
||||||
|
"Use '#' in the prompt input to load and select your documents.": "Use '#' na entrada do prompt para carregar e selecionar seus documentos.",
|
||||||
|
"Use Gravatar": "Usar Gravatar",
|
||||||
|
"user": "usuário",
|
||||||
|
"User Permissions": "Permissões do Usuário",
|
||||||
|
"Users": "Usuários",
|
||||||
|
"Utilize": "Utilizar",
|
||||||
|
"Valid time units:": "Unidades de tempo válidas:",
|
||||||
|
"variable": "variável",
|
||||||
|
"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
|
||||||
|
"Version": "Versão",
|
||||||
|
"Web": "Web",
|
||||||
|
"WebUI Add-ons": "Complementos WebUI",
|
||||||
|
"WebUI Settings": "Configurações WebUI",
|
||||||
|
"WebUI will make requests to": "WebUI fará solicitações para",
|
||||||
|
"What’s New in": "O que há de novo em",
|
||||||
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando o histórico está desativado, novos bate-papos neste navegador não aparecerão em seu histórico em nenhum dos seus dispositivos.",
|
||||||
|
"Whisper (Local)": "Whisper (Local)",
|
||||||
|
"Write a prompt suggestion (e.g. Who are you?)": "Escreva uma sugestão de prompt (por exemplo, Quem é você?)",
|
||||||
|
"Write a summary in 50 words that summarizes [topic or keyword].": "Escreva um resumo em 50 palavras que resuma [tópico ou palavra-chave].",
|
||||||
|
"You": "Você",
|
||||||
|
"You're a helpful assistant.": "Você é um assistente útil.",
|
||||||
|
"You're now logged in.": "Você está conectado agora."
|
||||||
|
}
|
|
@ -1,363 +1,363 @@
|
||||||
{
|
{
|
||||||
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 's' ou '-1' para nenhuma expiração.",
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 's' ou '-1' para nenhuma expiração.",
|
||||||
"(Beta)": "(Beta)",
|
"(Beta)": "(Beta)",
|
||||||
"(e.g. `sh webui.sh --api`)": "(por exemplo, `sh webui.sh --api`)",
|
"(e.g. `sh webui.sh --api`)": "(por exemplo, `sh webui.sh --api`)",
|
||||||
"(latest)": "(mais recente)",
|
"(latest)": "(mais recente)",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} está pensando...",
|
"{{modelName}} is thinking...": "{{modelName}} está pensando...",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} Backend Necessário",
|
"{{webUIName}} Backend Required": "{{webUIName}} Backend Necessário",
|
||||||
"a user": "um usuário",
|
"a user": "um usuário",
|
||||||
"About": "Sobre",
|
"About": "Sobre",
|
||||||
"Account": "Conta",
|
"Account": "Conta",
|
||||||
"Action": "Ação",
|
"Action": "Ação",
|
||||||
"Add a model": "Adicionar um modelo",
|
"Add a model": "Adicionar um modelo",
|
||||||
"Add a model tag name": "Adicionar um nome de tag de modelo",
|
"Add a model tag name": "Adicionar um nome de tag de modelo",
|
||||||
"Add a short description about what this modelfile does": "Adicione uma breve descrição sobre o que este arquivo de modelo faz",
|
"Add a short description about what this modelfile does": "Adicione uma breve descrição sobre o que este arquivo de modelo faz",
|
||||||
"Add a short title for this prompt": "Adicione um título curto para este prompt",
|
"Add a short title for this prompt": "Adicione um título curto para este prompt",
|
||||||
"Add a tag": "Adicionar uma tag",
|
"Add a tag": "Adicionar uma tag",
|
||||||
"Add Docs": "Adicionar Documentos",
|
"Add Docs": "Adicionar Documentos",
|
||||||
"Add Files": "Adicionar Arquivos",
|
"Add Files": "Adicionar Arquivos",
|
||||||
"Add message": "Adicionar mensagem",
|
"Add message": "Adicionar mensagem",
|
||||||
"add tags": "adicionar tags",
|
"add tags": "adicionar tags",
|
||||||
"Adjusting these settings will apply changes universally to all users.": "Ajustar essas configurações aplicará alterações universalmente a todos os usuários.",
|
"Adjusting these settings will apply changes universally to all users.": "Ajustar essas configurações aplicará alterações universalmente a todos os usuários.",
|
||||||
"admin": "administrador",
|
"admin": "administrador",
|
||||||
"Admin Panel": "Painel do Administrador",
|
"Admin Panel": "Painel do Administrador",
|
||||||
"Admin Settings": "Configurações do Administrador",
|
"Admin Settings": "Configurações do Administrador",
|
||||||
"Advanced Parameters": "Parâmetros Avançados",
|
"Advanced Parameters": "Parâmetros Avançados",
|
||||||
"all": "todos",
|
"all": "todos",
|
||||||
"All Users": "Todos os Usuários",
|
"All Users": "Todos os Usuários",
|
||||||
"Allow": "Permitir",
|
"Allow": "Permitir",
|
||||||
"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
|
"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
|
||||||
"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
|
"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
|
||||||
"Already have an account?": "Já tem uma conta?",
|
"Already have an account?": "Já tem uma conta?",
|
||||||
"an assistant": "um assistente",
|
"an assistant": "um assistente",
|
||||||
"and": "e",
|
"and": "e",
|
||||||
"API Base URL": "URL Base da API",
|
"API Base URL": "URL Base da API",
|
||||||
"API Key": "Chave da API",
|
"API Key": "Chave da API",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "API RPM",
|
||||||
"are allowed - Activate this command by typing": "são permitidos - Ative este comando digitando",
|
"are allowed - Activate this command by typing": "são permitidos - Ative este comando digitando",
|
||||||
"Are you sure?": "Tem certeza?",
|
"Are you sure?": "Tem certeza?",
|
||||||
"Audio": "Áudio",
|
"Audio": "Áudio",
|
||||||
"Auto-playback response": "Reprodução automática da resposta",
|
"Auto-playback response": "Reprodução automática da resposta",
|
||||||
"Auto-send input after 3 sec.": "Enviar entrada automaticamente após 3 segundos.",
|
"Auto-send input after 3 sec.": "Enviar entrada automaticamente após 3 segundos.",
|
||||||
"AUTOMATIC1111 Base URL": "URL Base do AUTOMATIC1111",
|
"AUTOMATIC1111 Base URL": "URL Base do AUTOMATIC1111",
|
||||||
"AUTOMATIC1111 Base URL is required.": "A URL Base do AUTOMATIC1111 é obrigatória.",
|
"AUTOMATIC1111 Base URL is required.": "A URL Base do AUTOMATIC1111 é obrigatória.",
|
||||||
"available!": "disponível!",
|
"available!": "disponível!",
|
||||||
"Back": "Voltar",
|
"Back": "Voltar",
|
||||||
"Builder Mode": "Modo de Construtor",
|
"Builder Mode": "Modo de Construtor",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
"Categories": "Categorias",
|
"Categories": "Categorias",
|
||||||
"Change Password": "Alterar Senha",
|
"Change Password": "Alterar Senha",
|
||||||
"Chat": "Bate-papo",
|
"Chat": "Bate-papo",
|
||||||
"Chat History": "Histórico de Bate-papo",
|
"Chat History": "Histórico de Bate-papo",
|
||||||
"Chat History is off for this browser.": "O histórico de bate-papo está desativado para este navegador.",
|
"Chat History is off for this browser.": "O histórico de bate-papo está desativado para este navegador.",
|
||||||
"Chats": "Bate-papos",
|
"Chats": "Bate-papos",
|
||||||
"Check Again": "Verifique novamente",
|
"Check Again": "Verifique novamente",
|
||||||
"Check for updates": "Verificar atualizações",
|
"Check for updates": "Verificar atualizações",
|
||||||
"Checking for updates...": "Verificando atualizações...",
|
"Checking for updates...": "Verificando atualizações...",
|
||||||
"Choose a model before saving...": "Escolha um modelo antes de salvar...",
|
"Choose a model before saving...": "Escolha um modelo antes de salvar...",
|
||||||
"Chunk Overlap": "Sobreposição de Fragmento",
|
"Chunk Overlap": "Sobreposição de Fragmento",
|
||||||
"Chunk Params": "Parâmetros de Fragmento",
|
"Chunk Params": "Parâmetros de Fragmento",
|
||||||
"Chunk Size": "Tamanho do Fragmento",
|
"Chunk Size": "Tamanho do Fragmento",
|
||||||
"Click here for help.": "Clique aqui para obter ajuda.",
|
"Click here for help.": "Clique aqui para obter ajuda.",
|
||||||
"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
|
"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
|
||||||
"Click here to select": "Clique aqui para selecionar",
|
"Click here to select": "Clique aqui para selecionar",
|
||||||
"Click here to select documents.": "Clique aqui para selecionar documentos.",
|
"Click here to select documents.": "Clique aqui para selecionar documentos.",
|
||||||
"click here.": "clique aqui.",
|
"click here.": "clique aqui.",
|
||||||
"Click on the user role button to change a user's role.": "Clique no botão de função do usuário para alterar a função de um usuário.",
|
"Click on the user role button to change a user's role.": "Clique no botão de função do usuário para alterar a função de um usuário.",
|
||||||
"Close": "Fechar",
|
"Close": "Fechar",
|
||||||
"Collection": "Coleção",
|
"Collection": "Coleção",
|
||||||
"Command": "Comando",
|
"Command": "Comando",
|
||||||
"Confirm Password": "Confirmar Senha",
|
"Confirm Password": "Confirmar Senha",
|
||||||
"Connections": "Conexões",
|
"Connections": "Conexões",
|
||||||
"Content": "Conteúdo",
|
"Content": "Conteúdo",
|
||||||
"Context Length": "Comprimento do Contexto",
|
"Context Length": "Comprimento do Contexto",
|
||||||
"Conversation Mode": "Modo de Conversa",
|
"Conversation Mode": "Modo de Conversa",
|
||||||
"Copy last code block": "Copiar último bloco de código",
|
"Copy last code block": "Copiar último bloco de código",
|
||||||
"Copy last response": "Copiar última resposta",
|
"Copy last response": "Copiar última resposta",
|
||||||
"Copying to clipboard was successful!": "Cópia para a área de transferência bem-sucedida!",
|
"Copying to clipboard was successful!": "Cópia para a área de transferência bem-sucedida!",
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crie uma frase concisa de 3 a 5 palavras como cabeçalho para a seguinte consulta, aderindo estritamente ao limite de 3 a 5 palavras e evitando o uso da palavra 'título':",
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Crie uma frase concisa de 3 a 5 palavras como cabeçalho para a seguinte consulta, aderindo estritamente ao limite de 3 a 5 palavras e evitando o uso da palavra 'título':",
|
||||||
"Create a modelfile": "Criar um arquivo de modelo",
|
"Create a modelfile": "Criar um arquivo de modelo",
|
||||||
"Create Account": "Criar Conta",
|
"Create Account": "Criar Conta",
|
||||||
"Created at": "Criado em",
|
"Created at": "Criado em",
|
||||||
"Created by": "Criado por",
|
"Created by": "Criado por",
|
||||||
"Current Model": "Modelo Atual",
|
"Current Model": "Modelo Atual",
|
||||||
"Current Password": "Senha Atual",
|
"Current Password": "Senha Atual",
|
||||||
"Custom": "Personalizado",
|
"Custom": "Personalizado",
|
||||||
"Customize Ollama models for a specific purpose": "Personalize os modelos Ollama para um propósito específico",
|
"Customize Ollama models for a specific purpose": "Personalize os modelos Ollama para um propósito específico",
|
||||||
"Dark": "Escuro",
|
"Dark": "Escuro",
|
||||||
"Database": "Banco de dados",
|
"Database": "Banco de dados",
|
||||||
"DD/MM/YYYY HH:mm": "DD/MM/AAAA HH:mm",
|
"DD/MM/YYYY HH:mm": "DD/MM/AAAA HH:mm",
|
||||||
"Default": "Padrão",
|
"Default": "Padrão",
|
||||||
"Default (Automatic1111)": "Padrão (Automatic1111)",
|
"Default (Automatic1111)": "Padrão (Automatic1111)",
|
||||||
"Default (Web API)": "Padrão (API Web)",
|
"Default (Web API)": "Padrão (API Web)",
|
||||||
"Default model updated": "Modelo padrão atualizado",
|
"Default model updated": "Modelo padrão atualizado",
|
||||||
"Default Prompt Suggestions": "Sugestões de Prompt Padrão",
|
"Default Prompt Suggestions": "Sugestões de Prompt Padrão",
|
||||||
"Default User Role": "Função de Usuário Padrão",
|
"Default User Role": "Função de Usuário Padrão",
|
||||||
"delete": "excluir",
|
"delete": "excluir",
|
||||||
"Delete a model": "Excluir um modelo",
|
"Delete a model": "Excluir um modelo",
|
||||||
"Delete chat": "Excluir bate-papo",
|
"Delete chat": "Excluir bate-papo",
|
||||||
"Delete Chats": "Excluir Bate-papos",
|
"Delete Chats": "Excluir Bate-papos",
|
||||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} excluído",
|
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} excluído",
|
||||||
"Deleted {tagName}": "{tagName} excluído",
|
"Deleted {tagName}": "{tagName} excluído",
|
||||||
"Description": "Descrição",
|
"Description": "Descrição",
|
||||||
"Desktop Notifications": "Notificações da Área de Trabalho",
|
"Desktop Notifications": "Notificações da Área de Trabalho",
|
||||||
"Disabled": "Desativado",
|
"Disabled": "Desativado",
|
||||||
"Discover a modelfile": "Descobrir um arquivo de modelo",
|
"Discover a modelfile": "Descobrir um arquivo de modelo",
|
||||||
"Discover a prompt": "Descobrir um prompt",
|
"Discover a prompt": "Descobrir um prompt",
|
||||||
"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
|
"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
|
||||||
"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
|
"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
|
||||||
"Display the username instead of You in the Chat": "Exibir o nome de usuário em vez de Você no Bate-papo",
|
"Display the username instead of You in the Chat": "Exibir o nome de usuário em vez de Você no Bate-papo",
|
||||||
"Document": "Documento",
|
"Document": "Documento",
|
||||||
"Document Settings": "Configurações de Documento",
|
"Document Settings": "Configurações de Documento",
|
||||||
"Documents": "Documentos",
|
"Documents": "Documentos",
|
||||||
"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e seus dados permanecem seguros em seu servidor hospedado localmente.",
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "não faz conexões externas e seus dados permanecem seguros em seu servidor hospedado localmente.",
|
||||||
"Don't Allow": "Não Permitir",
|
"Don't Allow": "Não Permitir",
|
||||||
"Don't have an account?": "Não tem uma conta?",
|
"Don't have an account?": "Não tem uma conta?",
|
||||||
"Download as a File": "Baixar como Arquivo",
|
"Download as a File": "Baixar como Arquivo",
|
||||||
"Download Database": "Baixar Banco de Dados",
|
"Download Database": "Baixar Banco de Dados",
|
||||||
"Drop any files here to add to the conversation": "Solte os arquivos aqui para adicionar à conversa",
|
"Drop any files here to add to the conversation": "Solte os arquivos aqui para adicionar à conversa",
|
||||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.",
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "por exemplo, '30s', '10m'. Unidades de tempo válidas são 's', 'm', 'h'.",
|
||||||
"Edit Doc": "Editar Documento",
|
"Edit Doc": "Editar Documento",
|
||||||
"Edit User": "Editar Usuário",
|
"Edit User": "Editar Usuário",
|
||||||
"Email": "E-mail",
|
"Email": "E-mail",
|
||||||
"Enable Chat History": "Ativar Histórico de Bate-papo",
|
"Enable Chat History": "Ativar Histórico de Bate-papo",
|
||||||
"Enable New Sign Ups": "Ativar Novas Inscrições",
|
"Enable New Sign Ups": "Ativar Novas Inscrições",
|
||||||
"Enabled": "Ativado",
|
"Enabled": "Ativado",
|
||||||
"Enter {{role}} message here": "Digite a mensagem de {{role}} aqui",
|
"Enter {{role}} message here": "Digite a mensagem de {{role}} aqui",
|
||||||
"Enter API Key": "Digite a Chave da API",
|
"Enter API Key": "Digite a Chave da API",
|
||||||
"Enter Chunk Overlap": "Digite a Sobreposição de Fragmento",
|
"Enter Chunk Overlap": "Digite a Sobreposição de Fragmento",
|
||||||
"Enter Chunk Size": "Digite o Tamanho do Fragmento",
|
"Enter Chunk Size": "Digite o Tamanho do Fragmento",
|
||||||
"Enter Image Size (e.g. 512x512)": "Digite o Tamanho da Imagem (por exemplo, 512x512)",
|
"Enter Image Size (e.g. 512x512)": "Digite o Tamanho da Imagem (por exemplo, 512x512)",
|
||||||
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Digite a URL Base da API LiteLLM (litellm_params.api_base)",
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Digite a URL Base da API LiteLLM (litellm_params.api_base)",
|
||||||
"Enter LiteLLM API Key (litellm_params.api_key)": "Digite a Chave da API LiteLLM (litellm_params.api_key)",
|
"Enter LiteLLM API Key (litellm_params.api_key)": "Digite a Chave da API LiteLLM (litellm_params.api_key)",
|
||||||
"Enter LiteLLM API RPM (litellm_params.rpm)": "Digite o RPM da API LiteLLM (litellm_params.rpm)",
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "Digite o RPM da API LiteLLM (litellm_params.rpm)",
|
||||||
"Enter LiteLLM Model (litellm_params.model)": "Digite o Modelo LiteLLM (litellm_params.model)",
|
"Enter LiteLLM Model (litellm_params.model)": "Digite o Modelo LiteLLM (litellm_params.model)",
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "Digite o Máximo de Tokens (litellm_params.max_tokens)",
|
"Enter Max Tokens (litellm_params.max_tokens)": "Digite o Máximo de Tokens (litellm_params.max_tokens)",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "Digite a tag do modelo (por exemplo, {{modelTag}})",
|
"Enter model tag (e.g. {{modelTag}})": "Digite a tag do modelo (por exemplo, {{modelTag}})",
|
||||||
"Enter Number of Steps (e.g. 50)": "Digite o Número de Etapas (por exemplo, 50)",
|
"Enter Number of Steps (e.g. 50)": "Digite o Número de Etapas (por exemplo, 50)",
|
||||||
"Enter stop sequence": "Digite a sequência de parada",
|
"Enter stop sequence": "Digite a sequência de parada",
|
||||||
"Enter Top K": "Digite o Top K",
|
"Enter Top K": "Digite o Top K",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "Digite a URL (por exemplo, http://127.0.0.1:7860/)",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "Digite a URL (por exemplo, http://127.0.0.1:7860/)",
|
||||||
"Enter Your Email": "Digite seu E-mail",
|
"Enter Your Email": "Digite seu E-mail",
|
||||||
"Enter Your Full Name": "Digite seu Nome Completo",
|
"Enter Your Full Name": "Digite seu Nome Completo",
|
||||||
"Enter Your Password": "Digite sua Senha",
|
"Enter Your Password": "Digite sua Senha",
|
||||||
"Experimental": "Experimental",
|
"Experimental": "Experimental",
|
||||||
"Export All Chats (All Users)": "Exportar Todos os Bate-papos (Todos os Usuários)",
|
"Export All Chats (All Users)": "Exportar Todos os Bate-papos (Todos os Usuários)",
|
||||||
"Export Chats": "Exportar Bate-papos",
|
"Export Chats": "Exportar Bate-papos",
|
||||||
"Export Documents Mapping": "Exportar Mapeamento de Documentos",
|
"Export Documents Mapping": "Exportar Mapeamento de Documentos",
|
||||||
"Export Modelfiles": "Exportar Arquivos de Modelo",
|
"Export Modelfiles": "Exportar Arquivos de Modelo",
|
||||||
"Export Prompts": "Exportar Prompts",
|
"Export Prompts": "Exportar Prompts",
|
||||||
"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
|
"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
|
||||||
"File Mode": "Modo de Arquivo",
|
"File Mode": "Modo de Arquivo",
|
||||||
"File not found.": "Arquivo não encontrado.",
|
"File not found.": "Arquivo não encontrado.",
|
||||||
"Focus chat input": "Focar entrada de bate-papo",
|
"Focus chat input": "Focar entrada de bate-papo",
|
||||||
"Format your variables using square brackets like this:": "Formate suas variáveis usando colchetes como este:",
|
"Format your variables using square brackets like this:": "Formate suas variáveis usando colchetes como este:",
|
||||||
"From (Base Model)": "De (Modelo Base)",
|
"From (Base Model)": "De (Modelo Base)",
|
||||||
"Full Screen Mode": "Modo de Tela Cheia",
|
"Full Screen Mode": "Modo de Tela Cheia",
|
||||||
"General": "Geral",
|
"General": "Geral",
|
||||||
"General Settings": "Configurações Gerais",
|
"General Settings": "Configurações Gerais",
|
||||||
"Hello, {{name}}": "Olá, {{name}}",
|
"Hello, {{name}}": "Olá, {{name}}",
|
||||||
"Hide": "Ocultar",
|
"Hide": "Ocultar",
|
||||||
"Hide Additional Params": "Ocultar Parâmetros Adicionais",
|
"Hide Additional Params": "Ocultar Parâmetros Adicionais",
|
||||||
"How can I help you today?": "Como posso ajudá-lo hoje?",
|
"How can I help you today?": "Como posso ajudá-lo hoje?",
|
||||||
"Image Generation (Experimental)": "Geração de Imagens (Experimental)",
|
"Image Generation (Experimental)": "Geração de Imagens (Experimental)",
|
||||||
"Image Generation Engine": "Mecanismo de Geração de Imagens",
|
"Image Generation Engine": "Mecanismo de Geração de Imagens",
|
||||||
"Image Settings": "Configurações de Imagem",
|
"Image Settings": "Configurações de Imagem",
|
||||||
"Images": "Imagens",
|
"Images": "Imagens",
|
||||||
"Import Chats": "Importar Bate-papos",
|
"Import Chats": "Importar Bate-papos",
|
||||||
"Import Documents Mapping": "Importar Mapeamento de Documentos",
|
"Import Documents Mapping": "Importar Mapeamento de Documentos",
|
||||||
"Import Modelfiles": "Importar Arquivos de Modelo",
|
"Import Modelfiles": "Importar Arquivos de Modelo",
|
||||||
"Import Prompts": "Importar Prompts",
|
"Import Prompts": "Importar Prompts",
|
||||||
"Include `--api` flag when running stable-diffusion-webui": "Inclua a flag `--api` ao executar stable-diffusion-webui",
|
"Include `--api` flag when running stable-diffusion-webui": "Inclua a flag `--api` ao executar stable-diffusion-webui",
|
||||||
"Interface": "Interface",
|
"Interface": "Interface",
|
||||||
"join our Discord for help.": "junte-se ao nosso Discord para obter ajuda.",
|
"join our Discord for help.": "junte-se ao nosso Discord para obter ajuda.",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"JWT Expiration": "Expiração JWT",
|
"JWT Expiration": "Expiração JWT",
|
||||||
"JWT Token": "Token JWT",
|
"JWT Token": "Token JWT",
|
||||||
"Keep Alive": "Manter Vivo",
|
"Keep Alive": "Manter Vivo",
|
||||||
"Keyboard shortcuts": "Atalhos de teclado",
|
"Keyboard shortcuts": "Atalhos de teclado",
|
||||||
"Language": "Idioma",
|
"Language": "Idioma",
|
||||||
"Light": "Claro",
|
"Light": "Claro",
|
||||||
"Listening...": "Ouvindo...",
|
"Listening...": "Ouvindo...",
|
||||||
"LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.",
|
"LLMs can make mistakes. Verify important information.": "LLMs podem cometer erros. Verifique informações importantes.",
|
||||||
"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
|
"Made by OpenWebUI Community": "Feito pela Comunidade OpenWebUI",
|
||||||
"Make sure to enclose them with": "Certifique-se de colocá-los entre",
|
"Make sure to enclose them with": "Certifique-se de colocá-los entre",
|
||||||
"Manage LiteLLM Models": "Gerenciar Modelos LiteLLM",
|
"Manage LiteLLM Models": "Gerenciar Modelos LiteLLM",
|
||||||
"Manage Models": "Gerenciar Modelos",
|
"Manage Models": "Gerenciar Modelos",
|
||||||
"Manage Ollama Models": "Gerenciar Modelos Ollama",
|
"Manage Ollama Models": "Gerenciar Modelos Ollama",
|
||||||
"Max Tokens": "Máximo de Tokens",
|
"Max Tokens": "Máximo de Tokens",
|
||||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Máximo de 3 modelos podem ser baixados simultaneamente. Tente novamente mais tarde.",
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Máximo de 3 modelos podem ser baixados simultaneamente. Tente novamente mais tarde.",
|
||||||
"Mirostat": "Mirostat",
|
"Mirostat": "Mirostat",
|
||||||
"Mirostat Eta": "Mirostat Eta",
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
"Mirostat Tau": "Mirostat Tau",
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
"MMMM DD, YYYY": "MMMM DD, AAAA",
|
"MMMM DD, YYYY": "MMMM DD, AAAA",
|
||||||
"Model '{{modelName}}' has been successfully downloaded.": "O modelo '{{modelName}}' foi baixado com sucesso.",
|
"Model '{{modelName}}' has been successfully downloaded.": "O modelo '{{modelName}}' foi baixado com sucesso.",
|
||||||
"Model '{{modelTag}}' is already in queue for downloading.": "O modelo '{{modelTag}}' já está na fila para download.",
|
"Model '{{modelTag}}' is already in queue for downloading.": "O modelo '{{modelTag}}' já está na fila para download.",
|
||||||
"Model {{modelId}} not found": "Modelo {{modelId}} não encontrado",
|
"Model {{modelId}} not found": "Modelo {{modelId}} não encontrado",
|
||||||
"Model {{modelName}} already exists.": "O modelo {{modelName}} já existe.",
|
"Model {{modelName}} already exists.": "O modelo {{modelName}} já existe.",
|
||||||
"Model Name": "Nome do Modelo",
|
"Model Name": "Nome do Modelo",
|
||||||
"Model not selected": "Modelo não selecionado",
|
"Model not selected": "Modelo não selecionado",
|
||||||
"Model Tag Name": "Nome da Tag do Modelo",
|
"Model Tag Name": "Nome da Tag do Modelo",
|
||||||
"Model Whitelisting": "Lista de Permissões de Modelo",
|
"Model Whitelisting": "Lista de Permissões de Modelo",
|
||||||
"Model(s) Whitelisted": "Modelo(s) na Lista de Permissões",
|
"Model(s) Whitelisted": "Modelo(s) na Lista de Permissões",
|
||||||
"Modelfile": "Arquivo de Modelo",
|
"Modelfile": "Arquivo de Modelo",
|
||||||
"Modelfile Advanced Settings": "Configurações Avançadas do Arquivo de Modelo",
|
"Modelfile Advanced Settings": "Configurações Avançadas do Arquivo de Modelo",
|
||||||
"Modelfile Content": "Conteúdo do Arquivo de Modelo",
|
"Modelfile Content": "Conteúdo do Arquivo de Modelo",
|
||||||
"Modelfiles": "Arquivos de Modelo",
|
"Modelfiles": "Arquivos de Modelo",
|
||||||
"Models": "Modelos",
|
"Models": "Modelos",
|
||||||
"My Documents": "Meus Documentos",
|
"My Documents": "Meus Documentos",
|
||||||
"My Modelfiles": "Meus Arquivos de Modelo",
|
"My Modelfiles": "Meus Arquivos de Modelo",
|
||||||
"My Prompts": "Meus Prompts",
|
"My Prompts": "Meus Prompts",
|
||||||
"Name": "Nome",
|
"Name": "Nome",
|
||||||
"Name Tag": "Tag de Nome",
|
"Name Tag": "Tag de Nome",
|
||||||
"Name your modelfile": "Nomeie seu arquivo de modelo",
|
"Name your modelfile": "Nomeie seu arquivo de modelo",
|
||||||
"New Chat": "Novo Bate-papo",
|
"New Chat": "Novo Bate-papo",
|
||||||
"New Password": "Nova Senha",
|
"New Password": "Nova Senha",
|
||||||
"Not sure what to add?": "Não tem certeza do que adicionar?",
|
"Not sure what to add?": "Não tem certeza do que adicionar?",
|
||||||
"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
|
"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
|
||||||
"Off": "Desligado",
|
"Off": "Desligado",
|
||||||
"Okay, Let's Go!": "Ok, Vamos Lá!",
|
"Okay, Let's Go!": "Ok, Vamos Lá!",
|
||||||
"Ollama Base URL": "URL Base do Ollama",
|
"Ollama Base URL": "URL Base do Ollama",
|
||||||
"Ollama Version": "Versão do Ollama",
|
"Ollama Version": "Versão do Ollama",
|
||||||
"On": "Ligado",
|
"On": "Ligado",
|
||||||
"Only": "Somente",
|
"Only": "Somente",
|
||||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Somente caracteres alfanuméricos e hífens são permitidos na string de comando.",
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "Somente caracteres alfanuméricos e hífens são permitidos na string de comando.",
|
||||||
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Opa! Aguente firme! Seus arquivos ainda estão no forno de processamento. Estamos cozinhando-os com perfeição. Por favor, seja paciente e avisaremos quando estiverem prontos.",
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Opa! Aguente firme! Seus arquivos ainda estão no forno de processamento. Estamos cozinhando-os com perfeição. Por favor, seja paciente e avisaremos quando estiverem prontos.",
|
||||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Opa! Parece que a URL é inválida. Verifique novamente e tente outra vez.",
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Opa! Parece que a URL é inválida. Verifique novamente e tente outra vez.",
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Opa! Você está usando um método não suportado (somente frontend). Por favor, sirva o WebUI a partir do backend.",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Opa! Você está usando um método não suportado (somente frontend). Por favor, sirva o WebUI a partir do backend.",
|
||||||
"Open": "Abrir",
|
"Open": "Abrir",
|
||||||
"Open AI": "OpenAI",
|
"Open AI": "OpenAI",
|
||||||
"Open AI (Dall-E)": "OpenAI (Dall-E)",
|
"Open AI (Dall-E)": "OpenAI (Dall-E)",
|
||||||
"Open new chat": "Abrir novo bate-papo",
|
"Open new chat": "Abrir novo bate-papo",
|
||||||
"OpenAI API": "API OpenAI",
|
"OpenAI API": "API OpenAI",
|
||||||
"OpenAI API Key": "Chave da API OpenAI",
|
"OpenAI API Key": "Chave da API OpenAI",
|
||||||
"OpenAI API Key is required.": "A Chave da API OpenAI é obrigatória.",
|
"OpenAI API Key is required.": "A Chave da API OpenAI é obrigatória.",
|
||||||
"or": "ou",
|
"or": "ou",
|
||||||
"Parameters": "Parâmetros",
|
"Parameters": "Parâmetros",
|
||||||
"Password": "Senha",
|
"Password": "Senha",
|
||||||
"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
|
"PDF Extract Images (OCR)": "Extrair Imagens de PDF (OCR)",
|
||||||
"pending": "pendente",
|
"pending": "pendente",
|
||||||
"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
|
"Permission denied when accessing microphone: {{error}}": "Permissão negada ao acessar o microfone: {{error}}",
|
||||||
"Playground": "Playground",
|
"Playground": "Playground",
|
||||||
"Profile": "Perfil",
|
"Profile": "Perfil",
|
||||||
"Prompt Content": "Conteúdo do Prompt",
|
"Prompt Content": "Conteúdo do Prompt",
|
||||||
"Prompt suggestions": "Sugestões de Prompt",
|
"Prompt suggestions": "Sugestões de Prompt",
|
||||||
"Prompts": "Prompts",
|
"Prompts": "Prompts",
|
||||||
"Pull a model from Ollama.com": "Extrair um modelo do Ollama.com",
|
"Pull a model from Ollama.com": "Extrair um modelo do Ollama.com",
|
||||||
"Pull Progress": "Progresso da Extração",
|
"Pull Progress": "Progresso da Extração",
|
||||||
"Query Params": "Parâmetros de Consulta",
|
"Query Params": "Parâmetros de Consulta",
|
||||||
"RAG Template": "Modelo RAG",
|
"RAG Template": "Modelo RAG",
|
||||||
"Raw Format": "Formato Bruto",
|
"Raw Format": "Formato Bruto",
|
||||||
"Record voice": "Gravar voz",
|
"Record voice": "Gravar voz",
|
||||||
"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
|
"Redirecting you to OpenWebUI Community": "Redirecionando você para a Comunidade OpenWebUI",
|
||||||
"Release Notes": "Notas de Lançamento",
|
"Release Notes": "Notas de Lançamento",
|
||||||
"Repeat Last N": "Repetir Últimos N",
|
"Repeat Last N": "Repetir Últimos N",
|
||||||
"Repeat Penalty": "Penalidade de Repetição",
|
"Repeat Penalty": "Penalidade de Repetição",
|
||||||
"Request Mode": "Modo de Solicitação",
|
"Request Mode": "Modo de Solicitação",
|
||||||
"Reset Vector Storage": "Redefinir Armazenamento de Vetor",
|
"Reset Vector Storage": "Redefinir Armazenamento de Vetor",
|
||||||
"Response AutoCopy to Clipboard": "Cópia Automática da Resposta para a Área de Transferência",
|
"Response AutoCopy to Clipboard": "Cópia Automática da Resposta para a Área de Transferência",
|
||||||
"Role": "Função",
|
"Role": "Função",
|
||||||
"Rosé Pine": "Rosé Pine",
|
"Rosé Pine": "Rosé Pine",
|
||||||
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
"Save": "Salvar",
|
"Save": "Salvar",
|
||||||
"Save & Create": "Salvar e Criar",
|
"Save & Create": "Salvar e Criar",
|
||||||
"Save & Submit": "Salvar e Enviar",
|
"Save & Submit": "Salvar e Enviar",
|
||||||
"Save & Update": "Salvar e Atualizar",
|
"Save & Update": "Salvar e Atualizar",
|
||||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Salvar logs de bate-papo diretamente no armazenamento do seu navegador não é mais suportado. Reserve um momento para baixar e excluir seus logs de bate-papo clicando no botão abaixo. Não se preocupe, você pode facilmente reimportar seus logs de bate-papo para o backend através de",
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Salvar logs de bate-papo diretamente no armazenamento do seu navegador não é mais suportado. Reserve um momento para baixar e excluir seus logs de bate-papo clicando no botão abaixo. Não se preocupe, você pode facilmente reimportar seus logs de bate-papo para o backend através de",
|
||||||
"Scan": "Digitalizar",
|
"Scan": "Digitalizar",
|
||||||
"Scan complete!": "Digitalização concluída!",
|
"Scan complete!": "Digitalização concluída!",
|
||||||
"Scan for documents from {{path}}": "Digitalizar documentos de {{path}}",
|
"Scan for documents from {{path}}": "Digitalizar documentos de {{path}}",
|
||||||
"Search": "Pesquisar",
|
"Search": "Pesquisar",
|
||||||
"Search Documents": "Pesquisar Documentos",
|
"Search Documents": "Pesquisar Documentos",
|
||||||
"Search Prompts": "Pesquisar Prompts",
|
"Search Prompts": "Pesquisar Prompts",
|
||||||
"See readme.md for instructions": "Consulte readme.md para obter instruções",
|
"See readme.md for instructions": "Consulte readme.md para obter instruções",
|
||||||
"See what's new": "Veja o que há de novo",
|
"See what's new": "Veja o que há de novo",
|
||||||
"Seed": "Semente",
|
"Seed": "Semente",
|
||||||
"Select a mode": "Selecione um modo",
|
"Select a mode": "Selecione um modo",
|
||||||
"Select a model": "Selecione um modelo",
|
"Select a model": "Selecione um modelo",
|
||||||
"Select an Ollama instance": "Selecione uma instância Ollama",
|
"Select an Ollama instance": "Selecione uma instância Ollama",
|
||||||
"Send a Message": "Enviar uma Mensagem",
|
"Send a Message": "Enviar uma Mensagem",
|
||||||
"Send message": "Enviar mensagem",
|
"Send message": "Enviar mensagem",
|
||||||
"Server connection verified": "Conexão com o servidor verificada",
|
"Server connection verified": "Conexão com o servidor verificada",
|
||||||
"Set as default": "Definir como padrão",
|
"Set as default": "Definir como padrão",
|
||||||
"Set Default Model": "Definir Modelo Padrão",
|
"Set Default Model": "Definir Modelo Padrão",
|
||||||
"Set Image Size": "Definir Tamanho da Imagem",
|
"Set Image Size": "Definir Tamanho da Imagem",
|
||||||
"Set Steps": "Definir Etapas",
|
"Set Steps": "Definir Etapas",
|
||||||
"Set Title Auto-Generation Model": "Definir Modelo de Geração Automática de Título",
|
"Set Title Auto-Generation Model": "Definir Modelo de Geração Automática de Título",
|
||||||
"Set Voice": "Definir Voz",
|
"Set Voice": "Definir Voz",
|
||||||
"Settings": "Configurações",
|
"Settings": "Configurações",
|
||||||
"Settings saved successfully!": "Configurações salvas com sucesso!",
|
"Settings saved successfully!": "Configurações salvas com sucesso!",
|
||||||
"Share to OpenWebUI Community": "Compartilhar com a Comunidade OpenWebUI",
|
"Share to OpenWebUI Community": "Compartilhar com a Comunidade OpenWebUI",
|
||||||
"short-summary": "resumo-curto",
|
"short-summary": "resumo-curto",
|
||||||
"Show": "Mostrar",
|
"Show": "Mostrar",
|
||||||
"Show Additional Params": "Mostrar Parâmetros Adicionais",
|
"Show Additional Params": "Mostrar Parâmetros Adicionais",
|
||||||
"Show shortcuts": "Mostrar",
|
"Show shortcuts": "Mostrar",
|
||||||
"sidebar": "barra lateral",
|
"sidebar": "barra lateral",
|
||||||
"Sign in": "Entrar",
|
"Sign in": "Entrar",
|
||||||
"Sign Out": "Sair",
|
"Sign Out": "Sair",
|
||||||
"Sign up": "Inscrever-se",
|
"Sign up": "Inscrever-se",
|
||||||
"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
|
"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
|
||||||
"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
|
"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
|
||||||
"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
|
"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
|
||||||
"Stop Sequence": "Sequência de Parada",
|
"Stop Sequence": "Sequência de Parada",
|
||||||
"STT Settings": "Configurações STT",
|
"STT Settings": "Configurações STT",
|
||||||
"Submit": "Enviar",
|
"Submit": "Enviar",
|
||||||
"Success": "Sucesso",
|
"Success": "Sucesso",
|
||||||
"Successfully updated.": "Atualizado com sucesso.",
|
"Successfully updated.": "Atualizado com sucesso.",
|
||||||
"Sync All": "Sincronizar Tudo",
|
"Sync All": "Sincronizar Tudo",
|
||||||
"System": "Sistema",
|
"System": "Sistema",
|
||||||
"System Prompt": "Prompt do Sistema",
|
"System Prompt": "Prompt do Sistema",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Temperature": "Temperatura",
|
"Temperature": "Temperatura",
|
||||||
"Template": "Modelo",
|
"Template": "Modelo",
|
||||||
"Text Completion": "Complemento de Texto",
|
"Text Completion": "Complemento de Texto",
|
||||||
"Text-to-Speech Engine": "Mecanismo de Texto para Fala",
|
"Text-to-Speech Engine": "Mecanismo de Texto para Fala",
|
||||||
"Tfs Z": "Tfs Z",
|
"Tfs Z": "Tfs Z",
|
||||||
"Theme": "Tema",
|
"Theme": "Tema",
|
||||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isso garante que suas conversas valiosas sejam salvas com segurança em seu banco de dados de backend. Obrigado!",
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Isso garante que suas conversas valiosas sejam salvas com segurança em seu banco de dados de backend. Obrigado!",
|
||||||
"This setting does not sync across browsers or devices.": "Esta configuração não sincroniza entre navegadores ou dispositivos.",
|
"This setting does not sync across browsers or devices.": "Esta configuração não sincroniza entre navegadores ou dispositivos.",
|
||||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Dica: Atualize vários slots de variáveis consecutivamente pressionando a tecla Tab na entrada de bate-papo após cada substituição.",
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Dica: Atualize vários slots de variáveis consecutivamente pressionando a tecla Tab na entrada de bate-papo após cada substituição.",
|
||||||
"Title": "Título",
|
"Title": "Título",
|
||||||
"Title Auto-Generation": "Geração Automática de Título",
|
"Title Auto-Generation": "Geração Automática de Título",
|
||||||
"Title Generation Prompt": "Prompt de Geração de Título",
|
"Title Generation Prompt": "Prompt de Geração de Título",
|
||||||
"to": "para",
|
"to": "para",
|
||||||
"To access the available model names for downloading,": "Para acessar os nomes de modelo disponíveis para download,",
|
"To access the available model names for downloading,": "Para acessar os nomes de modelo disponíveis para download,",
|
||||||
"To access the GGUF models available for downloading,": "Para acessar os modelos GGUF disponíveis para download,",
|
"To access the GGUF models available for downloading,": "Para acessar os modelos GGUF disponíveis para download,",
|
||||||
"to chat input.": "para a entrada de bate-papo.",
|
"to chat input.": "para a entrada de bate-papo.",
|
||||||
"Toggle settings": "Alternar configurações",
|
"Toggle settings": "Alternar configurações",
|
||||||
"Toggle sidebar": "Alternar barra lateral",
|
"Toggle sidebar": "Alternar barra lateral",
|
||||||
"Top K": "Top K",
|
"Top K": "Top K",
|
||||||
"Top P": "Top P",
|
"Top P": "Top P",
|
||||||
"Trouble accessing Ollama?": "Problemas para acessar o Ollama?",
|
"Trouble accessing Ollama?": "Problemas para acessar o Ollama?",
|
||||||
"TTS Settings": "Configurações TTS",
|
"TTS Settings": "Configurações TTS",
|
||||||
"Type Hugging Face Resolve (Download) URL": "Digite a URL do Hugging Face Resolve (Download)",
|
"Type Hugging Face Resolve (Download) URL": "Digite a URL do Hugging Face Resolve (Download)",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Opa! Houve um problema ao conectar-se a {{provider}}.",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Opa! Houve um problema ao conectar-se a {{provider}}.",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Tipo de arquivo desconhecido '{{file_type}}', mas aceitando e tratando como texto simples",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Tipo de arquivo desconhecido '{{file_type}}', mas aceitando e tratando como texto simples",
|
||||||
"Update password": "Atualizar senha",
|
"Update password": "Atualizar senha",
|
||||||
"Upload a GGUF model": "Carregar um modelo GGUF",
|
"Upload a GGUF model": "Carregar um modelo GGUF",
|
||||||
"Upload files": "Carregar arquivos",
|
"Upload files": "Carregar arquivos",
|
||||||
"Upload Progress": "Progresso do Carregamento",
|
"Upload Progress": "Progresso do Carregamento",
|
||||||
"URL Mode": "Modo de URL",
|
"URL Mode": "Modo de URL",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "Use '#' na entrada do prompt para carregar e selecionar seus documentos.",
|
"Use '#' in the prompt input to load and select your documents.": "Use '#' na entrada do prompt para carregar e selecionar seus documentos.",
|
||||||
"Use Gravatar": "Usar Gravatar",
|
"Use Gravatar": "Usar Gravatar",
|
||||||
"user": "usuário",
|
"user": "usuário",
|
||||||
"User Permissions": "Permissões do Usuário",
|
"User Permissions": "Permissões do Usuário",
|
||||||
"Users": "Usuários",
|
"Users": "Usuários",
|
||||||
"Utilize": "Utilizar",
|
"Utilize": "Utilizar",
|
||||||
"Valid time units:": "Unidades de tempo válidas:",
|
"Valid time units:": "Unidades de tempo válidas:",
|
||||||
"variable": "variável",
|
"variable": "variável",
|
||||||
"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
|
"variable to have them replaced with clipboard content.": "variável para que sejam substituídos pelo conteúdo da área de transferência.",
|
||||||
"Version": "Versão",
|
"Version": "Versão",
|
||||||
"Web": "Web",
|
"Web": "Web",
|
||||||
"WebUI Add-ons": "Complementos WebUI",
|
"WebUI Add-ons": "Complementos WebUI",
|
||||||
"WebUI Settings": "Configurações WebUI",
|
"WebUI Settings": "Configurações WebUI",
|
||||||
"WebUI will make requests to": "WebUI fará solicitações para",
|
"WebUI will make requests to": "WebUI fará solicitações para",
|
||||||
"What’s New in": "O que há de novo em",
|
"What’s New in": "O que há de novo em",
|
||||||
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando o histórico está desativado, novos bate-papos neste navegador não aparecerão em seu histórico em nenhum dos seus dispositivos.",
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Quando o histórico está desativado, novos bate-papos neste navegador não aparecerão em seu histórico em nenhum dos seus dispositivos.",
|
||||||
"Whisper (Local)": "Whisper (Local)",
|
"Whisper (Local)": "Whisper (Local)",
|
||||||
"Write a prompt suggestion (e.g. Who are you?)": "Escreva uma sugestão de prompt (por exemplo, Quem é você?)",
|
"Write a prompt suggestion (e.g. Who are you?)": "Escreva uma sugestão de prompt (por exemplo, Quem é você?)",
|
||||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Escreva um resumo em 50 palavras que resuma [tópico ou palavra-chave].",
|
"Write a summary in 50 words that summarizes [topic or keyword].": "Escreva um resumo em 50 palavras que resuma [tópico ou palavra-chave].",
|
||||||
"You": "Você",
|
"You": "Você",
|
||||||
"You're a helpful assistant.": "Você é um assistente útil.",
|
"You're a helpful assistant.": "Você é um assistente útil.",
|
||||||
"You're now logged in.": "Você está conectado agora."
|
"You're now logged in.": "Você está conectado agora."
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,4 +360,4 @@
|
||||||
"You": "Вы",
|
"You": "Вы",
|
||||||
"You're a helpful assistant.": "Вы полезный ассистент.",
|
"You're a helpful assistant.": "Вы полезный ассистент.",
|
||||||
"You're now logged in.": "Вы вошли в систему."
|
"You're now logged in.": "Вы вошли в систему."
|
||||||
}
|
}
|
||||||
|
|
363
src/lib/i18n/locales/tr-TR/translation.json
Normal file
363
src/lib/i18n/locales/tr-TR/translation.json
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
{
|
||||||
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' veya süresiz için '-1'.",
|
||||||
|
"(Beta)": "(Beta)",
|
||||||
|
"(e.g. `sh webui.sh --api`)": "(örn. `sh webui.sh --api`)",
|
||||||
|
"(latest)": "(en son)",
|
||||||
|
"{{modelName}} is thinking...": "{{modelName}} düşünüyor...",
|
||||||
|
"{{webUIName}} Backend Required": "{{webUIName}} Arkayüz Gerekli",
|
||||||
|
"a user": "bir kullanıcı",
|
||||||
|
"About": "Hakkında",
|
||||||
|
"Account": "Hesap",
|
||||||
|
"Action": "Eylem",
|
||||||
|
"Add a model": "Bir model ekleyin",
|
||||||
|
"Add a model tag name": "Bir model etiket adı ekleyin",
|
||||||
|
"Add a short description about what this modelfile does": "Bu model dosyasının ne yaptığı hakkında kısa bir açıklama ekleyin",
|
||||||
|
"Add a short title for this prompt": "Bu prompt için kısa bir başlık ekleyin",
|
||||||
|
"Add a tag": "Bir etiket ekleyin",
|
||||||
|
"Add Docs": "Dökümanlar Ekle",
|
||||||
|
"Add Files": "Dosyalar Ekle",
|
||||||
|
"Add message": "Mesaj ekle",
|
||||||
|
"add tags": "etiketler ekle",
|
||||||
|
"Adjusting these settings will apply changes universally to all users.": "Bu ayarları ayarlamak değişiklikleri tüm kullanıcılara evrensel olarak uygular.",
|
||||||
|
"admin": "yönetici",
|
||||||
|
"Admin Panel": "Yönetici Paneli",
|
||||||
|
"Admin Settings": "Yönetici Ayarları",
|
||||||
|
"Advanced Parameters": "Gelişmiş Parametreler",
|
||||||
|
"all": "tümü",
|
||||||
|
"All Users": "Tüm Kullanıcılar",
|
||||||
|
"Allow": "İzin ver",
|
||||||
|
"Allow Chat Deletion": "Sohbet Silmeye İzin Ver",
|
||||||
|
"alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler",
|
||||||
|
"Already have an account?": "Zaten bir hesabınız mı var?",
|
||||||
|
"an assistant": "bir asistan",
|
||||||
|
"and": "ve",
|
||||||
|
"API Base URL": "API Temel URL",
|
||||||
|
"API Key": "API Anahtarı",
|
||||||
|
"API RPM": "API RPM",
|
||||||
|
"are allowed - Activate this command by typing": "izin verilir - Bu komutu yazarak etkinleştirin",
|
||||||
|
"Are you sure?": "Emin misiniz?",
|
||||||
|
"Audio": "Ses",
|
||||||
|
"Auto-playback response": "Yanıtı otomatik oynatma",
|
||||||
|
"Auto-send input after 3 sec.": "3 saniye sonra otomatik olarak gönder",
|
||||||
|
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 Temel URL",
|
||||||
|
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Temel URL gereklidir.",
|
||||||
|
"available!": "mevcut!",
|
||||||
|
"Back": "Geri",
|
||||||
|
"Builder Mode": "Oluşturucu Modu",
|
||||||
|
"Cancel": "İptal",
|
||||||
|
"Categories": "Kategoriler",
|
||||||
|
"Change Password": "Parola Değiştir",
|
||||||
|
"Chat": "Sohbet",
|
||||||
|
"Chat History": "Sohbet Geçmişi",
|
||||||
|
"Chat History is off for this browser.": "Bu tarayıcı için sohbet geçmişi kapalı.",
|
||||||
|
"Chats": "Sohbetler",
|
||||||
|
"Check Again": "Tekrar Kontrol Et",
|
||||||
|
"Check for updates": "Güncellemeleri kontrol et",
|
||||||
|
"Checking for updates...": "Güncellemeler kontrol ediliyor...",
|
||||||
|
"Choose a model before saving...": "Kaydetmeden önce bir model seçin...",
|
||||||
|
"Chunk Overlap": "Chunk Çakışması",
|
||||||
|
"Chunk Params": "Chunk Parametreleri",
|
||||||
|
"Chunk Size": "Chunk Boyutu",
|
||||||
|
"Click here for help.": "Yardım için buraya tıklayın.",
|
||||||
|
"Click here to check other modelfiles.": "Diğer model dosyalarını kontrol etmek için buraya tıklayın.",
|
||||||
|
"Click here to select": "Seçmek için buraya tıklayın",
|
||||||
|
"Click here to select documents.": "Belgeleri seçmek için buraya tıklayın.",
|
||||||
|
"click here.": "buraya tıklayın.",
|
||||||
|
"Click on the user role button to change a user's role.": "Bir kullanıcının rolünü değiştirmek için kullanıcı rolü düğmesine tıklayın.",
|
||||||
|
"Close": "Kapat",
|
||||||
|
"Collection": "Koleksiyon",
|
||||||
|
"Command": "Komut",
|
||||||
|
"Confirm Password": "Parolayı Onayla",
|
||||||
|
"Connections": "Bağlantılar",
|
||||||
|
"Content": "İçerik",
|
||||||
|
"Context Length": "Bağlam Uzunluğu",
|
||||||
|
"Conversation Mode": "Sohbet Modu",
|
||||||
|
"Copy last code block": "Son kod bloğunu kopyala",
|
||||||
|
"Copy last response": "Son yanıtı kopyala",
|
||||||
|
"Copying to clipboard was successful!": "Panoya kopyalama başarılı!",
|
||||||
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Aşağıdaki sorgu için başlık olarak 3-5 kelimelik kısa ve öz bir ifade oluşturun, 3-5 kelime sınırına kesinlikle uyun ve 'başlık' kelimesini kullanmaktan kaçının:",
|
||||||
|
"Create a modelfile": "Bir model dosyası oluştur",
|
||||||
|
"Create Account": "Hesap Oluştur",
|
||||||
|
"Created at": "Oluşturulma tarihi",
|
||||||
|
"Created by": "Oluşturan",
|
||||||
|
"Current Model": "Mevcut Model",
|
||||||
|
"Current Password": "Mevcut Parola",
|
||||||
|
"Custom": "Özel",
|
||||||
|
"Customize Ollama models for a specific purpose": "Ollama modellerini belirli bir amaç için özelleştirin",
|
||||||
|
"Dark": "Koyu",
|
||||||
|
"Database": "Veritabanı",
|
||||||
|
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
||||||
|
"Default": "Varsayılan",
|
||||||
|
"Default (Automatic1111)": "Varsayılan (Automatic1111)",
|
||||||
|
"Default (Web API)": "Varsayılan (Web API)",
|
||||||
|
"Default model updated": "Varsayılan model güncellendi",
|
||||||
|
"Default Prompt Suggestions": "Varsayılan Prompt Önerileri",
|
||||||
|
"Default User Role": "Varsayılan Kullanıcı Rolü",
|
||||||
|
"delete": "sil",
|
||||||
|
"Delete a model": "Bir modeli sil",
|
||||||
|
"Delete chat": "Sohbeti sil",
|
||||||
|
"Delete Chats": "Sohbetleri Sil",
|
||||||
|
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} silindi",
|
||||||
|
"Deleted {tagName}": "{tagName} silindi",
|
||||||
|
"Description": "Açıklama",
|
||||||
|
"Desktop Notifications": "Masaüstü Bildirimleri",
|
||||||
|
"Disabled": "Devre Dışı",
|
||||||
|
"Discover a modelfile": "Bir model dosyası keşfedin",
|
||||||
|
"Discover a prompt": "Bir prompt keşfedin",
|
||||||
|
"Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin",
|
||||||
|
"Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin",
|
||||||
|
"Display the username instead of You in the Chat": "Sohbet'te Siz yerine kullanıcı adını göster",
|
||||||
|
"Document": "Belge",
|
||||||
|
"Document Settings": "Belge Ayarları",
|
||||||
|
"Documents": "Belgeler",
|
||||||
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "herhangi bir harici bağlantı yapmaz ve verileriniz güvenli bir şekilde yerel olarak barındırılan sunucunuzda kalır.",
|
||||||
|
"Don't Allow": "İzin Verme",
|
||||||
|
"Don't have an account?": "Hesabınız yok mu?",
|
||||||
|
"Download as a File": "Dosya olarak indir",
|
||||||
|
"Download Database": "Veritabanını İndir",
|
||||||
|
"Drop any files here to add to the conversation": "Sohbete eklemek istediğiniz dosyaları buraya bırakın",
|
||||||
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "örn. '30s', '10m'. Geçerli zaman birimleri 's', 'm', 'h'.",
|
||||||
|
"Edit Doc": "Belgeyi Düzenle",
|
||||||
|
"Edit User": "Kullanıcıyı Düzenle",
|
||||||
|
"Email": "E-posta",
|
||||||
|
"Enable Chat History": "Sohbet Geçmişini Etkinleştir",
|
||||||
|
"Enable New Sign Ups": "Yeni Kayıtları Etkinleştir",
|
||||||
|
"Enabled": "Etkin",
|
||||||
|
"Enter {{role}} message here": "Buraya {{role}} mesajını girin",
|
||||||
|
"Enter API Key": "API Anahtarını Girin",
|
||||||
|
"Enter Chunk Overlap": "Chunk Örtüşmesini Girin",
|
||||||
|
"Enter Chunk Size": "Chunk Boyutunu Girin",
|
||||||
|
"Enter Image Size (e.g. 512x512)": "Görüntü Boyutunu Girin (örn. 512x512)",
|
||||||
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "LiteLLM API Ana URL'sini Girin (litellm_params.api_base)",
|
||||||
|
"Enter LiteLLM API Key (litellm_params.api_key)": "LiteLLM API Anahtarını Girin (litellm_params.api_key)",
|
||||||
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "LiteLLM API RPM'ini Girin (litellm_params.rpm)",
|
||||||
|
"Enter LiteLLM Model (litellm_params.model)": "LiteLLM Modelini Girin (litellm_params.model)",
|
||||||
|
"Enter Max Tokens (litellm_params.max_tokens)": "Maksimum Token Sayısını Girin (litellm_params.max_tokens)",
|
||||||
|
"Enter model tag (e.g. {{modelTag}})": "Model etiketini girin (örn. {{modelTag}})",
|
||||||
|
"Enter Number of Steps (e.g. 50)": "Adım Sayısını Girin (örn. 50)",
|
||||||
|
"Enter stop sequence": "Durdurma dizisini girin",
|
||||||
|
"Enter Top K": "Top K'yı girin",
|
||||||
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "URL'yi Girin (örn. http://127.0.0.1:7860/)",
|
||||||
|
"Enter Your Email": "E-postanızı Girin",
|
||||||
|
"Enter Your Full Name": "Tam Adınızı Girin",
|
||||||
|
"Enter Your Password": "Parolanızı Girin",
|
||||||
|
"Experimental": "Deneysel",
|
||||||
|
"Export All Chats (All Users)": "Tüm Sohbetleri Dışa Aktar (Tüm Kullanıcılar)",
|
||||||
|
"Export Chats": "Sohbetleri Dışa Aktar",
|
||||||
|
"Export Documents Mapping": "Belge Eşlemesini Dışa Aktar",
|
||||||
|
"Export Modelfiles": "Model Dosyalarını Dışa Aktar",
|
||||||
|
"Export Prompts": "Promptları Dışa Aktar",
|
||||||
|
"Failed to read clipboard contents": "Pano içeriği okunamadı",
|
||||||
|
"File Mode": "Dosya Modu",
|
||||||
|
"File not found.": "Dosya bulunamadı.",
|
||||||
|
"Focus chat input": "Sohbet girişine odaklan",
|
||||||
|
"Format your variables using square brackets like this:": "Değişkenlerinizi şu şekilde kare parantezlerle biçimlendirin:",
|
||||||
|
"From (Base Model)": "(Temel Model)'den",
|
||||||
|
"Full Screen Mode": "Tam Ekran Modu",
|
||||||
|
"General": "Genel",
|
||||||
|
"General Settings": "Genel Ayarlar",
|
||||||
|
"Hello, {{name}}": "Merhaba, {{name}}",
|
||||||
|
"Hide": "Gizle",
|
||||||
|
"Hide Additional Params": "Ek Parametreleri Gizle",
|
||||||
|
"How can I help you today?": "Bugün size nasıl yardımcı olabilirim?",
|
||||||
|
"Image Generation (Experimental)": "Görüntü Oluşturma (Deneysel)",
|
||||||
|
"Image Generation Engine": "Görüntü Oluşturma Motoru",
|
||||||
|
"Image Settings": "Görüntü Ayarları",
|
||||||
|
"Images": "Görüntüler",
|
||||||
|
"Import Chats": "Sohbetleri İçe Aktar",
|
||||||
|
"Import Documents Mapping": "Belge Eşlemesini İçe Aktar",
|
||||||
|
"Import Modelfiles": "Model Dosyalarını İçe Aktar",
|
||||||
|
"Import Prompts": "Promptları İçe Aktar",
|
||||||
|
"Include `--api` flag when running stable-diffusion-webui": "stable-diffusion-webui çalıştırılırken `--api` bayrağını dahil edin",
|
||||||
|
"Interface": "Arayüz",
|
||||||
|
"join our Discord for help.": "yardım için Discord'umuza katılın.",
|
||||||
|
"JSON": "JSON",
|
||||||
|
"JWT Expiration": "JWT Bitişi",
|
||||||
|
"JWT Token": "JWT Token",
|
||||||
|
"Keep Alive": "Canlı Tut",
|
||||||
|
"Keyboard shortcuts": "Klavye kısayolları",
|
||||||
|
"Language": "Dil",
|
||||||
|
"Light": "Açık",
|
||||||
|
"Listening...": "Dinleniyor...",
|
||||||
|
"LLMs can make mistakes. Verify important information.": "LLM'ler hata yapabilir. Önemli bilgileri doğrulayın.",
|
||||||
|
"Made by OpenWebUI Community": "OpenWebUI Topluluğu tarafından yapılmıştır",
|
||||||
|
"Make sure to enclose them with": "Değişkenlerinizi şu şekilde biçimlendirin:",
|
||||||
|
"Manage LiteLLM Models": "LiteLLM Modellerini Yönet",
|
||||||
|
"Manage Models": "Modelleri Yönet",
|
||||||
|
"Manage Ollama Models": "Ollama Modellerini Yönet",
|
||||||
|
"Max Tokens": "Maksimum Token",
|
||||||
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Aynı anda en fazla 3 model indirilebilir. Lütfen daha sonra tekrar deneyin.",
|
||||||
|
"Mirostat": "Mirostat",
|
||||||
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
|
"MMMM DD, YYYY": "DD MMMM YYYY",
|
||||||
|
"Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' başarıyla indirildi.",
|
||||||
|
"Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' zaten indirme sırasında.",
|
||||||
|
"Model {{modelId}} not found": "{{modelId}} bulunamadı",
|
||||||
|
"Model {{modelName}} already exists.": "{{modelName}} zaten mevcut.",
|
||||||
|
"Model Name": "Model Adı",
|
||||||
|
"Model not selected": "Model seçilmedi",
|
||||||
|
"Model Tag Name": "Model Etiket Adı",
|
||||||
|
"Model Whitelisting": "Model Beyaz Listeye Alma",
|
||||||
|
"Model(s) Whitelisted": "Model(ler) Beyaz Listeye Alındı",
|
||||||
|
"Modelfile": "Model Dosyası",
|
||||||
|
"Modelfile Advanced Settings": "Model Dosyası Gelişmiş Ayarları",
|
||||||
|
"Modelfile Content": "Model Dosyası İçeriği",
|
||||||
|
"Modelfiles": "Model Dosyaları",
|
||||||
|
"Models": "Modeller",
|
||||||
|
"My Documents": "Belgelerim",
|
||||||
|
"My Modelfiles": "Model Dosyalarım",
|
||||||
|
"My Prompts": "Promptlarım",
|
||||||
|
"Name": "Ad",
|
||||||
|
"Name Tag": "Ad Etiketi",
|
||||||
|
"Name your modelfile": "Model dosyanıza ad verin",
|
||||||
|
"New Chat": "Yeni Sohbet",
|
||||||
|
"New Password": "Yeni Parola",
|
||||||
|
"Not sure what to add?": "Ne ekleyeceğinizden emin değil misiniz?",
|
||||||
|
"Not sure what to write? Switch to": "Ne yazacağınızdan emin değil misiniz? Şuraya geçin",
|
||||||
|
"Off": "Kapalı",
|
||||||
|
"Okay, Let's Go!": "Tamam, Hadi Başlayalım!",
|
||||||
|
"Ollama Base URL": "Ollama Temel URL",
|
||||||
|
"Ollama Version": "Ollama Sürümü",
|
||||||
|
"On": "Açık",
|
||||||
|
"Only": "Yalnızca",
|
||||||
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "Komut dizisinde yalnızca alfasayısal karakterler ve tireler kabul edilir.",
|
||||||
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Hop! Biraz sabırlı ol! Dosyaların hala hazırlama fırınında. Onları ağzınıza layık olana kadar pişiriyoruz :) Lütfen sabırlı olun; hazır olduklarında size haber vereceğiz.",
|
||||||
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Hop! URL geçersiz gibi görünüyor. Lütfen tekrar kontrol edin ve yeniden deneyin.",
|
||||||
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Hop! Desteklenmeyen bir yöntem kullanıyorsunuz (yalnızca önyüz). Lütfen WebUI'yi arkayüzden sunun.",
|
||||||
|
"Open": "Aç",
|
||||||
|
"Open AI": "Open AI",
|
||||||
|
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
||||||
|
"Open new chat": "Yeni sohbet aç",
|
||||||
|
"OpenAI API": "OpenAI API",
|
||||||
|
"OpenAI API Key": "OpenAI API Anahtarı",
|
||||||
|
"OpenAI API Key is required.": "OpenAI API Anahtarı gereklidir.",
|
||||||
|
"or": "veya",
|
||||||
|
"Parameters": "Parametreler",
|
||||||
|
"Password": "Parola",
|
||||||
|
"PDF Extract Images (OCR)": "PDF Görüntülerini Çıkart (OCR)",
|
||||||
|
"pending": "beklemede",
|
||||||
|
"Permission denied when accessing microphone: {{error}}": "Mikrofona erişim izni reddedildi: {{error}}",
|
||||||
|
"Playground": "Oyun Alanı",
|
||||||
|
"Profile": "Profil",
|
||||||
|
"Prompt Content": "Prompt İçeriği",
|
||||||
|
"Prompt suggestions": "Prompt önerileri",
|
||||||
|
"Prompts": "Promptlar",
|
||||||
|
"Pull a model from Ollama.com": "Ollama.com'dan bir model çekin",
|
||||||
|
"Pull Progress": "Çekme İlerlemesi",
|
||||||
|
"Query Params": "Sorgu Parametreleri",
|
||||||
|
"RAG Template": "RAG Şablonu",
|
||||||
|
"Raw Format": "Ham Format",
|
||||||
|
"Record voice": "Ses kaydı yap",
|
||||||
|
"Redirecting you to OpenWebUI Community": "OpenWebUI Topluluğuna yönlendiriliyorsunuz",
|
||||||
|
"Release Notes": "Sürüm Notları",
|
||||||
|
"Repeat Last N": "Son N'yi Tekrar Et",
|
||||||
|
"Repeat Penalty": "Tekrar Cezası",
|
||||||
|
"Request Mode": "İstek Modu",
|
||||||
|
"Reset Vector Storage": "Vektör Depolamayı Sıfırla",
|
||||||
|
"Response AutoCopy to Clipboard": "Yanıtı Panoya Otomatik Kopyala",
|
||||||
|
"Role": "Rol",
|
||||||
|
"Rosé Pine": "Rosé Pine",
|
||||||
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
|
"Save": "Kaydet",
|
||||||
|
"Save & Create": "Kaydet ve Oluştur",
|
||||||
|
"Save & Submit": "Kaydet ve Gönder",
|
||||||
|
"Save & Update": "Kaydet ve Güncelle",
|
||||||
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Sohbet kayıtlarının doğrudan tarayıcınızın depolama alanına kaydedilmesi artık desteklenmemektedir. Lütfen aşağıdaki butona tıklayarak sohbet kayıtlarınızı indirmek ve silmek için bir dakikanızı ayırın. Endişelenmeyin, sohbet günlüklerinizi arkayüze kolayca yeniden aktarabilirsiniz:",
|
||||||
|
"Scan": "Tarama",
|
||||||
|
"Scan complete!": "Tarama tamamlandı!",
|
||||||
|
"Scan for documents from {{path}}": "{{path}} dizininden belgeleri tarayın",
|
||||||
|
"Search": "Ara",
|
||||||
|
"Search Documents": "Belgeleri Ara",
|
||||||
|
"Search Prompts": "Prompt Ara",
|
||||||
|
"See readme.md for instructions": "Yönergeler için readme.md dosyasına bakın",
|
||||||
|
"See what's new": "Yeniliklere göz atın",
|
||||||
|
"Seed": "Seed",
|
||||||
|
"Select a mode": "Bir mod seç",
|
||||||
|
"Select a model": "Bir model seç",
|
||||||
|
"Select an Ollama instance": "Bir Ollama örneği seçin",
|
||||||
|
"Send a Message": "Bir Mesaj Gönder",
|
||||||
|
"Send message": "Mesaj gönder",
|
||||||
|
"Server connection verified": "Sunucu bağlantısı doğrulandı",
|
||||||
|
"Set as default": "Varsayılan olarak ayarla",
|
||||||
|
"Set Default Model": "Varsayılan Modeli Ayarla",
|
||||||
|
"Set Image Size": "Görüntü Boyutunu Ayarla",
|
||||||
|
"Set Steps": "Adımları Ayarla",
|
||||||
|
"Set Title Auto-Generation Model": "Otomatik Başlık Oluşturma Modelini Ayarla",
|
||||||
|
"Set Voice": "Ses Ayarla",
|
||||||
|
"Settings": "Ayarlar",
|
||||||
|
"Settings saved successfully!": "Ayarlar başarıyla kaydedildi!",
|
||||||
|
"Share to OpenWebUI Community": "OpenWebUI Topluluğu ile Paylaş",
|
||||||
|
"short-summary": "kısa-özet",
|
||||||
|
"Show": "Göster",
|
||||||
|
"Show Additional Params": "Ek Parametreleri Göster",
|
||||||
|
"Show shortcuts": "Kısayolları göster",
|
||||||
|
"sidebar": "kenar çubuğu",
|
||||||
|
"Sign in": "Oturum aç",
|
||||||
|
"Sign Out": "Çıkış Yap",
|
||||||
|
"Sign up": "Kaydol",
|
||||||
|
"Speech recognition error: {{error}}": "Konuşma tanıma hatası: {{error}}",
|
||||||
|
"Speech-to-Text Engine": "Konuşmadan Metne Motoru",
|
||||||
|
"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API bu tarayıcıda desteklenmiyor.",
|
||||||
|
"Stop Sequence": "Diziyi Durdur",
|
||||||
|
"STT Settings": "STT Ayarları",
|
||||||
|
"Submit": "Gönder",
|
||||||
|
"Success": "Başarılı",
|
||||||
|
"Successfully updated.": "Başarıyla güncellendi.",
|
||||||
|
"Sync All": "Tümünü Senkronize Et",
|
||||||
|
"System": "Sistem",
|
||||||
|
"System Prompt": "Sistem Promptu",
|
||||||
|
"Tags": "Etiketler",
|
||||||
|
"Temperature": "Temperature",
|
||||||
|
"Template": "Şablon",
|
||||||
|
"Text Completion": "Metin Tamamlama",
|
||||||
|
"Text-to-Speech Engine": "Metinden Sese Motoru",
|
||||||
|
"Tfs Z": "Tfs Z",
|
||||||
|
"Theme": "Tema",
|
||||||
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Bu, önemli konuşmalarınızın güvenli bir şekilde arkayüz veritabanınıza kaydedildiğini garantiler. Teşekkür ederiz!",
|
||||||
|
"This setting does not sync across browsers or devices.": "Bu ayar tarayıcılar veya cihazlar arasında senkronize edilmez.",
|
||||||
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "İpucu: Her değiştirmeden sonra sohbet girişinde tab tuşuna basarak birden fazla değişken yuvasını art arda güncelleyin.",
|
||||||
|
"Title": "Başlık",
|
||||||
|
"Title Auto-Generation": "Otomatik Başlık Oluşturma",
|
||||||
|
"Title Generation Prompt": "Başlık Oluşturma Promptu",
|
||||||
|
"to": "için",
|
||||||
|
"To access the available model names for downloading,": "İndirilebilir mevcut model adlarına erişmek için,",
|
||||||
|
"To access the GGUF models available for downloading,": "İndirilebilir mevcut GGUF modellerine erişmek için,",
|
||||||
|
"to chat input.": "sohbet girişine.",
|
||||||
|
"Toggle settings": "Ayarları Aç/Kapat",
|
||||||
|
"Toggle sidebar": "Kenar Çubuğunu Aç/Kapat",
|
||||||
|
"Top K": "Top K",
|
||||||
|
"Top P": "Top P",
|
||||||
|
"Trouble accessing Ollama?": "Ollama'ya erişmede sorun mu yaşıyorsunuz?",
|
||||||
|
"TTS Settings": "TTS Ayarları",
|
||||||
|
"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (Download) URL'sini Yazın",
|
||||||
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Ah! {{provider}}'a bağlanırken bir sorun oluştu.",
|
||||||
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Bilinmeyen Dosya Türü '{{file_type}}', ancak düz metin olarak kabul ediliyor ve işleniyor",
|
||||||
|
"Update password": "Parolayı Güncelle",
|
||||||
|
"Upload a GGUF model": "Bir GGUF modeli yükle",
|
||||||
|
"Upload files": "Dosyaları Yükle",
|
||||||
|
"Upload Progress": "Yükleme İlerlemesi",
|
||||||
|
"URL Mode": "URL Modu",
|
||||||
|
"Use '#' in the prompt input to load and select your documents.": "Belgelerinizi yüklemek ve seçmek için promptda '#' kullanın.",
|
||||||
|
"Use Gravatar": "Gravatar Kullan",
|
||||||
|
"user": "kullanıcı",
|
||||||
|
"User Permissions": "Kullanıcı İzinleri",
|
||||||
|
"Users": "Kullanıcılar",
|
||||||
|
"Utilize": "Kullan",
|
||||||
|
"Valid time units:": "Geçerli zaman birimleri:",
|
||||||
|
"variable": "değişken",
|
||||||
|
"variable to have them replaced with clipboard content.": "panodaki içerikle değiştirilmesi için değişken.",
|
||||||
|
"Version": "Sürüm",
|
||||||
|
"Web": "Web",
|
||||||
|
"WebUI Add-ons": "WebUI Eklentileri",
|
||||||
|
"WebUI Settings": "WebUI Ayarları",
|
||||||
|
"WebUI will make requests to": "WebUI, isteklerde bulunacak:",
|
||||||
|
"What’s New in": "Yenilikler:",
|
||||||
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Geçmiş kapatıldığında, bu tarayıcıdaki yeni sohbetler hiçbir cihazınızdaki geçmişinizde görünmez.",
|
||||||
|
"Whisper (Local)": "Whisper (Yerel)",
|
||||||
|
"Write a prompt suggestion (e.g. Who are you?)": "Bir prompt önerisi yazın (örn. Sen kimsin?)",
|
||||||
|
"Write a summary in 50 words that summarizes [topic or keyword].": "[Konuyu veya anahtar kelimeyi] özetleyen 50 kelimelik bir özet yazın.",
|
||||||
|
"You": "Siz",
|
||||||
|
"You're a helpful assistant.": "Sen yardımcı bir asistansın.",
|
||||||
|
"You're now logged in.": "Şimdi oturum açtınız."
|
||||||
|
}
|
|
@ -1,363 +1,363 @@
|
||||||
{
|
{
|
||||||
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' hoặc '-1' không hết hạn.",
|
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' hoặc '-1' không hết hạn.",
|
||||||
"(Beta)": "(Beta)",
|
"(Beta)": "(Beta)",
|
||||||
"(e.g. `sh webui.sh --api`)": "(vd: `sh webui.sh --api`)",
|
"(e.g. `sh webui.sh --api`)": "(vd: `sh webui.sh --api`)",
|
||||||
"(latest)": "(mới nhất)",
|
"(latest)": "(mới nhất)",
|
||||||
"{{modelName}} is thinking...": "{{modelName}} đang suy nghĩ...",
|
"{{modelName}} is thinking...": "{{modelName}} đang suy nghĩ...",
|
||||||
"{{webUIName}} Backend Required": "{{webUIName}} Yêu cầu Backend",
|
"{{webUIName}} Backend Required": "{{webUIName}} Yêu cầu Backend",
|
||||||
"a user": "người sử dụng",
|
"a user": "người sử dụng",
|
||||||
"About": "Giới thiệu",
|
"About": "Giới thiệu",
|
||||||
"Account": "Tài khoản",
|
"Account": "Tài khoản",
|
||||||
"Action": "Tác vụ",
|
"Action": "Tác vụ",
|
||||||
"Add a model": "Thêm mô hình",
|
"Add a model": "Thêm mô hình",
|
||||||
"Add a model tag name": "Thêm tên thẻ mô hình (tag)",
|
"Add a model tag name": "Thêm tên thẻ mô hình (tag)",
|
||||||
"Add a short description about what this modelfile does": "Thêm mô tả ngắn về việc tệp mô tả mô hình (modelfile) này làm gì",
|
"Add a short description about what this modelfile does": "Thêm mô tả ngắn về việc tệp mô tả mô hình (modelfile) này làm gì",
|
||||||
"Add a short title for this prompt": "Thêm tiêu đề ngắn cho prompt này",
|
"Add a short title for this prompt": "Thêm tiêu đề ngắn cho prompt này",
|
||||||
"Add a tag": "Thêm thẻ (tag)",
|
"Add a tag": "Thêm thẻ (tag)",
|
||||||
"Add Docs": "Thêm tài liệu",
|
"Add Docs": "Thêm tài liệu",
|
||||||
"Add Files": "Thêm tệp",
|
"Add Files": "Thêm tệp",
|
||||||
"Add message": "Thêm tin nhắn",
|
"Add message": "Thêm tin nhắn",
|
||||||
"add tags": "thêm thẻ",
|
"add tags": "thêm thẻ",
|
||||||
"Adjusting these settings will apply changes universally to all users.": "Các thay đổi cài đặt này sẽ áp dụng cho tất cả người sử dụng.",
|
"Adjusting these settings will apply changes universally to all users.": "Các thay đổi cài đặt này sẽ áp dụng cho tất cả người sử dụng.",
|
||||||
"admin": "quản trị viên",
|
"admin": "quản trị viên",
|
||||||
"Admin Panel": "Trang Quản trị",
|
"Admin Panel": "Trang Quản trị",
|
||||||
"Admin Settings": "Cài đặt hệ thống",
|
"Admin Settings": "Cài đặt hệ thống",
|
||||||
"Advanced Parameters": "Các tham số Nâng cao",
|
"Advanced Parameters": "Các tham số Nâng cao",
|
||||||
"all": "tất cả",
|
"all": "tất cả",
|
||||||
"All Users": "Danh sách người sử dụng",
|
"All Users": "Danh sách người sử dụng",
|
||||||
"Allow": "Cho phép",
|
"Allow": "Cho phép",
|
||||||
"Allow Chat Deletion": "Cho phép Xóa nội dung chat",
|
"Allow Chat Deletion": "Cho phép Xóa nội dung chat",
|
||||||
"alphanumeric characters and hyphens": "ký tự số và gạch nối",
|
"alphanumeric characters and hyphens": "ký tự số và gạch nối",
|
||||||
"Already have an account?": "Bạn đã có tài khoản?",
|
"Already have an account?": "Bạn đã có tài khoản?",
|
||||||
"an assistant": "trợ lý",
|
"an assistant": "trợ lý",
|
||||||
"and": "và",
|
"and": "và",
|
||||||
"API Base URL": "Đường dẫn tới API (API Base URL)",
|
"API Base URL": "Đường dẫn tới API (API Base URL)",
|
||||||
"API Key": "API Key",
|
"API Key": "API Key",
|
||||||
"API RPM": "API RPM",
|
"API RPM": "API RPM",
|
||||||
"are allowed - Activate this command by typing": "được phép - Kích hoạt lệnh này bằng cách gõ",
|
"are allowed - Activate this command by typing": "được phép - Kích hoạt lệnh này bằng cách gõ",
|
||||||
"Are you sure?": "Bạn có chắc chắn không?",
|
"Are you sure?": "Bạn có chắc chắn không?",
|
||||||
"Audio": "Âm thanh",
|
"Audio": "Âm thanh",
|
||||||
"Auto-playback response": "Tự động phát lại phản hồi (Auto-playback)",
|
"Auto-playback response": "Tự động phát lại phản hồi (Auto-playback)",
|
||||||
"Auto-send input after 3 sec.": "Tự động gửi đầu vào sau 3 giây.",
|
"Auto-send input after 3 sec.": "Tự động gửi đầu vào sau 3 giây.",
|
||||||
"AUTOMATIC1111 Base URL": "Đường dẫn kết nối tới AUTOMATIC1111 (Base URL)",
|
"AUTOMATIC1111 Base URL": "Đường dẫn kết nối tới AUTOMATIC1111 (Base URL)",
|
||||||
"AUTOMATIC1111 Base URL is required.": "Base URL của AUTOMATIC1111 là bắt buộc.",
|
"AUTOMATIC1111 Base URL is required.": "Base URL của AUTOMATIC1111 là bắt buộc.",
|
||||||
"available!": "có sẵn!",
|
"available!": "có sẵn!",
|
||||||
"Back": "Quay lại",
|
"Back": "Quay lại",
|
||||||
"Builder Mode": "Chế độ Builder",
|
"Builder Mode": "Chế độ Builder",
|
||||||
"Cancel": "Hủy bỏ",
|
"Cancel": "Hủy bỏ",
|
||||||
"Categories": "Danh mục",
|
"Categories": "Danh mục",
|
||||||
"Change Password": "Đổi Mật khẩu",
|
"Change Password": "Đổi Mật khẩu",
|
||||||
"Chat": "Trò chuyện",
|
"Chat": "Trò chuyện",
|
||||||
"Chat History": "Lịch sử chat",
|
"Chat History": "Lịch sử chat",
|
||||||
"Chat History is off for this browser.": "Lịch sử chat đã tắt cho trình duyệt này.",
|
"Chat History is off for this browser.": "Lịch sử chat đã tắt cho trình duyệt này.",
|
||||||
"Chats": "Chat",
|
"Chats": "Chat",
|
||||||
"Check Again": "Kiểm tra Lại",
|
"Check Again": "Kiểm tra Lại",
|
||||||
"Check for updates": "Kiểm tra cập nhật",
|
"Check for updates": "Kiểm tra cập nhật",
|
||||||
"Checking for updates...": "Đang kiểm tra cập nhật...",
|
"Checking for updates...": "Đang kiểm tra cập nhật...",
|
||||||
"Choose a model before saving...": "Chọn mô hình trước khi lưu...",
|
"Choose a model before saving...": "Chọn mô hình trước khi lưu...",
|
||||||
"Chunk Overlap": "Kích thước chồng lấn (overlap)",
|
"Chunk Overlap": "Kích thước chồng lấn (overlap)",
|
||||||
"Chunk Params": "Cài đặt số lượng ký tự cho khối ký tự (chunk)",
|
"Chunk Params": "Cài đặt số lượng ký tự cho khối ký tự (chunk)",
|
||||||
"Chunk Size": "Kích thức khối (size)",
|
"Chunk Size": "Kích thức khối (size)",
|
||||||
"Click here for help.": "Bấm vào đây để được trợ giúp.",
|
"Click here for help.": "Bấm vào đây để được trợ giúp.",
|
||||||
"Click here to check other modelfiles.": "Bấm vào đây để kiểm tra các tệp mô tả mô hình (modelfiles) khác.",
|
"Click here to check other modelfiles.": "Bấm vào đây để kiểm tra các tệp mô tả mô hình (modelfiles) khác.",
|
||||||
"Click here to select": "Bấm vào đây để chọn",
|
"Click here to select": "Bấm vào đây để chọn",
|
||||||
"Click here to select documents.": "Bấm vào đây để chọn tài liệu.",
|
"Click here to select documents.": "Bấm vào đây để chọn tài liệu.",
|
||||||
"click here.": "bấm vào đây.",
|
"click here.": "bấm vào đây.",
|
||||||
"Click on the user role button to change a user's role.": "Bấm vào nút trong cột VAI TRÒ để thay đổi quyền của người sử dụng.",
|
"Click on the user role button to change a user's role.": "Bấm vào nút trong cột VAI TRÒ để thay đổi quyền của người sử dụng.",
|
||||||
"Close": "Đóng",
|
"Close": "Đóng",
|
||||||
"Collection": "Bộ sưu tập",
|
"Collection": "Bộ sưu tập",
|
||||||
"Command": "Lệnh",
|
"Command": "Lệnh",
|
||||||
"Confirm Password": "Xác nhận Mật khẩu",
|
"Confirm Password": "Xác nhận Mật khẩu",
|
||||||
"Connections": "Kết nối",
|
"Connections": "Kết nối",
|
||||||
"Content": "Nội dung",
|
"Content": "Nội dung",
|
||||||
"Context Length": "Độ dài ngữ cảnh (Context Length)",
|
"Context Length": "Độ dài ngữ cảnh (Context Length)",
|
||||||
"Conversation Mode": "Chế độ hội thoại",
|
"Conversation Mode": "Chế độ hội thoại",
|
||||||
"Copy last code block": "Sao chép khối mã cuối cùng",
|
"Copy last code block": "Sao chép khối mã cuối cùng",
|
||||||
"Copy last response": "Sao chép phản hồi cuối cùng",
|
"Copy last response": "Sao chép phản hồi cuối cùng",
|
||||||
"Copying to clipboard was successful!": "Sao chép vào clipboard thành công!",
|
"Copying to clipboard was successful!": "Sao chép vào clipboard thành công!",
|
||||||
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Tạo một cụm từ súc tích, 3-5 từ làm tiêu đề cho truy vấn sau, tuân thủ nghiêm ngặt giới hạn 3-5 từ và tránh sử dụng từ 'tiêu đề':",
|
"Create a concise, 3-5 word phrase as a header for the following query, strictly adhering to the 3-5 word limit and avoiding the use of the word 'title':": "Tạo một cụm từ súc tích, 3-5 từ làm tiêu đề cho truy vấn sau, tuân thủ nghiêm ngặt giới hạn 3-5 từ và tránh sử dụng từ 'tiêu đề':",
|
||||||
"Create a modelfile": "Tạo tệp mô tả mô hình",
|
"Create a modelfile": "Tạo tệp mô tả mô hình",
|
||||||
"Create Account": "Tạo Tài khoản",
|
"Create Account": "Tạo Tài khoản",
|
||||||
"Created at": "Được tạo vào lúc",
|
"Created at": "Được tạo vào lúc",
|
||||||
"Created by": "Được tạo bởi",
|
"Created by": "Được tạo bởi",
|
||||||
"Current Model": "Mô hình hiện tại",
|
"Current Model": "Mô hình hiện tại",
|
||||||
"Current Password": "Mật khẩu hiện tại",
|
"Current Password": "Mật khẩu hiện tại",
|
||||||
"Custom": "Tùy chỉnh",
|
"Custom": "Tùy chỉnh",
|
||||||
"Customize Ollama models for a specific purpose": "Tùy chỉnh các mô hình dựa trên Ollama cho một mục đích cụ thể",
|
"Customize Ollama models for a specific purpose": "Tùy chỉnh các mô hình dựa trên Ollama cho một mục đích cụ thể",
|
||||||
"Dark": "Tối",
|
"Dark": "Tối",
|
||||||
"Database": "Cơ sở dữ liệu",
|
"Database": "Cơ sở dữ liệu",
|
||||||
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
"DD/MM/YYYY HH:mm": "DD/MM/YYYY HH:mm",
|
||||||
"Default": "Mặc định",
|
"Default": "Mặc định",
|
||||||
"Default (Automatic1111)": "Mặc định (Automatic1111)",
|
"Default (Automatic1111)": "Mặc định (Automatic1111)",
|
||||||
"Default (Web API)": "Mặc định (Web API)",
|
"Default (Web API)": "Mặc định (Web API)",
|
||||||
"Default model updated": "Mô hình mặc định đã được cập nhật",
|
"Default model updated": "Mô hình mặc định đã được cập nhật",
|
||||||
"Default Prompt Suggestions": "Đề xuất prompt mặc định",
|
"Default Prompt Suggestions": "Đề xuất prompt mặc định",
|
||||||
"Default User Role": "Vai trò mặc định",
|
"Default User Role": "Vai trò mặc định",
|
||||||
"delete": "xóa",
|
"delete": "xóa",
|
||||||
"Delete a model": "Xóa mô hình",
|
"Delete a model": "Xóa mô hình",
|
||||||
"Delete chat": "Xóa nội dung chat",
|
"Delete chat": "Xóa nội dung chat",
|
||||||
"Delete Chats": "Xóa nội dung chat",
|
"Delete Chats": "Xóa nội dung chat",
|
||||||
"Deleted {{deleteModelTag}}": "Đã xóa {{deleteModelTag}}",
|
"Deleted {{deleteModelTag}}": "Đã xóa {{deleteModelTag}}",
|
||||||
"Deleted {tagName}": "Đã xóa {tagName}",
|
"Deleted {tagName}": "Đã xóa {tagName}",
|
||||||
"Description": "Mô tả",
|
"Description": "Mô tả",
|
||||||
"Desktop Notifications": "Thông báo trên máy tính (Notification)",
|
"Desktop Notifications": "Thông báo trên máy tính (Notification)",
|
||||||
"Disabled": "Đã vô hiệu hóa",
|
"Disabled": "Đã vô hiệu hóa",
|
||||||
"Discover a modelfile": "Khám phá thêm các mô hình mới",
|
"Discover a modelfile": "Khám phá thêm các mô hình mới",
|
||||||
"Discover a prompt": "Khám phá thêm prompt mới",
|
"Discover a prompt": "Khám phá thêm prompt mới",
|
||||||
"Discover, download, and explore custom prompts": "Tìm kiếm, tải về và khám phá thêm các prompt tùy chỉnh",
|
"Discover, download, and explore custom prompts": "Tìm kiếm, tải về và khám phá thêm các prompt tùy chỉnh",
|
||||||
"Discover, download, and explore model presets": "Tìm kiếm, tải về và khám phá thêm các thiết lập mô hình sẵn",
|
"Discover, download, and explore model presets": "Tìm kiếm, tải về và khám phá thêm các thiết lập mô hình sẵn",
|
||||||
"Display the username instead of You in the Chat": "Hiển thị tên người sử dụng thay vì 'Bạn' trong nội dung chat",
|
"Display the username instead of You in the Chat": "Hiển thị tên người sử dụng thay vì 'Bạn' trong nội dung chat",
|
||||||
"Document": "Tài liệu",
|
"Document": "Tài liệu",
|
||||||
"Document Settings": "Cấu hình kho tài liệu",
|
"Document Settings": "Cấu hình kho tài liệu",
|
||||||
"Documents": "Tài liệu",
|
"Documents": "Tài liệu",
|
||||||
"does not make any external connections, and your data stays securely on your locally hosted server.": "không thực hiện bất kỳ kết nối ngoài nào, và dữ liệu của bạn vẫn được lưu trữ an toàn trên máy chủ lưu trữ cục bộ của bạn.",
|
"does not make any external connections, and your data stays securely on your locally hosted server.": "không thực hiện bất kỳ kết nối ngoài nào, và dữ liệu của bạn vẫn được lưu trữ an toàn trên máy chủ lưu trữ cục bộ của bạn.",
|
||||||
"Don't Allow": "Không Cho phép",
|
"Don't Allow": "Không Cho phép",
|
||||||
"Don't have an account?": "Không có tài khoản?",
|
"Don't have an account?": "Không có tài khoản?",
|
||||||
"Download as a File": "Tải xuống dưới dạng tệp",
|
"Download as a File": "Tải xuống dưới dạng tệp",
|
||||||
"Download Database": "Tải xuống Cơ sở dữ liệu",
|
"Download Database": "Tải xuống Cơ sở dữ liệu",
|
||||||
"Drop any files here to add to the conversation": "Thả bất kỳ tệp nào ở đây để thêm vào nội dung chat",
|
"Drop any files here to add to the conversation": "Thả bất kỳ tệp nào ở đây để thêm vào nội dung chat",
|
||||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "vd: '30s','10m'. Đơn vị thời gian hợp lệ là 's', 'm', 'h'.",
|
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "vd: '30s','10m'. Đơn vị thời gian hợp lệ là 's', 'm', 'h'.",
|
||||||
"Edit Doc": "Thay đổi tài liệu",
|
"Edit Doc": "Thay đổi tài liệu",
|
||||||
"Edit User": "Thay đổi thông tin người sử dụng",
|
"Edit User": "Thay đổi thông tin người sử dụng",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"Enable Chat History": "Bật Lịch sử chat",
|
"Enable Chat History": "Bật Lịch sử chat",
|
||||||
"Enable New Sign Ups": "Cho phép đăng ký mới",
|
"Enable New Sign Ups": "Cho phép đăng ký mới",
|
||||||
"Enabled": "Đã bật",
|
"Enabled": "Đã bật",
|
||||||
"Enter {{role}} message here": "Nhập yêu cầu của {{role}} ở đây",
|
"Enter {{role}} message here": "Nhập yêu cầu của {{role}} ở đây",
|
||||||
"Enter API Key": "Nhập Khóa API",
|
"Enter API Key": "Nhập Khóa API",
|
||||||
"Enter Chunk Overlap": "Nhập Chunk chồng lấn (overlap)",
|
"Enter Chunk Overlap": "Nhập Chunk chồng lấn (overlap)",
|
||||||
"Enter Chunk Size": "Nhập Kích thước Chunk",
|
"Enter Chunk Size": "Nhập Kích thước Chunk",
|
||||||
"Enter Image Size (e.g. 512x512)": "Nhập Kích thước ảnh (vd: 512x512)",
|
"Enter Image Size (e.g. 512x512)": "Nhập Kích thước ảnh (vd: 512x512)",
|
||||||
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Nhập URL Cơ bản API LiteLLM (litellm_params.api_base)",
|
"Enter LiteLLM API Base URL (litellm_params.api_base)": "Nhập URL Cơ bản API LiteLLM (litellm_params.api_base)",
|
||||||
"Enter LiteLLM API Key (litellm_params.api_key)": "Nhập Khóa API LiteLLM (litellm_params.api_key)",
|
"Enter LiteLLM API Key (litellm_params.api_key)": "Nhập Khóa API LiteLLM (litellm_params.api_key)",
|
||||||
"Enter LiteLLM API RPM (litellm_params.rpm)": "Nhập RPM API LiteLLM (litellm_params.rpm)",
|
"Enter LiteLLM API RPM (litellm_params.rpm)": "Nhập RPM API LiteLLM (litellm_params.rpm)",
|
||||||
"Enter LiteLLM Model (litellm_params.model)": "Nhập Mô hình LiteLLM (litellm_params.model)",
|
"Enter LiteLLM Model (litellm_params.model)": "Nhập Mô hình LiteLLM (litellm_params.model)",
|
||||||
"Enter Max Tokens (litellm_params.max_tokens)": "Nhập Số Token Tối đa (litellm_params.max_tokens)",
|
"Enter Max Tokens (litellm_params.max_tokens)": "Nhập Số Token Tối đa (litellm_params.max_tokens)",
|
||||||
"Enter model tag (e.g. {{modelTag}})": "Nhập thẻ mô hình (vd: {{modelTag}})",
|
"Enter model tag (e.g. {{modelTag}})": "Nhập thẻ mô hình (vd: {{modelTag}})",
|
||||||
"Enter Number of Steps (e.g. 50)": "Nhập số Steps (vd: 50)",
|
"Enter Number of Steps (e.g. 50)": "Nhập số Steps (vd: 50)",
|
||||||
"Enter stop sequence": "Nhập stop sequence",
|
"Enter stop sequence": "Nhập stop sequence",
|
||||||
"Enter Top K": "Nhập Top K",
|
"Enter Top K": "Nhập Top K",
|
||||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "Nhập URL (vd: http://127.0.0.1:7860/)",
|
"Enter URL (e.g. http://127.0.0.1:7860/)": "Nhập URL (vd: http://127.0.0.1:7860/)",
|
||||||
"Enter Your Email": "Nhập Email của bạn",
|
"Enter Your Email": "Nhập Email của bạn",
|
||||||
"Enter Your Full Name": "Nhập Họ và Tên của bạn",
|
"Enter Your Full Name": "Nhập Họ và Tên của bạn",
|
||||||
"Enter Your Password": "Nhập Mật khẩu của bạn",
|
"Enter Your Password": "Nhập Mật khẩu của bạn",
|
||||||
"Experimental": "Thử nghiệm",
|
"Experimental": "Thử nghiệm",
|
||||||
"Export All Chats (All Users)": "Tải về tất cả nội dung chat (tất cả mọi người)",
|
"Export All Chats (All Users)": "Tải về tất cả nội dung chat (tất cả mọi người)",
|
||||||
"Export Chats": "Tải nội dung chat về máy",
|
"Export Chats": "Tải nội dung chat về máy",
|
||||||
"Export Documents Mapping": "Tải cấu trúc tài liệu về máy",
|
"Export Documents Mapping": "Tải cấu trúc tài liệu về máy",
|
||||||
"Export Modelfiles": "Tải tệp mô tả về máy",
|
"Export Modelfiles": "Tải tệp mô tả về máy",
|
||||||
"Export Prompts": "Tải các prompt về máy",
|
"Export Prompts": "Tải các prompt về máy",
|
||||||
"Failed to read clipboard contents": "Không thể đọc nội dung clipboard",
|
"Failed to read clipboard contents": "Không thể đọc nội dung clipboard",
|
||||||
"File Mode": "Chế độ Tệp văn bản",
|
"File Mode": "Chế độ Tệp văn bản",
|
||||||
"File not found.": "Không tìm thấy tệp.",
|
"File not found.": "Không tìm thấy tệp.",
|
||||||
"Focus chat input": "Tập trung vào nội dung chat",
|
"Focus chat input": "Tập trung vào nội dung chat",
|
||||||
"Format your variables using square brackets like this:": "Định dạng các biến của bạn bằng cách sử dụng dấu ngoặc vuông như thế này:",
|
"Format your variables using square brackets like this:": "Định dạng các biến của bạn bằng cách sử dụng dấu ngoặc vuông như thế này:",
|
||||||
"From (Base Model)": "Từ (Base Model)",
|
"From (Base Model)": "Từ (Base Model)",
|
||||||
"Full Screen Mode": "Chế độ Toàn màn hình",
|
"Full Screen Mode": "Chế độ Toàn màn hình",
|
||||||
"General": "Cài đặt chung",
|
"General": "Cài đặt chung",
|
||||||
"General Settings": "Cấu hình chung",
|
"General Settings": "Cấu hình chung",
|
||||||
"Hello, {{name}}": "Xin chào, {{name}}",
|
"Hello, {{name}}": "Xin chào, {{name}}",
|
||||||
"Hide": "Ẩn",
|
"Hide": "Ẩn",
|
||||||
"Hide Additional Params": "Ẩn Các tham số bổ sung",
|
"Hide Additional Params": "Ẩn Các tham số bổ sung",
|
||||||
"How can I help you today?": "Tôi có thể giúp gì cho bạn hôm nay?",
|
"How can I help you today?": "Tôi có thể giúp gì cho bạn hôm nay?",
|
||||||
"Image Generation (Experimental)": "Tạo ảnh (thử nghiệm)",
|
"Image Generation (Experimental)": "Tạo ảnh (thử nghiệm)",
|
||||||
"Image Generation Engine": "Công cụ tạo ảnh",
|
"Image Generation Engine": "Công cụ tạo ảnh",
|
||||||
"Image Settings": "Cài đặt ảnh",
|
"Image Settings": "Cài đặt ảnh",
|
||||||
"Images": "Hình ảnh",
|
"Images": "Hình ảnh",
|
||||||
"Import Chats": "Nạp lại nội dung chat",
|
"Import Chats": "Nạp lại nội dung chat",
|
||||||
"Import Documents Mapping": "Nạp cấu trúc tài liệu",
|
"Import Documents Mapping": "Nạp cấu trúc tài liệu",
|
||||||
"Import Modelfiles": "Nạp tệp mô tả",
|
"Import Modelfiles": "Nạp tệp mô tả",
|
||||||
"Import Prompts": "Nạp các prompt lên hệ thống",
|
"Import Prompts": "Nạp các prompt lên hệ thống",
|
||||||
"Include `--api` flag when running stable-diffusion-webui": "Bao gồm flag `--api` khi chạy stable-diffusion-webui",
|
"Include `--api` flag when running stable-diffusion-webui": "Bao gồm flag `--api` khi chạy stable-diffusion-webui",
|
||||||
"Interface": "Giao diện",
|
"Interface": "Giao diện",
|
||||||
"join our Discord for help.": "tham gia Discord của chúng tôi để được trợ giúp.",
|
"join our Discord for help.": "tham gia Discord của chúng tôi để được trợ giúp.",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"JWT Expiration": "JWT Hết hạn",
|
"JWT Expiration": "JWT Hết hạn",
|
||||||
"JWT Token": "Token JWT",
|
"JWT Token": "Token JWT",
|
||||||
"Keep Alive": "Giữ kết nối",
|
"Keep Alive": "Giữ kết nối",
|
||||||
"Keyboard shortcuts": "Phím tắt",
|
"Keyboard shortcuts": "Phím tắt",
|
||||||
"Language": "Ngôn ngữ",
|
"Language": "Ngôn ngữ",
|
||||||
"Light": "Sáng",
|
"Light": "Sáng",
|
||||||
"Listening...": "Đang nghe...",
|
"Listening...": "Đang nghe...",
|
||||||
"LLMs can make mistakes. Verify important information.": "Hệ thống có thể tạo ra nội dung không chính xác hoặc sai. Hãy kiểm chứng kỹ lưỡng thông tin trước khi tiếp nhận và sử dụng.",
|
"LLMs can make mistakes. Verify important information.": "Hệ thống có thể tạo ra nội dung không chính xác hoặc sai. Hãy kiểm chứng kỹ lưỡng thông tin trước khi tiếp nhận và sử dụng.",
|
||||||
"Made by OpenWebUI Community": "Được tạo bởi Cộng đồng OpenWebUI",
|
"Made by OpenWebUI Community": "Được tạo bởi Cộng đồng OpenWebUI",
|
||||||
"Make sure to enclose them with": "Hãy chắc chắn bao quanh chúng bằng",
|
"Make sure to enclose them with": "Hãy chắc chắn bao quanh chúng bằng",
|
||||||
"Manage LiteLLM Models": "Quản lý mô hình với LiteLLM",
|
"Manage LiteLLM Models": "Quản lý mô hình với LiteLLM",
|
||||||
"Manage Models": "Quản lý mô hình",
|
"Manage Models": "Quản lý mô hình",
|
||||||
"Manage Ollama Models": "Quản lý mô hình với Ollama",
|
"Manage Ollama Models": "Quản lý mô hình với Ollama",
|
||||||
"Max Tokens": "Max Tokens",
|
"Max Tokens": "Max Tokens",
|
||||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Tối đa 3 mô hình có thể được tải xuống cùng lúc. Vui lòng thử lại sau.",
|
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Tối đa 3 mô hình có thể được tải xuống cùng lúc. Vui lòng thử lại sau.",
|
||||||
"Mirostat": "Mirostat",
|
"Mirostat": "Mirostat",
|
||||||
"Mirostat Eta": "Mirostat Eta",
|
"Mirostat Eta": "Mirostat Eta",
|
||||||
"Mirostat Tau": "Mirostat Tau",
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
||||||
"Model '{{modelName}}' has been successfully downloaded.": "Mô hình '{{modelName}}' đã được tải xuống thành công.",
|
"Model '{{modelName}}' has been successfully downloaded.": "Mô hình '{{modelName}}' đã được tải xuống thành công.",
|
||||||
"Model '{{modelTag}}' is already in queue for downloading.": "Mô hình '{{modelTag}}' đã có trong hàng đợi để tải xuống.",
|
"Model '{{modelTag}}' is already in queue for downloading.": "Mô hình '{{modelTag}}' đã có trong hàng đợi để tải xuống.",
|
||||||
"Model {{modelId}} not found": "Không tìm thấy Mô hình {{modelId}}",
|
"Model {{modelId}} not found": "Không tìm thấy Mô hình {{modelId}}",
|
||||||
"Model {{modelName}} already exists.": "Mô hình {{modelName}} đã tồn tại.",
|
"Model {{modelName}} already exists.": "Mô hình {{modelName}} đã tồn tại.",
|
||||||
"Model Name": "Tên Mô hình",
|
"Model Name": "Tên Mô hình",
|
||||||
"Model not selected": "Chưa chọn Mô hình",
|
"Model not selected": "Chưa chọn Mô hình",
|
||||||
"Model Tag Name": "Tên thẻ Mô hình",
|
"Model Tag Name": "Tên thẻ Mô hình",
|
||||||
"Model Whitelisting": "Whitelist mô hình",
|
"Model Whitelisting": "Whitelist mô hình",
|
||||||
"Model(s) Whitelisted": "các mô hình được cho vào danh sách Whitelist",
|
"Model(s) Whitelisted": "các mô hình được cho vào danh sách Whitelist",
|
||||||
"Modelfile": "Tệp Mô hình",
|
"Modelfile": "Tệp Mô hình",
|
||||||
"Modelfile Advanced Settings": "Cài đặt Nâng cao Tệp Mô hình",
|
"Modelfile Advanced Settings": "Cài đặt Nâng cao Tệp Mô hình",
|
||||||
"Modelfile Content": "Nội dung Tệp Mô hình",
|
"Modelfile Content": "Nội dung Tệp Mô hình",
|
||||||
"Modelfiles": "Tệp Mô hình",
|
"Modelfiles": "Tệp Mô hình",
|
||||||
"Models": "Mô hình",
|
"Models": "Mô hình",
|
||||||
"My Documents": "Tài liệu của tôi",
|
"My Documents": "Tài liệu của tôi",
|
||||||
"My Modelfiles": "Tệp Mô hình của tôi",
|
"My Modelfiles": "Tệp Mô hình của tôi",
|
||||||
"My Prompts": "Các prompt của tôi",
|
"My Prompts": "Các prompt của tôi",
|
||||||
"Name": "Tên",
|
"Name": "Tên",
|
||||||
"Name Tag": "Tên Thẻ",
|
"Name Tag": "Tên Thẻ",
|
||||||
"Name your modelfile": "Đặt tên cho tệp mô hình của bạn",
|
"Name your modelfile": "Đặt tên cho tệp mô hình của bạn",
|
||||||
"New Chat": "Tạo cuộc trò chuyện mới",
|
"New Chat": "Tạo cuộc trò chuyện mới",
|
||||||
"New Password": "Mật khẩu mới",
|
"New Password": "Mật khẩu mới",
|
||||||
"Not sure what to add?": "Không chắc phải thêm gì?",
|
"Not sure what to add?": "Không chắc phải thêm gì?",
|
||||||
"Not sure what to write? Switch to": "Không chắc phải viết gì? Chuyển sang",
|
"Not sure what to write? Switch to": "Không chắc phải viết gì? Chuyển sang",
|
||||||
"Off": "Tắt",
|
"Off": "Tắt",
|
||||||
"Okay, Let's Go!": "Được rồi, Bắt đầu thôi!",
|
"Okay, Let's Go!": "Được rồi, Bắt đầu thôi!",
|
||||||
"Ollama Base URL": "Đường dẫn tới API của Ollama (Ollama Base URL)",
|
"Ollama Base URL": "Đường dẫn tới API của Ollama (Ollama Base URL)",
|
||||||
"Ollama Version": "Phiên bản Ollama",
|
"Ollama Version": "Phiên bản Ollama",
|
||||||
"On": "Bật",
|
"On": "Bật",
|
||||||
"Only": "Only",
|
"Only": "Only",
|
||||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Chỉ ký tự số và gạch nối được phép trong chuỗi lệnh.",
|
"Only alphanumeric characters and hyphens are allowed in the command string.": "Chỉ ký tự số và gạch nối được phép trong chuỗi lệnh.",
|
||||||
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Vui lòng kiên nhẫn chờ đợi! Các tệp của bạn vẫn đang trong được phân tích và xử lý. Chúng tôi đang cố gắng hoàn thành chúng. Vui lòng kiên nhẫn và chúng tôi sẽ cho bạn biết khi chúng sẵn sàng.",
|
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Vui lòng kiên nhẫn chờ đợi! Các tệp của bạn vẫn đang trong được phân tích và xử lý. Chúng tôi đang cố gắng hoàn thành chúng. Vui lòng kiên nhẫn và chúng tôi sẽ cho bạn biết khi chúng sẵn sàng.",
|
||||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Rất tiếc! URL dường như không hợp lệ. Vui lòng kiểm tra lại và thử lại.",
|
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Rất tiếc! URL dường như không hợp lệ. Vui lòng kiểm tra lại và thử lại.",
|
||||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Rất tiếc! Bạn đang sử dụng một phương thức không được hỗ trợ (chỉ dành cho frontend). Vui lòng cung cấp phương thức cho WebUI từ phía backend.",
|
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Rất tiếc! Bạn đang sử dụng một phương thức không được hỗ trợ (chỉ dành cho frontend). Vui lòng cung cấp phương thức cho WebUI từ phía backend.",
|
||||||
"Open": "Mở",
|
"Open": "Mở",
|
||||||
"Open AI": "Open AI",
|
"Open AI": "Open AI",
|
||||||
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
"Open AI (Dall-E)": "Open AI (Dall-E)",
|
||||||
"Open new chat": "Mở nội dung chat mới",
|
"Open new chat": "Mở nội dung chat mới",
|
||||||
"OpenAI API": "API OpenAI",
|
"OpenAI API": "API OpenAI",
|
||||||
"OpenAI API Key": "Khóa API OpenAI",
|
"OpenAI API Key": "Khóa API OpenAI",
|
||||||
"OpenAI API Key is required.": "Bắt buộc nhập API OpenAI Key.",
|
"OpenAI API Key is required.": "Bắt buộc nhập API OpenAI Key.",
|
||||||
"or": "hoặc",
|
"or": "hoặc",
|
||||||
"Parameters": "Tham số",
|
"Parameters": "Tham số",
|
||||||
"Password": "Mật khẩu",
|
"Password": "Mật khẩu",
|
||||||
"PDF Extract Images (OCR)": "Trích xuất ảnh từ PDF (OCR)",
|
"PDF Extract Images (OCR)": "Trích xuất ảnh từ PDF (OCR)",
|
||||||
"pending": "đang chờ phê duyệt",
|
"pending": "đang chờ phê duyệt",
|
||||||
"Permission denied when accessing microphone: {{error}}": "Quyền truy cập micrô bị từ chối: {{error}}",
|
"Permission denied when accessing microphone: {{error}}": "Quyền truy cập micrô bị từ chối: {{error}}",
|
||||||
"Playground": "Thử nghiệm (Playground)",
|
"Playground": "Thử nghiệm (Playground)",
|
||||||
"Profile": "Hồ sơ",
|
"Profile": "Hồ sơ",
|
||||||
"Prompt Content": "Nội dung prompt",
|
"Prompt Content": "Nội dung prompt",
|
||||||
"Prompt suggestions": "Gợi ý prompt",
|
"Prompt suggestions": "Gợi ý prompt",
|
||||||
"Prompts": "Prompt",
|
"Prompts": "Prompt",
|
||||||
"Pull a model from Ollama.com": "Tải mô hình từ Ollama.com",
|
"Pull a model from Ollama.com": "Tải mô hình từ Ollama.com",
|
||||||
"Pull Progress": "Tiến trình Tải xuống",
|
"Pull Progress": "Tiến trình Tải xuống",
|
||||||
"Query Params": "Tham số Truy vấn",
|
"Query Params": "Tham số Truy vấn",
|
||||||
"RAG Template": "Mẫu prompt cho RAG",
|
"RAG Template": "Mẫu prompt cho RAG",
|
||||||
"Raw Format": "Raw Format",
|
"Raw Format": "Raw Format",
|
||||||
"Record voice": "Ghi âm",
|
"Record voice": "Ghi âm",
|
||||||
"Redirecting you to OpenWebUI Community": "Đang chuyển hướng bạn đến Cộng đồng OpenWebUI",
|
"Redirecting you to OpenWebUI Community": "Đang chuyển hướng bạn đến Cộng đồng OpenWebUI",
|
||||||
"Release Notes": "Mô tả những cập nhật mới",
|
"Release Notes": "Mô tả những cập nhật mới",
|
||||||
"Repeat Last N": "Repeat Last N",
|
"Repeat Last N": "Repeat Last N",
|
||||||
"Repeat Penalty": "Repeat Penalty",
|
"Repeat Penalty": "Repeat Penalty",
|
||||||
"Request Mode": "Request Mode",
|
"Request Mode": "Request Mode",
|
||||||
"Reset Vector Storage": "Cài đặt lại Vector Storage",
|
"Reset Vector Storage": "Cài đặt lại Vector Storage",
|
||||||
"Response AutoCopy to Clipboard": "Tự động Sao chép Phản hồi vào clipboard",
|
"Response AutoCopy to Clipboard": "Tự động Sao chép Phản hồi vào clipboard",
|
||||||
"Role": "Vai trò",
|
"Role": "Vai trò",
|
||||||
"Rosé Pine": "Rosé Pine",
|
"Rosé Pine": "Rosé Pine",
|
||||||
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
"Rosé Pine Dawn": "Rosé Pine Dawn",
|
||||||
"Save": "Lưu",
|
"Save": "Lưu",
|
||||||
"Save & Create": "Lưu & Tạo",
|
"Save & Create": "Lưu & Tạo",
|
||||||
"Save & Submit": "Lưu & Gửi",
|
"Save & Submit": "Lưu & Gửi",
|
||||||
"Save & Update": "Lưu & Cập nhật",
|
"Save & Update": "Lưu & Cập nhật",
|
||||||
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Không còn hỗ trợ lưu trữ lịch sử chat trực tiếp vào bộ nhớ trình duyệt của bạn. Vui lòng dành thời gian để tải xuống và xóa lịch sử chat của bạn bằng cách nhấp vào nút bên dưới. Đừng lo lắng, bạn có thể dễ dàng nhập lại lịch sử chat của mình vào backend thông qua",
|
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Không còn hỗ trợ lưu trữ lịch sử chat trực tiếp vào bộ nhớ trình duyệt của bạn. Vui lòng dành thời gian để tải xuống và xóa lịch sử chat của bạn bằng cách nhấp vào nút bên dưới. Đừng lo lắng, bạn có thể dễ dàng nhập lại lịch sử chat của mình vào backend thông qua",
|
||||||
"Scan": "Quét tài liệu",
|
"Scan": "Quét tài liệu",
|
||||||
"Scan complete!": "Quét hoàn tất!",
|
"Scan complete!": "Quét hoàn tất!",
|
||||||
"Scan for documents from {{path}}": "Quét tài liệu từ đường dẫn: {{path}}",
|
"Scan for documents from {{path}}": "Quét tài liệu từ đường dẫn: {{path}}",
|
||||||
"Search": "Tìm kiếm",
|
"Search": "Tìm kiếm",
|
||||||
"Search Documents": "Tìm tài liệu",
|
"Search Documents": "Tìm tài liệu",
|
||||||
"Search Prompts": "Tìm prompt",
|
"Search Prompts": "Tìm prompt",
|
||||||
"See readme.md for instructions": "Xem readme.md để biết hướng dẫn",
|
"See readme.md for instructions": "Xem readme.md để biết hướng dẫn",
|
||||||
"See what's new": "Xem những cập nhật mới",
|
"See what's new": "Xem những cập nhật mới",
|
||||||
"Seed": "Seed",
|
"Seed": "Seed",
|
||||||
"Select a mode": "Chọn một chế độ",
|
"Select a mode": "Chọn một chế độ",
|
||||||
"Select a model": "Chọn mô hình",
|
"Select a model": "Chọn mô hình",
|
||||||
"Select an Ollama instance": "Chọn một thực thể Ollama",
|
"Select an Ollama instance": "Chọn một thực thể Ollama",
|
||||||
"Send a Message": "Gửi yêu cầu",
|
"Send a Message": "Gửi yêu cầu",
|
||||||
"Send message": "Gửi yêu cầu",
|
"Send message": "Gửi yêu cầu",
|
||||||
"Server connection verified": "Kết nối máy chủ đã được xác minh",
|
"Server connection verified": "Kết nối máy chủ đã được xác minh",
|
||||||
"Set as default": "Đặt làm mặc định",
|
"Set as default": "Đặt làm mặc định",
|
||||||
"Set Default Model": "Đặt Mô hình Mặc định",
|
"Set Default Model": "Đặt Mô hình Mặc định",
|
||||||
"Set Image Size": "Đặt Kích thước ảnh",
|
"Set Image Size": "Đặt Kích thước ảnh",
|
||||||
"Set Steps": "Đặt Số Bước",
|
"Set Steps": "Đặt Số Bước",
|
||||||
"Set Title Auto-Generation Model": "Đặt tiêu đề tự động",
|
"Set Title Auto-Generation Model": "Đặt tiêu đề tự động",
|
||||||
"Set Voice": "Đặt Giọng nói",
|
"Set Voice": "Đặt Giọng nói",
|
||||||
"Settings": "Cài đặt",
|
"Settings": "Cài đặt",
|
||||||
"Settings saved successfully!": "Cài đặt đã được lưu thành công!",
|
"Settings saved successfully!": "Cài đặt đã được lưu thành công!",
|
||||||
"Share to OpenWebUI Community": "Chia sẻ đến Cộng đồng OpenWebUI",
|
"Share to OpenWebUI Community": "Chia sẻ đến Cộng đồng OpenWebUI",
|
||||||
"short-summary": "tóm tắt ngắn",
|
"short-summary": "tóm tắt ngắn",
|
||||||
"Show": "Hiển thị",
|
"Show": "Hiển thị",
|
||||||
"Show Additional Params": "Hiển thị Tham số Bổ sung",
|
"Show Additional Params": "Hiển thị Tham số Bổ sung",
|
||||||
"Show shortcuts": "Hiển thị phím tắt",
|
"Show shortcuts": "Hiển thị phím tắt",
|
||||||
"sidebar": "thanh bên",
|
"sidebar": "thanh bên",
|
||||||
"Sign in": "Đăng nhập",
|
"Sign in": "Đăng nhập",
|
||||||
"Sign Out": "Đăng xuất",
|
"Sign Out": "Đăng xuất",
|
||||||
"Sign up": "Đăng ký",
|
"Sign up": "Đăng ký",
|
||||||
"Speech recognition error: {{error}}": "Lỗi nhận dạng giọng nói: {{error}}",
|
"Speech recognition error: {{error}}": "Lỗi nhận dạng giọng nói: {{error}}",
|
||||||
"Speech-to-Text Engine": "Công cụ Nhận dạng Giọng nói",
|
"Speech-to-Text Engine": "Công cụ Nhận dạng Giọng nói",
|
||||||
"SpeechRecognition API is not supported in this browser.": "Trình duyệt này không hỗ trợ API Nhận dạng Giọng nói.",
|
"SpeechRecognition API is not supported in this browser.": "Trình duyệt này không hỗ trợ API Nhận dạng Giọng nói.",
|
||||||
"Stop Sequence": "Trình tự Dừng",
|
"Stop Sequence": "Trình tự Dừng",
|
||||||
"STT Settings": "Cài đặt Nhận dạng Giọng nói",
|
"STT Settings": "Cài đặt Nhận dạng Giọng nói",
|
||||||
"Submit": "Gửi",
|
"Submit": "Gửi",
|
||||||
"Success": "Thành công",
|
"Success": "Thành công",
|
||||||
"Successfully updated.": "Đã cập nhật thành công.",
|
"Successfully updated.": "Đã cập nhật thành công.",
|
||||||
"Sync All": "Đồng bộ hóa Tất cả",
|
"Sync All": "Đồng bộ hóa Tất cả",
|
||||||
"System": "Hệ thống",
|
"System": "Hệ thống",
|
||||||
"System Prompt": "Prompt Hệ thống (System Prompt)",
|
"System Prompt": "Prompt Hệ thống (System Prompt)",
|
||||||
"Tags": "Thẻ",
|
"Tags": "Thẻ",
|
||||||
"Temperature": "Temperature",
|
"Temperature": "Temperature",
|
||||||
"Template": "Mẫu",
|
"Template": "Mẫu",
|
||||||
"Text Completion": "Hoàn tất Văn bản",
|
"Text Completion": "Hoàn tất Văn bản",
|
||||||
"Text-to-Speech Engine": "Công cụ Chuyển Văn bản thành Giọng nói",
|
"Text-to-Speech Engine": "Công cụ Chuyển Văn bản thành Giọng nói",
|
||||||
"Tfs Z": "Tfs Z",
|
"Tfs Z": "Tfs Z",
|
||||||
"Theme": "Chủ đề",
|
"Theme": "Chủ đề",
|
||||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Điều này đảm bảo rằng các nội dung chat có giá trị của bạn được lưu an toàn vào cơ sở dữ liệu backend của bạn. Cảm ơn bạn!",
|
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Điều này đảm bảo rằng các nội dung chat có giá trị của bạn được lưu an toàn vào cơ sở dữ liệu backend của bạn. Cảm ơn bạn!",
|
||||||
"This setting does not sync across browsers or devices.": "Cài đặt này không đồng bộ hóa trên các trình duyệt hoặc thiết bị.",
|
"This setting does not sync across browsers or devices.": "Cài đặt này không đồng bộ hóa trên các trình duyệt hoặc thiết bị.",
|
||||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Mẹo: Cập nhật nhiều khe biến liên tiếp bằng cách nhấn phím tab trong đầu vào trò chuyện sau mỗi việc thay thế.",
|
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Mẹo: Cập nhật nhiều khe biến liên tiếp bằng cách nhấn phím tab trong đầu vào trò chuyện sau mỗi việc thay thế.",
|
||||||
"Title": "Tiêu đề",
|
"Title": "Tiêu đề",
|
||||||
"Title Auto-Generation": "Tự động Tạo Tiêu đề",
|
"Title Auto-Generation": "Tự động Tạo Tiêu đề",
|
||||||
"Title Generation Prompt": "Prompt tạo tiêu đề",
|
"Title Generation Prompt": "Prompt tạo tiêu đề",
|
||||||
"to": "đến",
|
"to": "đến",
|
||||||
"To access the available model names for downloading,": "Để truy cập các tên mô hình có sẵn để tải xuống,",
|
"To access the available model names for downloading,": "Để truy cập các tên mô hình có sẵn để tải xuống,",
|
||||||
"To access the GGUF models available for downloading,": "Để truy cập các mô hình GGUF có sẵn để tải xuống,",
|
"To access the GGUF models available for downloading,": "Để truy cập các mô hình GGUF có sẵn để tải xuống,",
|
||||||
"to chat input.": "đến đầu vào trò chuyện.",
|
"to chat input.": "đến đầu vào trò chuyện.",
|
||||||
"Toggle settings": "Bật/tắt cài đặt",
|
"Toggle settings": "Bật/tắt cài đặt",
|
||||||
"Toggle sidebar": "Bật/tắt thanh bên",
|
"Toggle sidebar": "Bật/tắt thanh bên",
|
||||||
"Top K": "Top K",
|
"Top K": "Top K",
|
||||||
"Top P": "Top P",
|
"Top P": "Top P",
|
||||||
"Trouble accessing Ollama?": "Gặp vấn đề khi truy cập Ollama?",
|
"Trouble accessing Ollama?": "Gặp vấn đề khi truy cập Ollama?",
|
||||||
"TTS Settings": "Cài đặt Chuyển văn bản thành Giọng nói",
|
"TTS Settings": "Cài đặt Chuyển văn bản thành Giọng nói",
|
||||||
"Type Hugging Face Resolve (Download) URL": "Nhập URL Hugging Face Resolve (Tải xuống)",
|
"Type Hugging Face Resolve (Download) URL": "Nhập URL Hugging Face Resolve (Tải xuống)",
|
||||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Ồ! Đã xảy ra sự cố khi kết nối với {{provider}}.",
|
"Uh-oh! There was an issue connecting to {{provider}}.": "Ồ! Đã xảy ra sự cố khi kết nối với {{provider}}.",
|
||||||
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Loại Tệp Không xác định '{{file_type}}', nhưng đang chấp nhận và xử lý như văn bản thô",
|
"Unknown File Type '{{file_type}}', but accepting and treating as plain text": "Loại Tệp Không xác định '{{file_type}}', nhưng đang chấp nhận và xử lý như văn bản thô",
|
||||||
"Update password": "Cập nhật mật khẩu",
|
"Update password": "Cập nhật mật khẩu",
|
||||||
"Upload a GGUF model": "Tải lên mô hình GGUF",
|
"Upload a GGUF model": "Tải lên mô hình GGUF",
|
||||||
"Upload files": "Tải tệp lên hệ thống",
|
"Upload files": "Tải tệp lên hệ thống",
|
||||||
"Upload Progress": "Tiến trình tải tệp lên hệ thống",
|
"Upload Progress": "Tiến trình tải tệp lên hệ thống",
|
||||||
"URL Mode": "Chế độ URL",
|
"URL Mode": "Chế độ URL",
|
||||||
"Use '#' in the prompt input to load and select your documents.": "Sử dụng '#' trong đầu vào của prompt để tải về và lựa chọn tài liệu của bạn cần truy vấn.",
|
"Use '#' in the prompt input to load and select your documents.": "Sử dụng '#' trong đầu vào của prompt để tải về và lựa chọn tài liệu của bạn cần truy vấn.",
|
||||||
"Use Gravatar": "Sử dụng Gravatar",
|
"Use Gravatar": "Sử dụng Gravatar",
|
||||||
"user": "Người sử dụng",
|
"user": "Người sử dụng",
|
||||||
"User Permissions": "Phân quyền sử dụng",
|
"User Permissions": "Phân quyền sử dụng",
|
||||||
"Users": "người sử dụng",
|
"Users": "người sử dụng",
|
||||||
"Utilize": "Sử dụng",
|
"Utilize": "Sử dụng",
|
||||||
"Valid time units:": "Đơn vị thời gian hợp lệ:",
|
"Valid time units:": "Đơn vị thời gian hợp lệ:",
|
||||||
"variable": "biến",
|
"variable": "biến",
|
||||||
"variable to have them replaced with clipboard content.": "biến để có chúng được thay thế bằng nội dung clipboard.",
|
"variable to have them replaced with clipboard content.": "biến để có chúng được thay thế bằng nội dung clipboard.",
|
||||||
"Version": "Phiên bản",
|
"Version": "Phiên bản",
|
||||||
"Web": "Web",
|
"Web": "Web",
|
||||||
"WebUI Add-ons": "Tiện ích WebUI",
|
"WebUI Add-ons": "Tiện ích WebUI",
|
||||||
"WebUI Settings": "Cài đặt WebUI",
|
"WebUI Settings": "Cài đặt WebUI",
|
||||||
"WebUI will make requests to": "WebUI sẽ thực hiện các yêu cầu đến",
|
"WebUI will make requests to": "WebUI sẽ thực hiện các yêu cầu đến",
|
||||||
"What's New in": "Có gì mới trong",
|
"What's New in": "Có gì mới trong",
|
||||||
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Khi chế độ lịch sử chat đã tắt, các nội dung chat mới trên trình duyệt này sẽ không xuất hiện trên bất kỳ thiết bị nào của bạn.",
|
"When history is turned off, new chats on this browser won't appear in your history on any of your devices.": "Khi chế độ lịch sử chat đã tắt, các nội dung chat mới trên trình duyệt này sẽ không xuất hiện trên bất kỳ thiết bị nào của bạn.",
|
||||||
"Whisper (Local)": "Whisper (Local)",
|
"Whisper (Local)": "Whisper (Local)",
|
||||||
"Write a prompt suggestion (e.g. Who are you?)": "Hãy viết một prompt (vd: Bạn là ai?)",
|
"Write a prompt suggestion (e.g. Who are you?)": "Hãy viết một prompt (vd: Bạn là ai?)",
|
||||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Viết một tóm tắt trong vòng 50 từ cho [chủ đề hoặc từ khóa].",
|
"Write a summary in 50 words that summarizes [topic or keyword].": "Viết một tóm tắt trong vòng 50 từ cho [chủ đề hoặc từ khóa].",
|
||||||
"You": "Bạn",
|
"You": "Bạn",
|
||||||
"You're a helpful assistant.": "Bạn là một trợ lý hữu ích.",
|
"You're a helpful assistant.": "Bạn là một trợ lý hữu ích.",
|
||||||
"You're now logged in.": "Bạn đã đăng nhập."
|
"You're now logged in.": "Bạn đã đăng nhập."
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@ export const config = writable(undefined);
|
||||||
export const user = writable(undefined);
|
export const user = writable(undefined);
|
||||||
|
|
||||||
// Frontend
|
// Frontend
|
||||||
export const theme = writable('system');
|
export const MODEL_DOWNLOAD_POOL = writable({});
|
||||||
|
|
||||||
|
export const theme = writable('system');
|
||||||
export const chatId = writable('');
|
export const chatId = writable('');
|
||||||
|
|
||||||
export const chats = writable([]);
|
export const chats = writable([]);
|
||||||
|
|
|
@ -1,10 +1,55 @@
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import sha256 from 'js-sha256';
|
import sha256 from 'js-sha256';
|
||||||
|
import { getOllamaModels } from '$lib/apis/ollama';
|
||||||
|
import { getOpenAIModels } from '$lib/apis/openai';
|
||||||
|
import { getLiteLLMModels } from '$lib/apis/litellm';
|
||||||
|
|
||||||
|
export const getModels = async (token: string) => {
|
||||||
|
let models = await Promise.all([
|
||||||
|
await getOllamaModels(token).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
await getOpenAIModels(token).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
await getLiteLLMModels(token).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
models = models
|
||||||
|
.filter((models) => models)
|
||||||
|
.reduce((a, e, i, arr) => a.concat(e, ...(i < arr.length - 1 ? [{ name: 'hr' }] : [])), []);
|
||||||
|
|
||||||
|
return models;
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// Helper functions
|
// Helper functions
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
export const sanitizeResponseContent = (content: string) => {
|
||||||
|
return content
|
||||||
|
.replace(/<\|[a-z]*$/, '')
|
||||||
|
.replace(/<\|[a-z]+\|$/, '')
|
||||||
|
.replace(/<$/, '')
|
||||||
|
.replaceAll(/<\|[a-z]+\|>/g, ' ')
|
||||||
|
.replaceAll(/<br\s?\/?>/gi, '\n')
|
||||||
|
.replaceAll('<', '<')
|
||||||
|
.trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const revertSanitizedResponseContent = (content: string) => {
|
||||||
|
return content.replaceAll('<', '<');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const capitalizeFirstLetter = (string) => {
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
export const splitStream = (splitOn) => {
|
export const splitStream = (splitOn) => {
|
||||||
let buffer = '';
|
let buffer = '';
|
||||||
return new TransformStream({
|
return new TransformStream({
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue