Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
e31cf081
"...hubert/git@developer.sourcefind.cn:hehl2/torchaudio.git" did not exist on "984b169e240aa250803c0e0b892b26f3fbb1bab0"
Commit
e31cf081
authored
May 06, 2024
by
Jannik Streidl
Browse files
merged conflicts in PL locale
parents
e57c0c30
e92311b4
Changes
47
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
752 additions
and
134 deletions
+752
-134
backend/apps/images/main.py
backend/apps/images/main.py
+33
-21
backend/apps/litellm/main.py
backend/apps/litellm/main.py
+4
-0
backend/apps/ollama/main.py
backend/apps/ollama/main.py
+15
-8
backend/apps/web/routers/chats.py
backend/apps/web/routers/chats.py
+74
-64
backend/main.py
backend/main.py
+3
-1
cypress/e2e/chat.cy.ts
cypress/e2e/chat.cy.ts
+2
-2
src/lib/apis/chats/index.ts
src/lib/apis/chats/index.ts
+19
-6
src/lib/components/chat/MessageInput.svelte
src/lib/components/chat/MessageInput.svelte
+4
-1
src/lib/components/chat/ModelSelector/Selector.svelte
src/lib/components/chat/ModelSelector/Selector.svelte
+15
-5
src/lib/components/chat/ShortcutsModal.svelte
src/lib/components/chat/ShortcutsModal.svelte
+52
-0
src/lib/components/chat/Tags.svelte
src/lib/components/chat/Tags.svelte
+21
-3
src/lib/components/common/ImagePreview.svelte
src/lib/components/common/ImagePreview.svelte
+1
-1
src/lib/components/layout/Sidebar.svelte
src/lib/components/layout/Sidebar.svelte
+35
-21
src/lib/components/layout/Sidebar/ChatMenu.svelte
src/lib/components/layout/Sidebar/ChatMenu.svelte
+7
-1
src/lib/i18n/locales/ar-BH/translation.json
src/lib/i18n/locales/ar-BH/translation.json
+447
-0
src/lib/i18n/locales/bg-BG/translation.json
src/lib/i18n/locales/bg-BG/translation.json
+4
-0
src/lib/i18n/locales/bn-BD/translation.json
src/lib/i18n/locales/bn-BD/translation.json
+4
-0
src/lib/i18n/locales/ca-ES/translation.json
src/lib/i18n/locales/ca-ES/translation.json
+4
-0
src/lib/i18n/locales/de-DE/translation.json
src/lib/i18n/locales/de-DE/translation.json
+4
-0
src/lib/i18n/locales/dg-DG/translation.json
src/lib/i18n/locales/dg-DG/translation.json
+4
-0
No files found.
backend/apps/images/main.py
View file @
e31cf081
...
@@ -317,19 +317,31 @@ class GenerateImageForm(BaseModel):
...
@@ -317,19 +317,31 @@ class GenerateImageForm(BaseModel):
def
save_b64_image
(
b64_str
):
def
save_b64_image
(
b64_str
):
try
:
try
:
header
,
encoded
=
b64_str
.
split
(
","
,
1
)
image_id
=
str
(
uuid
.
uuid4
())
mime_type
=
header
.
split
(
";"
)[
0
]
img_data
=
base64
.
b64decode
(
encoded
)
if
","
in
b64_str
:
header
,
encoded
=
b64_str
.
split
(
","
,
1
)
mime_type
=
header
.
split
(
";"
)[
0
]
image_id
=
str
(
uuid
.
uuid4
())
img_data
=
base64
.
b64decode
(
encoded
)
image_format
=
mimetypes
.
guess_extension
(
mime_type
)
image_format
=
mimetypes
.
guess_extension
(
mime_type
)
image_filename
=
f
"
{
image_id
}{
image_format
}
"
file_path
=
IMAGE_CACHE_DIR
/
f
"
{
image_filename
}
"
with
open
(
file_path
,
"wb"
)
as
f
:
f
.
write
(
img_data
)
return
image_filename
else
:
image_filename
=
f
"
{
image_id
}
.png"
file_path
=
IMAGE_CACHE_DIR
.
joinpath
(
image_filename
)
img_data
=
base64
.
b64decode
(
b64_str
)
# Write the image data to a file
with
open
(
file_path
,
"wb"
)
as
f
:
f
.
write
(
img_data
)
return
image_filename
image_filename
=
f
"
{
image_id
}{
image_format
}
"
file_path
=
IMAGE_CACHE_DIR
/
f
"
{
image_filename
}
"
with
open
(
file_path
,
"wb"
)
as
f
:
f
.
write
(
img_data
)
return
image_filename
except
Exception
as
e
:
except
Exception
as
e
:
log
.
exception
(
f
"Error saving image:
{
e
}
"
)
log
.
exception
(
f
"Error saving image:
{
e
}
"
)
return
None
return
None
...
@@ -348,18 +360,20 @@ def save_url_image(url):
...
@@ -348,18 +360,20 @@ def save_url_image(url):
if
not
image_format
:
if
not
image_format
:
raise
ValueError
(
"Could not determine image type from MIME type"
)
raise
ValueError
(
"Could not determine image type from MIME type"
)
file_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_id
}{
image_format
}
"
)
image_filename
=
f
"
{
image_id
}{
image_format
}
"
file_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_filename
}
"
)
with
open
(
file_path
,
"wb"
)
as
image_file
:
with
open
(
file_path
,
"wb"
)
as
image_file
:
for
chunk
in
r
.
iter_content
(
chunk_size
=
8192
):
for
chunk
in
r
.
iter_content
(
chunk_size
=
8192
):
image_file
.
write
(
chunk
)
image_file
.
write
(
chunk
)
return
image_
id
,
image_format
return
image_
filename
else
:
else
:
log
.
error
(
f
"Url does not point to an image."
)
log
.
error
(
f
"Url does not point to an image."
)
return
None
,
None
return
None
except
Exception
as
e
:
except
Exception
as
e
:
log
.
exception
(
f
"Error saving image:
{
e
}
"
)
log
.
exception
(
f
"Error saving image:
{
e
}
"
)
return
None
,
None
return
None
@
app
.
post
(
"/generations"
)
@
app
.
post
(
"/generations"
)
...
@@ -400,7 +414,7 @@ def generate_image(
...
@@ -400,7 +414,7 @@ def generate_image(
for
image
in
res
[
"data"
]:
for
image
in
res
[
"data"
]:
image_filename
=
save_b64_image
(
image
[
"b64_json"
])
image_filename
=
save_b64_image
(
image
[
"b64_json"
])
images
.
append
({
"url"
:
f
"/cache/image/generations/
{
image_filename
}
"
})
images
.
append
({
"url"
:
f
"/cache/image/generations/
{
image_filename
}
"
})
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_
id
}
.json"
)
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_
filename
}
.json"
)
with
open
(
file_body_path
,
"w"
)
as
f
:
with
open
(
file_body_path
,
"w"
)
as
f
:
json
.
dump
(
data
,
f
)
json
.
dump
(
data
,
f
)
...
@@ -435,11 +449,9 @@ def generate_image(
...
@@ -435,11 +449,9 @@ def generate_image(
images
=
[]
images
=
[]
for
image
in
res
[
"data"
]:
for
image
in
res
[
"data"
]:
image_id
,
image_format
=
save_url_image
(
image
[
"url"
])
image_filename
=
save_url_image
(
image
[
"url"
])
images
.
append
(
images
.
append
({
"url"
:
f
"/cache/image/generations/
{
image_filename
}
"
})
{
"url"
:
f
"/cache/image/generations/
{
image_id
}{
image_format
}
"
}
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_filename
}
.json"
)
)
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_id
}
.json"
)
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
)
...
@@ -477,7 +489,7 @@ def generate_image(
...
@@ -477,7 +489,7 @@ def generate_image(
for
image
in
res
[
"images"
]:
for
image
in
res
[
"images"
]:
image_filename
=
save_b64_image
(
image
)
image_filename
=
save_b64_image
(
image
)
images
.
append
({
"url"
:
f
"/cache/image/generations/
{
image_filename
}
"
})
images
.
append
({
"url"
:
f
"/cache/image/generations/
{
image_filename
}
"
})
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_
id
}
.json"
)
file_body_path
=
IMAGE_CACHE_DIR
.
joinpath
(
f
"
{
image_
filename
}
.json"
)
with
open
(
file_body_path
,
"w"
)
as
f
:
with
open
(
file_body_path
,
"w"
)
as
f
:
json
.
dump
({
**
data
,
"info"
:
res
[
"info"
]},
f
)
json
.
dump
({
**
data
,
"info"
:
res
[
"info"
]},
f
)
...
...
backend/apps/litellm/main.py
View file @
e31cf081
...
@@ -36,6 +36,10 @@ from config import (
...
@@ -36,6 +36,10 @@ from config import (
LITELLM_PROXY_HOST
,
LITELLM_PROXY_HOST
,
)
)
import
warnings
warnings
.
simplefilter
(
"ignore"
)
from
litellm.utils
import
get_llm_provider
from
litellm.utils
import
get_llm_provider
import
asyncio
import
asyncio
...
...
backend/apps/ollama/main.py
View file @
e31cf081
...
@@ -31,7 +31,12 @@ from typing import Optional, List, Union
...
@@ -31,7 +31,12 @@ from typing import Optional, List, Union
from
apps.web.models.users
import
Users
from
apps.web.models.users
import
Users
from
constants
import
ERROR_MESSAGES
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_verified_user
,
get_admin_user
,
)
from
config
import
(
from
config
import
(
...
@@ -164,7 +169,7 @@ async def get_all_models():
...
@@ -164,7 +169,7 @@ async def get_all_models():
@
app
.
get
(
"/api/tags"
)
@
app
.
get
(
"/api/tags"
)
@
app
.
get
(
"/api/tags/{url_idx}"
)
@
app
.
get
(
"/api/tags/{url_idx}"
)
async
def
get_ollama_tags
(
async
def
get_ollama_tags
(
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
current
_user
)
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
verified
_user
)
):
):
if
url_idx
==
None
:
if
url_idx
==
None
:
models
=
await
get_all_models
()
models
=
await
get_all_models
()
...
@@ -563,7 +568,7 @@ async def delete_model(
...
@@ -563,7 +568,7 @@ async def delete_model(
@
app
.
post
(
"/api/show"
)
@
app
.
post
(
"/api/show"
)
async
def
show_model_info
(
form_data
:
ModelNameForm
,
user
=
Depends
(
get_
current
_user
)):
async
def
show_model_info
(
form_data
:
ModelNameForm
,
user
=
Depends
(
get_
verified
_user
)):
if
form_data
.
name
not
in
app
.
state
.
MODELS
:
if
form_data
.
name
not
in
app
.
state
.
MODELS
:
raise
HTTPException
(
raise
HTTPException
(
status_code
=
400
,
status_code
=
400
,
...
@@ -612,7 +617,7 @@ class GenerateEmbeddingsForm(BaseModel):
...
@@ -612,7 +617,7 @@ class GenerateEmbeddingsForm(BaseModel):
async
def
generate_embeddings
(
async
def
generate_embeddings
(
form_data
:
GenerateEmbeddingsForm
,
form_data
:
GenerateEmbeddingsForm
,
url_idx
:
Optional
[
int
]
=
None
,
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
current
_user
),
user
=
Depends
(
get_
verified
_user
),
):
):
if
url_idx
==
None
:
if
url_idx
==
None
:
model
=
form_data
.
model
model
=
form_data
.
model
...
@@ -730,7 +735,7 @@ class GenerateCompletionForm(BaseModel):
...
@@ -730,7 +735,7 @@ class GenerateCompletionForm(BaseModel):
async
def
generate_completion
(
async
def
generate_completion
(
form_data
:
GenerateCompletionForm
,
form_data
:
GenerateCompletionForm
,
url_idx
:
Optional
[
int
]
=
None
,
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
current
_user
),
user
=
Depends
(
get_
verified
_user
),
):
):
if
url_idx
==
None
:
if
url_idx
==
None
:
...
@@ -833,7 +838,7 @@ class GenerateChatCompletionForm(BaseModel):
...
@@ -833,7 +838,7 @@ class GenerateChatCompletionForm(BaseModel):
async
def
generate_chat_completion
(
async
def
generate_chat_completion
(
form_data
:
GenerateChatCompletionForm
,
form_data
:
GenerateChatCompletionForm
,
url_idx
:
Optional
[
int
]
=
None
,
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
current
_user
),
user
=
Depends
(
get_
verified
_user
),
):
):
if
url_idx
==
None
:
if
url_idx
==
None
:
...
@@ -942,7 +947,7 @@ class OpenAIChatCompletionForm(BaseModel):
...
@@ -942,7 +947,7 @@ class OpenAIChatCompletionForm(BaseModel):
async
def
generate_openai_chat_completion
(
async
def
generate_openai_chat_completion
(
form_data
:
OpenAIChatCompletionForm
,
form_data
:
OpenAIChatCompletionForm
,
url_idx
:
Optional
[
int
]
=
None
,
url_idx
:
Optional
[
int
]
=
None
,
user
=
Depends
(
get_
current
_user
),
user
=
Depends
(
get_
verified
_user
),
):
):
if
url_idx
==
None
:
if
url_idx
==
None
:
...
@@ -1241,7 +1246,9 @@ def upload_model(file: UploadFile = File(...), url_idx: Optional[int] = None):
...
@@ -1241,7 +1246,9 @@ def upload_model(file: UploadFile = File(...), url_idx: Optional[int] = None):
@
app
.
api_route
(
"/{path:path}"
,
methods
=
[
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
])
@
app
.
api_route
(
"/{path:path}"
,
methods
=
[
"GET"
,
"POST"
,
"PUT"
,
"DELETE"
])
async
def
deprecated_proxy
(
path
:
str
,
request
:
Request
,
user
=
Depends
(
get_current_user
)):
async
def
deprecated_proxy
(
path
:
str
,
request
:
Request
,
user
=
Depends
(
get_verified_user
)
):
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
0
]
url
=
app
.
state
.
OLLAMA_BASE_URLS
[
0
]
target_url
=
f
"
{
url
}
/
{
path
}
"
target_url
=
f
"
{
url
}
/
{
path
}
"
...
...
backend/apps/web/routers/chats.py
View file @
e31cf081
...
@@ -93,6 +93,31 @@ async def get_archived_session_user_chat_list(
...
@@ -93,6 +93,31 @@ async def get_archived_session_user_chat_list(
return
Chats
.
get_archived_chat_list_by_user_id
(
user
.
id
,
skip
,
limit
)
return
Chats
.
get_archived_chat_list_by_user_id
(
user
.
id
,
skip
,
limit
)
############################
# 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
)):
if
user
.
role
==
"pending"
:
raise
HTTPException
(
status_code
=
status
.
HTTP_401_UNAUTHORIZED
,
detail
=
ERROR_MESSAGES
.
NOT_FOUND
)
if
user
.
role
==
"user"
:
chat
=
Chats
.
get_chat_by_share_id
(
share_id
)
elif
user
.
role
==
"admin"
:
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
)
############################
############################
# GetChats
# GetChats
############################
############################
...
@@ -141,6 +166,55 @@ async def create_new_chat(form_data: ChatForm, user=Depends(get_current_user)):
...
@@ -141,6 +166,55 @@ async def create_new_chat(form_data: ChatForm, user=Depends(get_current_user)):
)
)
############################
# GetChatsByTags
############################
class
TagNameForm
(
BaseModel
):
name
:
str
skip
:
Optional
[
int
]
=
0
limit
:
Optional
[
int
]
=
50
@
router
.
post
(
"/tags"
,
response_model
=
List
[
ChatTitleIdResponse
])
async
def
get_user_chat_list_by_tag_name
(
form_data
:
TagNameForm
,
user
=
Depends
(
get_current_user
)
):
print
(
form_data
)
chat_ids
=
[
chat_id_tag
.
chat_id
for
chat_id_tag
in
Tags
.
get_chat_ids_by_tag_name_and_user_id
(
form_data
.
name
,
user
.
id
)
]
chats
=
Chats
.
get_chat_list_by_chat_ids
(
chat_ids
,
form_data
.
skip
,
form_data
.
limit
)
if
len
(
chats
)
==
0
:
Tags
.
delete_tag_by_tag_name_and_user_id
(
form_data
.
name
,
user
.
id
)
return
chats
############################
# GetAllTags
############################
@
router
.
get
(
"/tags/all"
,
response_model
=
List
[
TagModel
])
async
def
get_all_tags
(
user
=
Depends
(
get_current_user
)):
try
:
tags
=
Tags
.
get_tags_by_user_id
(
user
.
id
)
return
tags
except
Exception
as
e
:
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
()
)
############################
############################
# GetChatById
# GetChatById
############################
############################
...
@@ -274,70 +348,6 @@ async def delete_shared_chat_by_id(id: str, user=Depends(get_current_user)):
...
@@ -274,70 +348,6 @@ async def delete_shared_chat_by_id(id: str, user=Depends(get_current_user)):
)
)
############################
# 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
)):
if
user
.
role
==
"pending"
:
raise
HTTPException
(
status_code
=
status
.
HTTP_401_UNAUTHORIZED
,
detail
=
ERROR_MESSAGES
.
NOT_FOUND
)
if
user
.
role
==
"user"
:
chat
=
Chats
.
get_chat_by_share_id
(
share_id
)
elif
user
.
role
==
"admin"
:
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
)
############################
# GetAllTags
############################
@
router
.
get
(
"/tags/all"
,
response_model
=
List
[
TagModel
])
async
def
get_all_tags
(
user
=
Depends
(
get_current_user
)):
try
:
tags
=
Tags
.
get_tags_by_user_id
(
user
.
id
)
return
tags
except
Exception
as
e
:
log
.
exception
(
e
)
raise
HTTPException
(
status_code
=
status
.
HTTP_400_BAD_REQUEST
,
detail
=
ERROR_MESSAGES
.
DEFAULT
()
)
############################
# GetChatsByTags
############################
@
router
.
get
(
"/tags/tag/{tag_name}"
,
response_model
=
List
[
ChatTitleIdResponse
])
async
def
get_user_chat_list_by_tag_name
(
tag_name
:
str
,
user
=
Depends
(
get_current_user
),
skip
:
int
=
0
,
limit
:
int
=
50
):
chat_ids
=
[
chat_id_tag
.
chat_id
for
chat_id_tag
in
Tags
.
get_chat_ids_by_tag_name_and_user_id
(
tag_name
,
user
.
id
)
]
chats
=
Chats
.
get_chat_list_by_chat_ids
(
chat_ids
,
skip
,
limit
)
if
len
(
chats
)
==
0
:
Tags
.
delete_tag_by_tag_name_and_user_id
(
tag_name
,
user
.
id
)
return
chats
############################
############################
# GetChatTagsById
# GetChatTagsById
############################
############################
...
...
backend/main.py
View file @
e31cf081
...
@@ -25,6 +25,8 @@ from apps.litellm.main import (
...
@@ -25,6 +25,8 @@ from apps.litellm.main import (
start_litellm_background
,
start_litellm_background
,
shutdown_litellm_background
,
shutdown_litellm_background
,
)
)
from
apps.audio.main
import
app
as
audio_app
from
apps.audio.main
import
app
as
audio_app
from
apps.images.main
import
app
as
images_app
from
apps.images.main
import
app
as
images_app
from
apps.rag.main
import
app
as
rag_app
from
apps.rag.main
import
app
as
rag_app
...
@@ -74,7 +76,7 @@ class SPAStaticFiles(StaticFiles):
...
@@ -74,7 +76,7 @@ class SPAStaticFiles(StaticFiles):
print
(
print
(
f
"""
r
f
"""
___ __ __ _ _ _ ___
___ __ __ _ _ _ ___
/ _ \ _ __ ___ _ __ \ \ / /__| |__ | | | |_ _|
/ _ \ _ __ ___ _ __ \ \ / /__| |__ | | | |_ _|
| | | | '_ \ / _ \ '_ \ \ \ /\ / / _ \ '_ \| | | || |
| | | | '_ \ / _ \ '_ \ \ \ /\ / / _ \ '_ \| | | || |
...
...
cypress/e2e/chat.cy.ts
View file @
e31cf081
...
@@ -21,14 +21,14 @@ describe('Settings', () => {
...
@@ -21,14 +21,14 @@ describe('Settings', () => {
// Click on the model selector
// Click on the model selector
cy
.
get
(
'
button[aria-label="Select a model"]
'
).
click
();
cy
.
get
(
'
button[aria-label="Select a model"]
'
).
click
();
// Select the first model
// Select the first model
cy
.
get
(
'
div[role="option"][data-value
]
'
).
first
().
click
();
cy
.
get
(
'
button[aria-label="model-item"
]
'
).
first
().
click
();
});
});
it
(
'
user can perform text chat
'
,
()
=>
{
it
(
'
user can perform text chat
'
,
()
=>
{
// Click on the model selector
// Click on the model selector
cy
.
get
(
'
button[aria-label="Select a model"]
'
).
click
();
cy
.
get
(
'
button[aria-label="Select a model"]
'
).
click
();
// Select the first model
// Select the first model
cy
.
get
(
'
div[role="option"][data-value
]
'
).
first
().
click
();
cy
.
get
(
'
button[aria-label="model-item"
]
'
).
first
().
click
();
// Type a message
// Type a message
cy
.
get
(
'
#chat-textarea
'
).
type
(
'
Hi, what can you do? A single sentence only please.
'
,
{
cy
.
get
(
'
#chat-textarea
'
).
type
(
'
Hi, what can you do? A single sentence only please.
'
,
{
force
:
true
force
:
true
...
...
src/lib/apis/chats/index.ts
View file @
e31cf081
import
{
WEBUI_API_BASE_URL
}
from
'
$lib/constants
'
;
import
{
WEBUI_API_BASE_URL
}
from
'
$lib/constants
'
;
import
{
getTimeRange
}
from
'
$lib/utils
'
;
export
const
createNewChat
=
async
(
token
:
string
,
chat
:
object
)
=>
{
export
const
createNewChat
=
async
(
token
:
string
,
chat
:
object
)
=>
{
let
error
=
null
;
let
error
=
null
;
...
@@ -59,7 +60,10 @@ export const getChatList = async (token: string = '') => {
...
@@ -59,7 +60,10 @@ export const getChatList = async (token: string = '') => {
throw
error
;
throw
error
;
}
}
return
res
;
return
res
.
map
((
chat
)
=>
({
...
chat
,
time_range
:
getTimeRange
(
chat
.
updated_at
)
}));
};
};
export
const
getChatListByUserId
=
async
(
token
:
string
=
''
,
userId
:
string
)
=>
{
export
const
getChatListByUserId
=
async
(
token
:
string
=
''
,
userId
:
string
)
=>
{
...
@@ -90,7 +94,10 @@ export const getChatListByUserId = async (token: string = '', userId: string) =>
...
@@ -90,7 +94,10 @@ export const getChatListByUserId = async (token: string = '', userId: string) =>
throw
error
;
throw
error
;
}
}
return
res
;
return
res
.
map
((
chat
)
=>
({
...
chat
,
time_range
:
getTimeRange
(
chat
.
updated_at
)
}));
};
};
export
const
getArchivedChatList
=
async
(
token
:
string
=
''
)
=>
{
export
const
getArchivedChatList
=
async
(
token
:
string
=
''
)
=>
{
...
@@ -220,13 +227,16 @@ export const getAllChatTags = async (token: string) => {
...
@@ -220,13 +227,16 @@ export const getAllChatTags = async (token: string) => {
export
const
getChatListByTagName
=
async
(
token
:
string
=
''
,
tagName
:
string
)
=>
{
export
const
getChatListByTagName
=
async
(
token
:
string
=
''
,
tagName
:
string
)
=>
{
let
error
=
null
;
let
error
=
null
;
const
res
=
await
fetch
(
`
${
WEBUI_API_BASE_URL
}
/chats/tags
/tag/
${
tagName
}
`
,
{
const
res
=
await
fetch
(
`
${
WEBUI_API_BASE_URL
}
/chats/tags`
,
{
method
:
'
GE
T
'
,
method
:
'
POS
T
'
,
headers
:
{
headers
:
{
Accept
:
'
application/json
'
,
Accept
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
...(
token
&&
{
authorization
:
`Bearer
${
token
}
`
})
...(
token
&&
{
authorization
:
`Bearer
${
token
}
`
})
}
},
body
:
JSON
.
stringify
({
name
:
tagName
})
})
})
.
then
(
async
(
res
)
=>
{
.
then
(
async
(
res
)
=>
{
if
(
!
res
.
ok
)
throw
await
res
.
json
();
if
(
!
res
.
ok
)
throw
await
res
.
json
();
...
@@ -245,7 +255,10 @@ export const getChatListByTagName = async (token: string = '', tagName: string)
...
@@ -245,7 +255,10 @@ export const getChatListByTagName = async (token: string = '', tagName: string)
throw
error
;
throw
error
;
}
}
return
res
;
return
res
.
map
((
chat
)
=>
({
...
chat
,
time_range
:
getTimeRange
(
chat
.
updated_at
)
}));
};
};
export
const
getChatById
=
async
(
token
:
string
,
id
:
string
)
=>
{
export
const
getChatById
=
async
(
token
:
string
,
id
:
string
)
=>
{
...
...
src/lib/components/chat/MessageInput.svelte
View file @
e31cf081
...
@@ -411,7 +411,9 @@
...
@@ -411,7 +411,9 @@
{#if dragged}
{#if dragged}
<div
<div
class="fixed lg:w-[calc(100%-260px)] w-full h-full flex z-50 touch-none pointer-events-none"
class="fixed {$showSidebar
? 'left-0 lg:left-[260px] lg:w-[calc(100%-260px)]'
: 'left-0'} w-full h-full flex z-50 touch-none pointer-events-none"
id="dropzone"
id="dropzone"
role="region"
role="region"
aria-label="Drag and Drop Container"
aria-label="Drag and Drop Container"
...
@@ -763,6 +765,7 @@
...
@@ -763,6 +765,7 @@
bind:value={prompt}
bind:value={prompt}
on:keypress={(e) => {
on:keypress={(e) => {
if (
if (
window.innerWidth > 1024 ||
!(
!(
'ontouchstart' in window ||
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.maxTouchPoints > 0 ||
...
...
src/lib/components/chat/ModelSelector/Selector.svelte
View file @
e31cf081
...
@@ -25,7 +25,9 @@
...
@@ -25,7 +25,9 @@
export let items = [{ value: 'mango', label: 'Mango' }];
export let items = [{ value: 'mango', label: 'Mango' }];
export let className = 'max-w-lg';
export let className = ' w-[32rem]';
let show = false;
let selectedModel = '';
let selectedModel = '';
$: selectedModel = items.find((item) => item.value === value) ?? '';
$: selectedModel = items.find((item) => item.value === value) ?? '';
...
@@ -181,6 +183,7 @@
...
@@ -181,6 +183,7 @@
</script>
</script>
<DropdownMenu.Root
<DropdownMenu.Root
bind:open={show}
onOpenChange={async () => {
onOpenChange={async () => {
searchValue = '';
searchValue = '';
window.setTimeout(() => document.getElementById('model-search-input')?.focus(), 0);
window.setTimeout(() => document.getElementById('model-search-input')?.focus(), 0);
...
@@ -199,7 +202,7 @@
...
@@ -199,7 +202,7 @@
</div>
</div>
</DropdownMenu.Trigger>
</DropdownMenu.Trigger>
<DropdownMenu.Content
<DropdownMenu.Content
class=" z-40
w-full
{className} justify-start 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 "
class=" z-40 {className}
max-w-[calc(100vw-1rem)]
justify-start 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}
transition={flyAndScale}
side={'bottom-start'}
side={'bottom-start'}
sideOffset={4}
sideOffset={4}
...
@@ -214,6 +217,7 @@
...
@@ -214,6 +217,7 @@
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={searchPlaceholder}
placeholder={searchPlaceholder}
autocomplete="off"
/>
/>
</div>
</div>
...
@@ -222,10 +226,13 @@
...
@@ -222,10 +226,13 @@
<div class="px-3 my-2 max-h-72 overflow-y-auto scrollbar-none">
<div class="px-3 my-2 max-h-72 overflow-y-auto scrollbar-none">
{#each filteredItems as item}
{#each filteredItems as item}
<DropdownMenu.Item
<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"
aria-label="model-item"
class="flex w-full text-left 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={() => {
on:click={() => {
value = item.value;
value = item.value;
show = false;
}}
}}
>
>
<div class="flex items-center gap-2">
<div class="flex items-center gap-2">
...
@@ -294,7 +301,7 @@
...
@@ -294,7 +301,7 @@
<Check />
<Check />
</div>
</div>
{/if}
{/if}
</
DropdownMenu.Item
>
</
button
>
{:else}
{:else}
<div>
<div>
<div class="block px-3 py-2 text-sm text-gray-700 dark:text-gray-100">
<div class="block px-3 py-2 text-sm text-gray-700 dark:text-gray-100">
...
@@ -392,6 +399,9 @@
...
@@ -392,6 +399,9 @@
</div>
</div>
{/each}
{/each}
</div>
</div>
<div class="hidden w-[42rem]" />
<div class="hidden w-[32rem]" />
</slot>
</slot>
</DropdownMenu.Content>
</DropdownMenu.Content>
</DropdownMenu.Root>
</DropdownMenu.Root>
...
...
src/lib/components/chat/ShortcutsModal.svelte
View file @
e31cf081
...
@@ -209,6 +209,58 @@
...
@@ -209,6 +209,58 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div class=" flex justify-between dark:text-gray-300 px-5">
<div class=" text-lg font-medium self-center">{$i18n.t('Input commands')}</div>
</div>
<div class="flex flex-col md:flex-row w-full p-5 md:space-x-4 dark:text-gray-200">
<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
<div class="flex flex-col space-y-3 w-full self-start">
<div class="w-full flex justify-between items-center">
<div class=" text-sm">
{$i18n.t('Attach file')}
</div>
<div class="flex space-x-1 text-xs">
<div
class=" h-fit py-1 px-2 flex items-center justify-center rounded border border-black/10 capitalize text-gray-600 dark:border-white/10 dark:text-gray-300"
>
#
</div>
</div>
</div>
<div class="w-full flex justify-between items-center">
<div class=" text-sm">
{$i18n.t('Add custom prompt')}
</div>
<div class="flex space-x-1 text-xs">
<div
class=" h-fit py-1 px-2 flex items-center justify-center rounded border border-black/10 capitalize text-gray-600 dark:border-white/10 dark:text-gray-300"
>
/
</div>
</div>
</div>
<div class="w-full flex justify-between items-center">
<div class=" text-sm">
{$i18n.t('Select model')}
</div>
<div class="flex space-x-1 text-xs">
<div
class=" h-fit py-1 px-2 flex items-center justify-center rounded border border-black/10 capitalize text-gray-600 dark:border-white/10 dark:text-gray-300"
>
@
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Modal>
</Modal>
...
...
src/lib/components/chat/Tags.svelte
View file @
e31cf081
...
@@ -3,11 +3,15 @@
...
@@ -3,11 +3,15 @@
addTagById,
addTagById,
deleteTagById,
deleteTagById,
getAllChatTags,
getAllChatTags,
getChatList,
getChatListByTagName,
getTagsById,
getTagsById,
updateChatById
updateChatById
} from '$lib/apis/chats';
} from '$lib/apis/chats';
import { tags as _tags } from '$lib/stores';
import { tags as _tags, chats } from '$lib/stores';
import { onMount } from 'svelte';
import { createEventDispatcher, onMount } from 'svelte';
const dispatch = createEventDispatcher();
import Tags from '../common/Tags.svelte';
import Tags from '../common/Tags.svelte';
...
@@ -39,7 +43,21 @@
...
@@ -39,7 +43,21 @@
tags: tags
tags: tags
});
});
_tags.set(await getAllChatTags(localStorage.token));
console.log($_tags);
await _tags.set(await getAllChatTags(localStorage.token));
console.log($_tags);
if ($_tags.map((t) => t.name).includes(tagName)) {
await chats.set(await getChatListByTagName(localStorage.token, tagName));
if ($chats.find((chat) => chat.id === chatId)) {
dispatch('close');
}
} else {
await chats.set(await getChatList(localStorage.token));
}
};
};
onMount(async () => {
onMount(async () => {
...
...
src/lib/components/common/ImagePreview.svelte
View file @
e31cf081
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
<button
<button
class=" p-5"
class=" p-5"
on:click={() => {
on:click={() => {
downloadImage(src,
'Image.png'
);
downloadImage(src,
src.substring(src.lastIndexOf('/') + 1)
);
}}
}}
>
>
<svg
<svg
...
...
src/lib/components/layout/Sidebar.svelte
View file @
e31cf081
...
@@ -44,6 +44,28 @@
...
@@ -44,6 +44,28 @@
let showDropdown = false;
let showDropdown = false;
let isEditing = false;
let isEditing = false;
let filteredChatList = [];
$: filteredChatList = $chats.filter((chat) => {
if (search === '') {
return true;
} else {
let title = chat.title.toLowerCase();
const query = search.toLowerCase();
let contentMatches = false;
// Access the messages within chat.chat.messages
if (chat.chat && chat.chat.messages && Array.isArray(chat.chat.messages)) {
contentMatches = chat.chat.messages.some((message) => {
// Check if message.content exists and includes the search query
return message.content && message.content.toLowerCase().includes(query);
});
}
return title.includes(query) || contentMatches;
}
});
onMount(async () => {
onMount(async () => {
showSidebar.set(window.innerWidth > BREAKPOINT);
showSidebar.set(window.innerWidth > BREAKPOINT);
await chats.set(await getChatList(localStorage.token));
await chats.set(await getChatList(localStorage.token));
...
@@ -418,25 +440,17 @@
...
@@ -418,25 +440,17 @@
{/if}
{/if}
<div class="pl-2 my-2 flex-1 flex flex-col space-y-1 overflow-y-auto scrollbar-none">
<div class="pl-2 my-2 flex-1 flex flex-col space-y-1 overflow-y-auto scrollbar-none">
{#each $chats.filter((chat) => {
{#each filteredChatList as chat, idx}
if (search === '') {
{#if idx === 0 || (idx > 0 && chat.time_range !== filteredChatList[idx - 1].time_range)}
return true;
<div
} else {
class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium {idx === 0
let title = chat.title.toLowerCase();
? ''
const query = search.toLowerCase();
: 'pt-5'} pb-0.5"
>
let contentMatches = false;
{chat.time_range}
// Access the messages within chat.chat.messages
</div>
if (chat.chat && chat.chat.messages && Array.isArray(chat.chat.messages)) {
{/if}
contentMatches = chat.chat.messages.some((message) => {
// Check if message.content exists and includes the search query
return message.content && message.content.toLowerCase().includes(query);
});
}
return title.includes(query) || contentMatches;
}
}) as chat, i}
<div class=" w-full pr-2 relative group">
<div class=" w-full pr-2 relative group">
{#if chatTitleEditId === chat.id}
{#if chatTitleEditId === chat.id}
<div
<div
...
@@ -836,12 +850,12 @@
...
@@ -836,12 +850,12 @@
>
>
<div class="flex h-6 w-6 flex-col items-center">
<div class="flex h-6 w-6 flex-col items-center">
<div
<div
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[0.15rem] {show
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[0.15rem] {
$
show
Sidebar
? 'group-hover:rotate-[15deg]'
? 'group-hover:rotate-[15deg]'
: 'group-hover:rotate-[-15deg]'}"
: 'group-hover:rotate-[-15deg]'}"
/>
/>
<div
<div
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[-0.15rem] {show
class="h-3 w-1 rounded-full bg-[#0f0f0f] dark:bg-white rotate-0 translate-y-[-0.15rem] {
$
show
Sidebar
? 'group-hover:rotate-[-15deg]'
? 'group-hover:rotate-[-15deg]'
: 'group-hover:rotate-[15deg]'}"
: 'group-hover:rotate-[15deg]'}"
/>
/>
...
...
src/lib/components/layout/Sidebar/ChatMenu.svelte
View file @
e31cf081
...
@@ -75,7 +75,13 @@
...
@@ -75,7 +75,13 @@
<hr class="border-gray-100 dark:border-gray-800 mt-2.5 mb-1.5" />
<hr class="border-gray-100 dark:border-gray-800 mt-2.5 mb-1.5" />
<div class="flex p-1">
<div class="flex p-1">
<Tags {chatId} />
<Tags
{chatId}
on:close={() => {
show = false;
onClose();
}}
/>
</div>
</div>
</DropdownMenu.Content>
</DropdownMenu.Content>
</div>
</div>
...
...
src/lib/i18n/locales/ar-BH/translation.json
0 → 100644
View file @
e31cf081
This diff is collapsed.
Click to expand it.
src/lib/i18n/locales/bg-BG/translation.json
View file @
e31cf081
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
"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 custom prompt"
:
""
,
"Add Docs"
:
"Добавяне на Документи"
,
"Add Docs"
:
"Добавяне на Документи"
,
"Add Files"
:
"Добавяне на Файлове"
,
"Add Files"
:
"Добавяне на Файлове"
,
"Add message"
:
"Добавяне на съобщение"
,
"Add message"
:
"Добавяне на съобщение"
,
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
"Archived Chats"
:
""
,
"Archived Chats"
:
""
,
"are allowed - Activate this command by typing"
:
"са разрешени - Активирайте тази команда чрез въвеждане"
,
"are allowed - Activate this command by typing"
:
"са разрешени - Активирайте тази команда чрез въвеждане"
,
"Are you sure?"
:
"Сигурни ли сте?"
,
"Are you sure?"
:
"Сигурни ли сте?"
,
"Attach file"
:
""
,
"Attention to detail"
:
""
,
"Attention to detail"
:
""
,
"Audio"
:
"Аудио"
,
"Audio"
:
"Аудио"
,
"Auto-playback response"
:
"Аувтоматично възпроизвеждане на Отговора"
,
"Auto-playback response"
:
"Аувтоматично възпроизвеждане на Отговора"
,
...
@@ -214,6 +216,7 @@
...
@@ -214,6 +216,7 @@
"Import Modelfiles"
:
"Импортване на модфайлове"
,
"Import Modelfiles"
:
"Импортване на модфайлове"
,
"Import Prompts"
:
"Импортване на промптове"
,
"Import Prompts"
:
"Импортване на промптове"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Включете флага `--api`, когато стартирате stable-diffusion-webui"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Включете флага `--api`, когато стартирате stable-diffusion-webui"
,
"Input commands"
:
""
,
"Interface"
:
"Интерфейс"
,
"Interface"
:
"Интерфейс"
,
"join our Discord for help."
:
"свържете се с нашия Discord за помощ."
,
"join our Discord for help."
:
"свържете се с нашия Discord за помощ."
,
"JSON"
:
"JSON"
,
"JSON"
:
"JSON"
,
...
@@ -350,6 +353,7 @@
...
@@ -350,6 +353,7 @@
"Select a mode"
:
"Изберете режим"
,
"Select a mode"
:
"Изберете режим"
,
"Select a model"
:
"Изберете модел"
,
"Select a model"
:
"Изберете модел"
,
"Select an Ollama instance"
:
"Изберете Ollama инстанция"
,
"Select an Ollama instance"
:
"Изберете Ollama инстанция"
,
"Select model"
:
""
,
"Send a Message"
:
"Изпращане на Съобщение"
,
"Send a Message"
:
"Изпращане на Съобщение"
,
"Send message"
:
"Изпращане на съобщение"
,
"Send message"
:
"Изпращане на съобщение"
,
"Server connection verified"
:
"Server connection verified"
,
"Server connection verified"
:
"Server connection verified"
,
...
...
src/lib/i18n/locales/bn-BD/translation.json
View file @
e31cf081
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
"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 custom prompt"
:
""
,
"Add Docs"
:
"ডকুমেন্ট যোগ করুন"
,
"Add Docs"
:
"ডকুমেন্ট যোগ করুন"
,
"Add Files"
:
"ফাইল যোগ করুন"
,
"Add Files"
:
"ফাইল যোগ করুন"
,
"Add message"
:
"মেসেজ যোগ করুন"
,
"Add message"
:
"মেসেজ যোগ করুন"
,
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
"Archived Chats"
:
"চ্যাট ইতিহাস সংরক্ষণাগার"
,
"Archived Chats"
:
"চ্যাট ইতিহাস সংরক্ষণাগার"
,
"are allowed - Activate this command by typing"
:
"অনুমোদিত - কমান্ডটি চালু করার জন্য লিখুন"
,
"are allowed - Activate this command by typing"
:
"অনুমোদিত - কমান্ডটি চালু করার জন্য লিখুন"
,
"Are you sure?"
:
"আপনি নিশ্চিত?"
,
"Are you sure?"
:
"আপনি নিশ্চিত?"
,
"Attach file"
:
""
,
"Attention to detail"
:
""
,
"Attention to detail"
:
""
,
"Audio"
:
"অডিও"
,
"Audio"
:
"অডিও"
,
"Auto-playback response"
:
"রেসপন্স অটো-প্লেব্যাক"
,
"Auto-playback response"
:
"রেসপন্স অটো-প্লেব্যাক"
,
...
@@ -214,6 +216,7 @@
...
@@ -214,6 +216,7 @@
"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` ফ্ল্যাগ সংযুক্ত করুন"
,
"Input commands"
:
""
,
"Interface"
:
"ইন্টারফেস"
,
"Interface"
:
"ইন্টারফেস"
,
"join our Discord for help."
:
"সাহায্যের জন্য আমাদের Discord-এ যুক্ত হোন"
,
"join our Discord for help."
:
"সাহায্যের জন্য আমাদের Discord-এ যুক্ত হোন"
,
"JSON"
:
"JSON"
,
"JSON"
:
"JSON"
,
...
@@ -351,6 +354,7 @@
...
@@ -351,6 +354,7 @@
"Select a mode"
:
"একটি মডেল নির্বাচন করুন"
,
"Select a mode"
:
"একটি মডেল নির্বাচন করুন"
,
"Select a model"
:
"একটি মডেল নির্বাচন করুন"
,
"Select a model"
:
"একটি মডেল নির্বাচন করুন"
,
"Select an Ollama instance"
:
"একটি Ollama ইন্সট্যান্স নির্বাচন করুন"
,
"Select an Ollama instance"
:
"একটি Ollama ইন্সট্যান্স নির্বাচন করুন"
,
"Select model"
:
""
,
"Send a Message"
:
"একটি মেসেজ পাঠান"
,
"Send a Message"
:
"একটি মেসেজ পাঠান"
,
"Send message"
:
"মেসেজ পাঠান"
,
"Send message"
:
"মেসেজ পাঠান"
,
"Server connection verified"
:
"সার্ভার কানেকশন যাচাই করা হয়েছে"
,
"Server connection verified"
:
"সার্ভার কানেকশন যাচাই করা হয়েছে"
,
...
...
src/lib/i18n/locales/ca-ES/translation.json
View file @
e31cf081
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
"Add a short description about what this modelfile does"
:
"Afegeix una descripció curta del que fa aquest arxiu de model"
,
"Add a short description about what this modelfile does"
:
"Afegeix una descripció curta del que fa aquest arxiu de model"
,
"Add a short title for this prompt"
:
"Afegeix un títol curt per aquest prompt"
,
"Add a short title for this prompt"
:
"Afegeix un títol curt per aquest prompt"
,
"Add a tag"
:
"Afegeix una etiqueta"
,
"Add a tag"
:
"Afegeix una etiqueta"
,
"Add custom prompt"
:
""
,
"Add Docs"
:
"Afegeix Documents"
,
"Add Docs"
:
"Afegeix Documents"
,
"Add Files"
:
"Afegeix Arxius"
,
"Add Files"
:
"Afegeix Arxius"
,
"Add message"
:
"Afegeix missatge"
,
"Add message"
:
"Afegeix missatge"
,
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
"Archived Chats"
:
"Arxiu d'historial de xat"
,
"Archived Chats"
:
"Arxiu d'historial de xat"
,
"are allowed - Activate this command by typing"
:
"estan permesos - Activa aquesta comanda escrivint"
,
"are allowed - Activate this command by typing"
:
"estan permesos - Activa aquesta comanda escrivint"
,
"Are you sure?"
:
"Estàs segur?"
,
"Are you sure?"
:
"Estàs segur?"
,
"Attach file"
:
""
,
"Attention to detail"
:
""
,
"Attention to detail"
:
""
,
"Audio"
:
"Àudio"
,
"Audio"
:
"Àudio"
,
"Auto-playback response"
:
"Resposta de reproducció automàtica"
,
"Auto-playback response"
:
"Resposta de reproducció automàtica"
,
...
@@ -214,6 +216,7 @@
...
@@ -214,6 +216,7 @@
"Import Modelfiles"
:
"Importa Fitxers de Model"
,
"Import Modelfiles"
:
"Importa Fitxers de Model"
,
"Import Prompts"
:
"Importa Prompts"
,
"Import Prompts"
:
"Importa Prompts"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Inclou la bandera `--api` quan executis stable-diffusion-webui"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Inclou la bandera `--api` quan executis stable-diffusion-webui"
,
"Input commands"
:
""
,
"Interface"
:
"Interfície"
,
"Interface"
:
"Interfície"
,
"join our Discord for help."
:
"uneix-te al nostre Discord per ajuda."
,
"join our Discord for help."
:
"uneix-te al nostre Discord per ajuda."
,
"JSON"
:
"JSON"
,
"JSON"
:
"JSON"
,
...
@@ -351,6 +354,7 @@
...
@@ -351,6 +354,7 @@
"Select a mode"
:
"Selecciona un mode"
,
"Select a mode"
:
"Selecciona un mode"
,
"Select a model"
:
"Selecciona un model"
,
"Select a model"
:
"Selecciona un model"
,
"Select an Ollama instance"
:
"Selecciona una instància d'Ollama"
,
"Select an Ollama instance"
:
"Selecciona una instància d'Ollama"
,
"Select model"
:
""
,
"Send a Message"
:
"Envia un Missatge"
,
"Send a Message"
:
"Envia un Missatge"
,
"Send message"
:
"Envia missatge"
,
"Send message"
:
"Envia missatge"
,
"Server connection verified"
:
"Connexió al servidor verificada"
,
"Server connection verified"
:
"Connexió al servidor verificada"
,
...
...
src/lib/i18n/locales/de-DE/translation.json
View file @
e31cf081
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
"Add a short description about what this modelfile does"
:
"Füge eine kurze Beschreibung hinzu, was dieses Modelfile kann"
,
"Add a short description about what this modelfile does"
:
"Füge eine kurze Beschreibung hinzu, was dieses Modelfile kann"
,
"Add a short title for this prompt"
:
"Füge einen kurzen Titel für diesen Prompt hinzu"
,
"Add a short title for this prompt"
:
"Füge einen kurzen Titel für diesen Prompt hinzu"
,
"Add a tag"
:
"Tag hinzufügen"
,
"Add a tag"
:
"Tag hinzufügen"
,
"Add custom prompt"
:
""
,
"Add Docs"
:
"Dokumente hinzufügen"
,
"Add Docs"
:
"Dokumente hinzufügen"
,
"Add Files"
:
"Dateien hinzufügen"
,
"Add Files"
:
"Dateien hinzufügen"
,
"Add message"
:
"Nachricht eingeben"
,
"Add message"
:
"Nachricht eingeben"
,
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
"Archived Chats"
:
"Archivierte Chats"
,
"Archived Chats"
:
"Archivierte Chats"
,
"are allowed - Activate this command by typing"
:
"sind erlaubt - Aktiviere diesen Befehl, indem du"
,
"are allowed - Activate this command by typing"
:
"sind erlaubt - Aktiviere diesen Befehl, indem du"
,
"Are you sure?"
:
"Bist du sicher?"
,
"Are you sure?"
:
"Bist du sicher?"
,
"Attach file"
:
""
,
"Attention to detail"
:
"Auge fürs Detail"
,
"Attention to detail"
:
"Auge fürs Detail"
,
"Audio"
:
"Audio"
,
"Audio"
:
"Audio"
,
"Auto-playback response"
:
"Automatische Wiedergabe der Antwort"
,
"Auto-playback response"
:
"Automatische Wiedergabe der Antwort"
,
...
@@ -214,6 +216,7 @@
...
@@ -214,6 +216,7 @@
"Import Modelfiles"
:
"Modelfiles importieren"
,
"Import Modelfiles"
:
"Modelfiles importieren"
,
"Import Prompts"
:
"Prompts importieren"
,
"Import Prompts"
:
"Prompts importieren"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Füge das `--api`-Flag hinzu, wenn Du stable-diffusion-webui nutzt"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Füge das `--api`-Flag hinzu, wenn Du stable-diffusion-webui nutzt"
,
"Input commands"
:
""
,
"Interface"
:
"Benutzeroberfläche"
,
"Interface"
:
"Benutzeroberfläche"
,
"join our Discord for help."
:
"Trete unserem Discord bei, um Hilfe zu erhalten."
,
"join our Discord for help."
:
"Trete unserem Discord bei, um Hilfe zu erhalten."
,
"JSON"
:
"JSON"
,
"JSON"
:
"JSON"
,
...
@@ -351,6 +354,7 @@
...
@@ -351,6 +354,7 @@
"Select a mode"
:
"Einen Modus auswählen"
,
"Select a mode"
:
"Einen Modus auswählen"
,
"Select a model"
:
"Ein Modell auswählen"
,
"Select a model"
:
"Ein Modell auswählen"
,
"Select an Ollama instance"
:
"Eine Ollama Instanz auswählen"
,
"Select an Ollama instance"
:
"Eine Ollama Instanz auswählen"
,
"Select model"
:
""
,
"Send a Message"
:
"Eine Nachricht senden"
,
"Send a Message"
:
"Eine Nachricht senden"
,
"Send message"
:
"Nachricht senden"
,
"Send message"
:
"Nachricht senden"
,
"Server connection verified"
:
"Serververbindung überprüft"
,
"Server connection verified"
:
"Serververbindung überprüft"
,
...
...
src/lib/i18n/locales/dg-DG/translation.json
View file @
e31cf081
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
"Add a short description about what this modelfile does"
:
"Add short description about what this modelfile does"
,
"Add a short description about what this modelfile does"
:
"Add short description about what this modelfile does"
,
"Add a short title for this prompt"
:
"Add short title for this prompt"
,
"Add a short title for this prompt"
:
"Add short title for this prompt"
,
"Add a tag"
:
"Add such tag"
,
"Add a tag"
:
"Add such tag"
,
"Add custom prompt"
:
""
,
"Add Docs"
:
"Add Docs"
,
"Add Docs"
:
"Add Docs"
,
"Add Files"
:
"Add Files"
,
"Add Files"
:
"Add Files"
,
"Add message"
:
"Add Prompt"
,
"Add message"
:
"Add Prompt"
,
...
@@ -44,6 +45,7 @@
...
@@ -44,6 +45,7 @@
"Archived Chats"
:
""
,
"Archived Chats"
:
""
,
"are allowed - Activate this command by typing"
:
"are allowed. Activate typing"
,
"are allowed - Activate this command by typing"
:
"are allowed. Activate typing"
,
"Are you sure?"
:
"Such certainty?"
,
"Are you sure?"
:
"Such certainty?"
,
"Attach file"
:
""
,
"Attention to detail"
:
""
,
"Attention to detail"
:
""
,
"Audio"
:
"Audio"
,
"Audio"
:
"Audio"
,
"Auto-playback response"
:
"Auto-playback response"
,
"Auto-playback response"
:
"Auto-playback response"
,
...
@@ -214,6 +216,7 @@
...
@@ -214,6 +216,7 @@
"Import Modelfiles"
:
"Import Modelfiles"
,
"Import Modelfiles"
:
"Import Modelfiles"
,
"Import Prompts"
:
"Import Promptos"
,
"Import Prompts"
:
"Import Promptos"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Include `--api` flag when running stable-diffusion-webui"
,
"Include `--api` flag when running stable-diffusion-webui"
:
"Include `--api` flag when running stable-diffusion-webui"
,
"Input commands"
:
""
,
"Interface"
:
"Interface"
,
"Interface"
:
"Interface"
,
"join our Discord for help."
:
"join our Discord for help."
,
"join our Discord for help."
:
"join our Discord for help."
,
"JSON"
:
"JSON"
,
"JSON"
:
"JSON"
,
...
@@ -351,6 +354,7 @@
...
@@ -351,6 +354,7 @@
"Select a mode"
:
"Select a mode very choose"
,
"Select a mode"
:
"Select a mode very choose"
,
"Select a model"
:
"Select a model much choice"
,
"Select a model"
:
"Select a model much choice"
,
"Select an Ollama instance"
:
"Select an Ollama instance very choose"
,
"Select an Ollama instance"
:
"Select an Ollama instance very choose"
,
"Select model"
:
""
,
"Send a Message"
:
"Send a Message much message"
,
"Send a Message"
:
"Send a Message much message"
,
"Send message"
:
"Send message very send"
,
"Send message"
:
"Send message very send"
,
"Server connection verified"
:
"Server connection verified much secure"
,
"Server connection verified"
:
"Server connection verified much secure"
,
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment