mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 20:35:19 +00:00
Merge remote-tracking branch 'upstream/dev' into feat/oauth
This commit is contained in:
commit
f26d80dcae
81 changed files with 4112 additions and 1214 deletions
|
|
@ -77,6 +77,7 @@ from apps.rag.search.serpstack import search_serpstack
|
|||
from apps.rag.search.serply import search_serply
|
||||
from apps.rag.search.duckduckgo import search_duckduckgo
|
||||
from apps.rag.search.tavily import search_tavily
|
||||
from apps.rag.search.jina_search import search_jina
|
||||
|
||||
from utils.misc import (
|
||||
calculate_sha256,
|
||||
|
|
@ -856,6 +857,8 @@ def search_web(engine: str, query: str) -> list[SearchResult]:
|
|||
)
|
||||
else:
|
||||
raise Exception("No TAVILY_API_KEY found in environment variables")
|
||||
elif engine == "jina":
|
||||
return search_jina(query, app.state.config.RAG_WEB_SEARCH_RESULT_COUNT)
|
||||
else:
|
||||
raise Exception("No search engine API key found in environment variables")
|
||||
|
||||
|
|
|
|||
41
backend/apps/rag/search/jina_search.py
Normal file
41
backend/apps/rag/search/jina_search.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import logging
|
||||
import requests
|
||||
from yarl import URL
|
||||
|
||||
from apps.rag.search.main import SearchResult
|
||||
from config import SRC_LOG_LEVELS
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["RAG"])
|
||||
|
||||
|
||||
def search_jina(query: str, count: int) -> list[SearchResult]:
|
||||
"""
|
||||
Search using Jina's Search API and return the results as a list of SearchResult objects.
|
||||
Args:
|
||||
query (str): The query to search for
|
||||
count (int): The number of results to return
|
||||
|
||||
Returns:
|
||||
List[SearchResult]: A list of search results
|
||||
"""
|
||||
jina_search_endpoint = "https://s.jina.ai/"
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
}
|
||||
url = str(URL(jina_search_endpoint + query))
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
results = []
|
||||
for result in data["data"][:count]:
|
||||
results.append(
|
||||
SearchResult(
|
||||
link=result["url"],
|
||||
title=result.get("title"),
|
||||
snippet=result.get("content"),
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
"""Peewee migrations -- 009_add_models.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("tool", valves=pw.TextField(null=True))
|
||||
migrator.add_fields("function", valves=pw.TextField(null=True))
|
||||
migrator.add_fields("function", is_active=pw.BooleanField(default=False))
|
||||
|
||||
|
||||
def rollback(migrator: Migrator, database: pw.Database, *, fake=False):
|
||||
"""Write your rollback migrations here."""
|
||||
|
||||
migrator.remove_fields("tool", "valves")
|
||||
migrator.remove_fields("function", "valves")
|
||||
migrator.remove_fields("function", "is_active")
|
||||
|
|
@ -105,13 +105,15 @@ async def get_status():
|
|||
|
||||
|
||||
async def get_pipe_models():
|
||||
pipes = Functions.get_functions_by_type("pipe")
|
||||
pipes = Functions.get_functions_by_type("pipe", active_only=True)
|
||||
pipe_models = []
|
||||
|
||||
for pipe in pipes:
|
||||
# Check if function is already loaded
|
||||
if pipe.id not in app.state.FUNCTIONS:
|
||||
function_module, function_type = load_function_module_by_id(pipe.id)
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(
|
||||
pipe.id
|
||||
)
|
||||
app.state.FUNCTIONS[pipe.id] = function_module
|
||||
else:
|
||||
function_module = app.state.FUNCTIONS[pipe.id]
|
||||
|
|
@ -132,7 +134,9 @@ async def get_pipe_models():
|
|||
manifold_pipe_name = p["name"]
|
||||
|
||||
if hasattr(function_module, "name"):
|
||||
manifold_pipe_name = f"{pipe.name}{manifold_pipe_name}"
|
||||
manifold_pipe_name = (
|
||||
f"{function_module.name}{manifold_pipe_name}"
|
||||
)
|
||||
|
||||
pipe_models.append(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,8 +5,11 @@ from typing import List, Union, Optional
|
|||
import time
|
||||
import logging
|
||||
from apps.webui.internal.db import DB, JSONField
|
||||
from apps.webui.models.users import Users
|
||||
|
||||
import json
|
||||
import copy
|
||||
|
||||
|
||||
from config import SRC_LOG_LEVELS
|
||||
|
||||
|
|
@ -25,6 +28,8 @@ class Function(Model):
|
|||
type = TextField()
|
||||
content = TextField()
|
||||
meta = JSONField()
|
||||
valves = JSONField()
|
||||
is_active = BooleanField(default=False)
|
||||
updated_at = BigIntegerField()
|
||||
created_at = BigIntegerField()
|
||||
|
||||
|
|
@ -34,6 +39,7 @@ class Function(Model):
|
|||
|
||||
class FunctionMeta(BaseModel):
|
||||
description: Optional[str] = None
|
||||
manifest: Optional[dict] = {}
|
||||
|
||||
|
||||
class FunctionModel(BaseModel):
|
||||
|
|
@ -43,6 +49,7 @@ class FunctionModel(BaseModel):
|
|||
type: str
|
||||
content: str
|
||||
meta: FunctionMeta
|
||||
is_active: bool = False
|
||||
updated_at: int # timestamp in epoch
|
||||
created_at: int # timestamp in epoch
|
||||
|
||||
|
|
@ -58,6 +65,7 @@ class FunctionResponse(BaseModel):
|
|||
type: str
|
||||
name: str
|
||||
meta: FunctionMeta
|
||||
is_active: bool
|
||||
updated_at: int # timestamp in epoch
|
||||
created_at: int # timestamp in epoch
|
||||
|
||||
|
|
@ -69,6 +77,10 @@ class FunctionForm(BaseModel):
|
|||
meta: FunctionMeta
|
||||
|
||||
|
||||
class FunctionValves(BaseModel):
|
||||
valves: Optional[dict] = None
|
||||
|
||||
|
||||
class FunctionsTable:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
|
|
@ -104,16 +116,98 @@ class FunctionsTable:
|
|||
except:
|
||||
return None
|
||||
|
||||
def get_functions(self) -> List[FunctionModel]:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function)) for function in Function.select()
|
||||
]
|
||||
def get_functions(self, active_only=False) -> List[FunctionModel]:
|
||||
if active_only:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function))
|
||||
for function in Function.select().where(Function.is_active == True)
|
||||
]
|
||||
else:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function))
|
||||
for function in Function.select()
|
||||
]
|
||||
|
||||
def get_functions_by_type(self, type: str) -> List[FunctionModel]:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function))
|
||||
for function in Function.select().where(Function.type == type)
|
||||
]
|
||||
def get_functions_by_type(
|
||||
self, type: str, active_only=False
|
||||
) -> List[FunctionModel]:
|
||||
if active_only:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function))
|
||||
for function in Function.select().where(
|
||||
Function.type == type, Function.is_active == True
|
||||
)
|
||||
]
|
||||
else:
|
||||
return [
|
||||
FunctionModel(**model_to_dict(function))
|
||||
for function in Function.select().where(Function.type == type)
|
||||
]
|
||||
|
||||
def get_function_valves_by_id(self, id: str) -> Optional[dict]:
|
||||
try:
|
||||
function = Function.get(Function.id == id)
|
||||
return function.valves if function.valves else {}
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_function_valves_by_id(
|
||||
self, id: str, valves: dict
|
||||
) -> Optional[FunctionValves]:
|
||||
try:
|
||||
query = Function.update(
|
||||
**{"valves": valves},
|
||||
updated_at=int(time.time()),
|
||||
).where(Function.id == id)
|
||||
query.execute()
|
||||
|
||||
function = Function.get(Function.id == id)
|
||||
return FunctionValves(**model_to_dict(function))
|
||||
except:
|
||||
return None
|
||||
|
||||
def get_user_valves_by_id_and_user_id(
|
||||
self, id: str, user_id: str
|
||||
) -> Optional[dict]:
|
||||
try:
|
||||
user = Users.get_user_by_id(user_id)
|
||||
user_settings = user.settings.model_dump()
|
||||
|
||||
# Check if user has "functions" and "valves" settings
|
||||
if "functions" not in user_settings:
|
||||
user_settings["functions"] = {}
|
||||
if "valves" not in user_settings["functions"]:
|
||||
user_settings["functions"]["valves"] = {}
|
||||
|
||||
return user_settings["functions"]["valves"].get(id, {})
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_user_valves_by_id_and_user_id(
|
||||
self, id: str, user_id: str, valves: dict
|
||||
) -> Optional[dict]:
|
||||
try:
|
||||
user = Users.get_user_by_id(user_id)
|
||||
user_settings = user.settings.model_dump()
|
||||
|
||||
# Check if user has "functions" and "valves" settings
|
||||
if "functions" not in user_settings:
|
||||
user_settings["functions"] = {}
|
||||
if "valves" not in user_settings["functions"]:
|
||||
user_settings["functions"]["valves"] = {}
|
||||
|
||||
user_settings["functions"]["valves"][id] = valves
|
||||
|
||||
# Update the user settings in the database
|
||||
query = Users.update_user_by_id(user_id, {"settings": user_settings})
|
||||
query.execute()
|
||||
|
||||
return user_settings["functions"]["valves"][id]
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_function_by_id(self, id: str, updated: dict) -> Optional[FunctionModel]:
|
||||
try:
|
||||
|
|
@ -128,6 +222,19 @@ class FunctionsTable:
|
|||
except:
|
||||
return None
|
||||
|
||||
def deactivate_all_functions(self) -> Optional[bool]:
|
||||
try:
|
||||
query = Function.update(
|
||||
**{"is_active": False},
|
||||
updated_at=int(time.time()),
|
||||
)
|
||||
|
||||
query.execute()
|
||||
|
||||
return True
|
||||
except:
|
||||
return None
|
||||
|
||||
def delete_function_by_id(self, id: str) -> bool:
|
||||
try:
|
||||
query = Function.delete().where((Function.id == id))
|
||||
|
|
|
|||
|
|
@ -5,8 +5,11 @@ from typing import List, Union, Optional
|
|||
import time
|
||||
import logging
|
||||
from apps.webui.internal.db import DB, JSONField
|
||||
from apps.webui.models.users import Users
|
||||
|
||||
import json
|
||||
import copy
|
||||
|
||||
|
||||
from config import SRC_LOG_LEVELS
|
||||
|
||||
|
|
@ -25,6 +28,7 @@ class Tool(Model):
|
|||
content = TextField()
|
||||
specs = JSONField()
|
||||
meta = JSONField()
|
||||
valves = JSONField()
|
||||
updated_at = BigIntegerField()
|
||||
created_at = BigIntegerField()
|
||||
|
||||
|
|
@ -34,6 +38,7 @@ class Tool(Model):
|
|||
|
||||
class ToolMeta(BaseModel):
|
||||
description: Optional[str] = None
|
||||
manifest: Optional[dict] = {}
|
||||
|
||||
|
||||
class ToolModel(BaseModel):
|
||||
|
|
@ -68,6 +73,10 @@ class ToolForm(BaseModel):
|
|||
meta: ToolMeta
|
||||
|
||||
|
||||
class ToolValves(BaseModel):
|
||||
valves: Optional[dict] = None
|
||||
|
||||
|
||||
class ToolsTable:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
|
|
@ -106,6 +115,69 @@ class ToolsTable:
|
|||
def get_tools(self) -> List[ToolModel]:
|
||||
return [ToolModel(**model_to_dict(tool)) for tool in Tool.select()]
|
||||
|
||||
def get_tool_valves_by_id(self, id: str) -> Optional[dict]:
|
||||
try:
|
||||
tool = Tool.get(Tool.id == id)
|
||||
return tool.valves if tool.valves else {}
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_tool_valves_by_id(self, id: str, valves: dict) -> Optional[ToolValves]:
|
||||
try:
|
||||
query = Tool.update(
|
||||
**{"valves": valves},
|
||||
updated_at=int(time.time()),
|
||||
).where(Tool.id == id)
|
||||
query.execute()
|
||||
|
||||
tool = Tool.get(Tool.id == id)
|
||||
return ToolValves(**model_to_dict(tool))
|
||||
except:
|
||||
return None
|
||||
|
||||
def get_user_valves_by_id_and_user_id(
|
||||
self, id: str, user_id: str
|
||||
) -> Optional[dict]:
|
||||
try:
|
||||
user = Users.get_user_by_id(user_id)
|
||||
user_settings = user.settings.model_dump()
|
||||
|
||||
# Check if user has "tools" and "valves" settings
|
||||
if "tools" not in user_settings:
|
||||
user_settings["tools"] = {}
|
||||
if "valves" not in user_settings["tools"]:
|
||||
user_settings["tools"]["valves"] = {}
|
||||
|
||||
return user_settings["tools"]["valves"].get(id, {})
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_user_valves_by_id_and_user_id(
|
||||
self, id: str, user_id: str, valves: dict
|
||||
) -> Optional[dict]:
|
||||
try:
|
||||
user = Users.get_user_by_id(user_id)
|
||||
user_settings = user.settings.model_dump()
|
||||
|
||||
# Check if user has "tools" and "valves" settings
|
||||
if "tools" not in user_settings:
|
||||
user_settings["tools"] = {}
|
||||
if "valves" not in user_settings["tools"]:
|
||||
user_settings["tools"]["valves"] = {}
|
||||
|
||||
user_settings["tools"]["valves"][id] = valves
|
||||
|
||||
# Update the user settings in the database
|
||||
query = Users.update_user_by_id(user_id, {"settings": user_settings})
|
||||
query.execute()
|
||||
|
||||
return user_settings["tools"]["valves"][id]
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return None
|
||||
|
||||
def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]:
|
||||
try:
|
||||
query = Tool.update(
|
||||
|
|
|
|||
|
|
@ -194,6 +194,29 @@ async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
|
|||
)
|
||||
|
||||
|
||||
@router.get("/{id}/content/{file_name}", response_model=Optional[FileModel])
|
||||
async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
|
||||
file = Files.get_file_by_id(id)
|
||||
|
||||
if file:
|
||||
file_path = Path(file.meta["path"])
|
||||
|
||||
# Check if the file already exists in the cache
|
||||
if file_path.is_file():
|
||||
print(f"file_path: {file_path}")
|
||||
return FileResponse(file_path)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# Delete File By Id
|
||||
############################
|
||||
|
|
|
|||
|
|
@ -69,7 +69,10 @@ async def create_new_function(
|
|||
with open(function_path, "w") as function_file:
|
||||
function_file.write(form_data.content)
|
||||
|
||||
function_module, function_type = load_function_module_by_id(form_data.id)
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(
|
||||
form_data.id
|
||||
)
|
||||
form_data.meta.manifest = frontmatter
|
||||
|
||||
FUNCTIONS = request.app.state.FUNCTIONS
|
||||
FUNCTIONS[form_data.id] = function_module
|
||||
|
|
@ -117,13 +120,40 @@ async def get_function_by_id(id: str, user=Depends(get_admin_user)):
|
|||
)
|
||||
|
||||
|
||||
############################
|
||||
# ToggleFunctionById
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/toggle", response_model=Optional[FunctionModel])
|
||||
async def toggle_function_by_id(id: str, user=Depends(get_admin_user)):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
function = Functions.update_function_by_id(
|
||||
id, {"is_active": not function.is_active}
|
||||
)
|
||||
|
||||
if function:
|
||||
return function
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# UpdateFunctionById
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/update", response_model=Optional[FunctionModel])
|
||||
async def update_toolkit_by_id(
|
||||
async def update_function_by_id(
|
||||
request: Request, id: str, form_data: FunctionForm, user=Depends(get_admin_user)
|
||||
):
|
||||
function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
|
||||
|
|
@ -132,7 +162,8 @@ async def update_toolkit_by_id(
|
|||
with open(function_path, "w") as function_file:
|
||||
function_file.write(form_data.content)
|
||||
|
||||
function_module, function_type = load_function_module_by_id(id)
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||
form_data.meta.manifest = frontmatter
|
||||
|
||||
FUNCTIONS = request.app.state.FUNCTIONS
|
||||
FUNCTIONS[id] = function_module
|
||||
|
|
@ -178,3 +209,188 @@ async def delete_function_by_id(
|
|||
os.remove(function_path)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
############################
|
||||
# GetFunctionValves
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves", response_model=Optional[dict])
|
||||
async def get_function_valves_by_id(id: str, user=Depends(get_admin_user)):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
try:
|
||||
valves = Functions.get_function_valves_by_id(id)
|
||||
return valves
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# GetFunctionValvesSpec
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
|
||||
async def get_function_valves_spec_by_id(
|
||||
request: Request, id: str, user=Depends(get_admin_user)
|
||||
):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
if id in request.app.state.FUNCTIONS:
|
||||
function_module = request.app.state.FUNCTIONS[id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||
request.app.state.FUNCTIONS[id] = function_module
|
||||
|
||||
if hasattr(function_module, "Valves"):
|
||||
Valves = function_module.Valves
|
||||
return Valves.schema()
|
||||
return None
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# UpdateFunctionValves
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
||||
async def update_function_valves_by_id(
|
||||
request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
|
||||
):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
|
||||
if id in request.app.state.FUNCTIONS:
|
||||
function_module = request.app.state.FUNCTIONS[id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||
request.app.state.FUNCTIONS[id] = function_module
|
||||
|
||||
if hasattr(function_module, "Valves"):
|
||||
Valves = function_module.Valves
|
||||
|
||||
try:
|
||||
form_data = {k: v for k, v in form_data.items() if v is not None}
|
||||
valves = Valves(**form_data)
|
||||
Functions.update_function_valves_by_id(id, valves.model_dump())
|
||||
return valves.model_dump()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# FunctionUserValves
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/user", response_model=Optional[dict])
|
||||
async def get_function_user_valves_by_id(id: str, user=Depends(get_verified_user)):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
try:
|
||||
user_valves = Functions.get_user_valves_by_id_and_user_id(id, user.id)
|
||||
return user_valves
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict])
|
||||
async def get_function_user_valves_spec_by_id(
|
||||
request: Request, id: str, user=Depends(get_verified_user)
|
||||
):
|
||||
function = Functions.get_function_by_id(id)
|
||||
if function:
|
||||
if id in request.app.state.FUNCTIONS:
|
||||
function_module = request.app.state.FUNCTIONS[id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||
request.app.state.FUNCTIONS[id] = function_module
|
||||
|
||||
if hasattr(function_module, "UserValves"):
|
||||
UserValves = function_module.UserValves
|
||||
return UserValves.schema()
|
||||
return None
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/id/{id}/valves/user/update", response_model=Optional[dict])
|
||||
async def update_function_user_valves_by_id(
|
||||
request: Request, id: str, form_data: dict, user=Depends(get_verified_user)
|
||||
):
|
||||
function = Functions.get_function_by_id(id)
|
||||
|
||||
if function:
|
||||
if id in request.app.state.FUNCTIONS:
|
||||
function_module = request.app.state.FUNCTIONS[id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||
request.app.state.FUNCTIONS[id] = function_module
|
||||
|
||||
if hasattr(function_module, "UserValves"):
|
||||
UserValves = function_module.UserValves
|
||||
|
||||
try:
|
||||
form_data = {k: v for k, v in form_data.items() if v is not None}
|
||||
user_valves = UserValves(**form_data)
|
||||
Functions.update_user_valves_by_id_and_user_id(
|
||||
id, user.id, user_valves.model_dump()
|
||||
)
|
||||
return user_valves.model_dump()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ from fastapi import APIRouter
|
|||
from pydantic import BaseModel
|
||||
import json
|
||||
|
||||
|
||||
from apps.webui.models.users import Users
|
||||
from apps.webui.models.tools import Tools, ToolForm, ToolModel, ToolResponse
|
||||
from apps.webui.utils import load_toolkit_module_by_id
|
||||
|
||||
from utils.utils import get_current_user, get_admin_user
|
||||
from utils.utils import get_admin_user, get_verified_user
|
||||
from utils.tools import get_tools_specs
|
||||
from constants import ERROR_MESSAGES
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ router = APIRouter()
|
|||
|
||||
|
||||
@router.get("/", response_model=List[ToolResponse])
|
||||
async def get_toolkits(user=Depends(get_current_user)):
|
||||
async def get_toolkits(user=Depends(get_verified_user)):
|
||||
toolkits = [toolkit for toolkit in Tools.get_tools()]
|
||||
return toolkits
|
||||
|
||||
|
|
@ -72,7 +74,8 @@ async def create_new_toolkit(
|
|||
with open(toolkit_path, "w") as tool_file:
|
||||
tool_file.write(form_data.content)
|
||||
|
||||
toolkit_module = load_toolkit_module_by_id(form_data.id)
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(form_data.id)
|
||||
form_data.meta.manifest = frontmatter
|
||||
|
||||
TOOLS = request.app.state.TOOLS
|
||||
TOOLS[form_data.id] = toolkit_module
|
||||
|
|
@ -136,7 +139,8 @@ async def update_toolkit_by_id(
|
|||
with open(toolkit_path, "w") as tool_file:
|
||||
tool_file.write(form_data.content)
|
||||
|
||||
toolkit_module = load_toolkit_module_by_id(id)
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||
form_data.meta.manifest = frontmatter
|
||||
|
||||
TOOLS = request.app.state.TOOLS
|
||||
TOOLS[id] = toolkit_module
|
||||
|
|
@ -185,3 +189,187 @@ async def delete_toolkit_by_id(request: Request, id: str, user=Depends(get_admin
|
|||
os.remove(toolkit_path)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
############################
|
||||
# GetToolValves
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves", response_model=Optional[dict])
|
||||
async def get_toolkit_valves_by_id(id: str, user=Depends(get_admin_user)):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
if toolkit:
|
||||
try:
|
||||
valves = Tools.get_tool_valves_by_id(id)
|
||||
return valves
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# GetToolValvesSpec
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/spec", response_model=Optional[dict])
|
||||
async def get_toolkit_valves_spec_by_id(
|
||||
request: Request, id: str, user=Depends(get_admin_user)
|
||||
):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
if toolkit:
|
||||
if id in request.app.state.TOOLS:
|
||||
toolkit_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = toolkit_module
|
||||
|
||||
if hasattr(toolkit_module, "Valves"):
|
||||
Valves = toolkit_module.Valves
|
||||
return Valves.schema()
|
||||
return None
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# UpdateToolValves
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/valves/update", response_model=Optional[dict])
|
||||
async def update_toolkit_valves_by_id(
|
||||
request: Request, id: str, form_data: dict, user=Depends(get_admin_user)
|
||||
):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
if toolkit:
|
||||
if id in request.app.state.TOOLS:
|
||||
toolkit_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = toolkit_module
|
||||
|
||||
if hasattr(toolkit_module, "Valves"):
|
||||
Valves = toolkit_module.Valves
|
||||
|
||||
try:
|
||||
form_data = {k: v for k, v in form_data.items() if v is not None}
|
||||
valves = Valves(**form_data)
|
||||
Tools.update_tool_valves_by_id(id, valves.model_dump())
|
||||
return valves.model_dump()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# ToolUserValves
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/user", response_model=Optional[dict])
|
||||
async def get_toolkit_user_valves_by_id(id: str, user=Depends(get_verified_user)):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
if toolkit:
|
||||
try:
|
||||
user_valves = Tools.get_user_valves_by_id_and_user_id(id, user.id)
|
||||
return user_valves
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict])
|
||||
async def get_toolkit_user_valves_spec_by_id(
|
||||
request: Request, id: str, user=Depends(get_verified_user)
|
||||
):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
if toolkit:
|
||||
if id in request.app.state.TOOLS:
|
||||
toolkit_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = toolkit_module
|
||||
|
||||
if hasattr(toolkit_module, "UserValves"):
|
||||
UserValves = toolkit_module.UserValves
|
||||
return UserValves.schema()
|
||||
return None
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/id/{id}/valves/user/update", response_model=Optional[dict])
|
||||
async def update_toolkit_user_valves_by_id(
|
||||
request: Request, id: str, form_data: dict, user=Depends(get_verified_user)
|
||||
):
|
||||
toolkit = Tools.get_tool_by_id(id)
|
||||
|
||||
if toolkit:
|
||||
if id in request.app.state.TOOLS:
|
||||
toolkit_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = toolkit_module
|
||||
|
||||
if hasattr(toolkit_module, "UserValves"):
|
||||
UserValves = toolkit_module.UserValves
|
||||
|
||||
try:
|
||||
form_data = {k: v for k, v in form_data.items() if v is not None}
|
||||
user_valves = UserValves(**form_data)
|
||||
Tools.update_user_valves_by_id_and_user_id(
|
||||
id, user.id, user_valves.model_dump()
|
||||
)
|
||||
return user_valves.model_dump()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,56 @@
|
|||
from importlib import util
|
||||
import os
|
||||
import re
|
||||
|
||||
from config import TOOLS_DIR, FUNCTIONS_DIR
|
||||
|
||||
|
||||
def extract_frontmatter(file_path):
|
||||
"""
|
||||
Extract frontmatter as a dictionary from the specified file path.
|
||||
"""
|
||||
frontmatter = {}
|
||||
frontmatter_started = False
|
||||
frontmatter_ended = False
|
||||
frontmatter_pattern = re.compile(r"^\s*([a-z_]+):\s*(.*)\s*$", re.IGNORECASE)
|
||||
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
if '"""' in line:
|
||||
if not frontmatter_started:
|
||||
frontmatter_started = True
|
||||
continue # skip the line with the opening triple quotes
|
||||
else:
|
||||
frontmatter_ended = True
|
||||
break
|
||||
|
||||
if frontmatter_started and not frontmatter_ended:
|
||||
match = frontmatter_pattern.match(line)
|
||||
if match:
|
||||
key, value = match.groups()
|
||||
frontmatter[key.strip()] = value.strip()
|
||||
except FileNotFoundError:
|
||||
print(f"Error: The file {file_path} does not exist.")
|
||||
return {}
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return {}
|
||||
|
||||
return frontmatter
|
||||
|
||||
|
||||
def load_toolkit_module_by_id(toolkit_id):
|
||||
toolkit_path = os.path.join(TOOLS_DIR, f"{toolkit_id}.py")
|
||||
spec = util.spec_from_file_location(toolkit_id, toolkit_path)
|
||||
module = util.module_from_spec(spec)
|
||||
frontmatter = extract_frontmatter(toolkit_path)
|
||||
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
print(f"Loaded module: {module.__name__}")
|
||||
if hasattr(module, "Tools"):
|
||||
return module.Tools()
|
||||
return module.Tools(), frontmatter
|
||||
else:
|
||||
raise Exception("No Tools class found")
|
||||
except Exception as e:
|
||||
|
|
@ -28,14 +65,15 @@ def load_function_module_by_id(function_id):
|
|||
|
||||
spec = util.spec_from_file_location(function_id, function_path)
|
||||
module = util.module_from_spec(spec)
|
||||
frontmatter = extract_frontmatter(function_path)
|
||||
|
||||
try:
|
||||
spec.loader.exec_module(module)
|
||||
print(f"Loaded module: {module.__name__}")
|
||||
if hasattr(module, "Pipe"):
|
||||
return module.Pipe(), "pipe"
|
||||
return module.Pipe(), "pipe", frontmatter
|
||||
elif hasattr(module, "Filter"):
|
||||
return module.Filter(), "filter"
|
||||
return module.Filter(), "filter", frontmatter
|
||||
else:
|
||||
raise Exception("No Function class found")
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -167,6 +167,12 @@ for version in soup.find_all("h2"):
|
|||
CHANGELOG = changelog_json
|
||||
|
||||
|
||||
####################################
|
||||
# SAFE_MODE
|
||||
####################################
|
||||
|
||||
SAFE_MODE = os.environ.get("SAFE_MODE", "false").lower() == "true"
|
||||
|
||||
####################################
|
||||
# WEBUI_BUILD_HASH
|
||||
####################################
|
||||
|
|
|
|||
370
backend/main.py
370
backend/main.py
|
|
@ -62,9 +62,7 @@ from apps.webui.models.functions import Functions
|
|||
from apps.webui.models.users import Users
|
||||
|
||||
from apps.webui.utils import load_toolkit_module_by_id, load_function_module_by_id
|
||||
from apps.webui.utils import load_toolkit_module_by_id
|
||||
|
||||
from utils.misc import parse_duration
|
||||
from utils.utils import (
|
||||
get_admin_user,
|
||||
get_verified_user,
|
||||
|
|
@ -82,6 +80,7 @@ from utils.misc import (
|
|||
get_last_user_message,
|
||||
add_or_update_system_message,
|
||||
stream_message_template,
|
||||
parse_duration,
|
||||
)
|
||||
|
||||
from apps.rag.utils import get_rag_context, rag_template
|
||||
|
|
@ -113,6 +112,7 @@ from config import (
|
|||
SEARCH_QUERY_GENERATION_PROMPT_TEMPLATE,
|
||||
SEARCH_QUERY_PROMPT_LENGTH_THRESHOLD,
|
||||
TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
|
||||
SAFE_MODE,
|
||||
OAUTH_PROVIDERS,
|
||||
ENABLE_OAUTH_SIGNUP,
|
||||
OAUTH_MERGE_ACCOUNTS_BY_EMAIL,
|
||||
|
|
@ -124,6 +124,11 @@ from config import (
|
|||
from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
|
||||
from utils.webhook import post_webhook
|
||||
|
||||
if SAFE_MODE:
|
||||
print("SAFE MODE ENABLED")
|
||||
Functions.deactivate_all_functions()
|
||||
|
||||
|
||||
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["MAIN"])
|
||||
|
|
@ -271,7 +276,7 @@ async def get_function_call_response(
|
|||
if tool_id in webui_app.state.TOOLS:
|
||||
toolkit_module = webui_app.state.TOOLS[tool_id]
|
||||
else:
|
||||
toolkit_module = load_toolkit_module_by_id(tool_id)
|
||||
toolkit_module, frontmatter = load_toolkit_module_by_id(tool_id)
|
||||
webui_app.state.TOOLS[tool_id] = toolkit_module
|
||||
|
||||
file_handler = False
|
||||
|
|
@ -280,6 +285,14 @@ async def get_function_call_response(
|
|||
file_handler = True
|
||||
print("file_handler: ", file_handler)
|
||||
|
||||
if hasattr(toolkit_module, "valves") and hasattr(
|
||||
toolkit_module, "Valves"
|
||||
):
|
||||
valves = Tools.get_tool_valves_by_id(tool_id)
|
||||
toolkit_module.valves = toolkit_module.Valves(
|
||||
**(valves if valves else {})
|
||||
)
|
||||
|
||||
function = getattr(toolkit_module, result["name"])
|
||||
function_result = None
|
||||
try:
|
||||
|
|
@ -289,16 +302,24 @@ async def get_function_call_response(
|
|||
|
||||
if "__user__" in sig.parameters:
|
||||
# Call the function with the '__user__' parameter included
|
||||
params = {
|
||||
**params,
|
||||
"__user__": {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
},
|
||||
__user__ = {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
}
|
||||
|
||||
try:
|
||||
if hasattr(toolkit_module, "UserValves"):
|
||||
__user__["valves"] = toolkit_module.UserValves(
|
||||
**Tools.get_user_valves_by_id_and_user_id(
|
||||
tool_id, user.id
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
params = {**params, "__user__": __user__}
|
||||
if "__messages__" in sig.parameters:
|
||||
# Call the function with the '__messages__' parameter included
|
||||
params = {
|
||||
|
|
@ -386,54 +407,94 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
|
|||
)
|
||||
model = app.state.MODELS[model_id]
|
||||
|
||||
def get_priority(function_id):
|
||||
function = Functions.get_function_by_id(function_id)
|
||||
if function is not None and hasattr(function, "valves"):
|
||||
return (function.valves if function.valves else {}).get(
|
||||
"priority", 0
|
||||
)
|
||||
return 0
|
||||
|
||||
filter_ids = [
|
||||
function.id
|
||||
for function in Functions.get_functions_by_type(
|
||||
"filter", active_only=True
|
||||
)
|
||||
]
|
||||
# Check if the model has any filters
|
||||
if "info" in model and "meta" in model["info"]:
|
||||
for filter_id in model["info"]["meta"].get("filterIds", []):
|
||||
filter = Functions.get_function_by_id(filter_id)
|
||||
if filter:
|
||||
if filter_id in webui_app.state.FUNCTIONS:
|
||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||
else:
|
||||
function_module, function_type = load_function_module_by_id(
|
||||
filter_id
|
||||
)
|
||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||
filter_ids.extend(model["info"]["meta"].get("filterIds", []))
|
||||
filter_ids = list(set(filter_ids))
|
||||
|
||||
# Check if the function has a file_handler variable
|
||||
if hasattr(function_module, "file_handler"):
|
||||
skip_files = function_module.file_handler
|
||||
filter_ids.sort(key=get_priority)
|
||||
for filter_id in filter_ids:
|
||||
filter = Functions.get_function_by_id(filter_id)
|
||||
if filter:
|
||||
if filter_id in webui_app.state.FUNCTIONS:
|
||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = (
|
||||
load_function_module_by_id(filter_id)
|
||||
)
|
||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "inlet"):
|
||||
inlet = function_module.inlet
|
||||
# Check if the function has a file_handler variable
|
||||
if hasattr(function_module, "file_handler"):
|
||||
skip_files = function_module.file_handler
|
||||
|
||||
if inspect.iscoroutinefunction(inlet):
|
||||
data = await inlet(
|
||||
data,
|
||||
{
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
},
|
||||
)
|
||||
else:
|
||||
data = inlet(
|
||||
data,
|
||||
{
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
},
|
||||
)
|
||||
if hasattr(function_module, "valves") and hasattr(
|
||||
function_module, "Valves"
|
||||
):
|
||||
valves = Functions.get_function_valves_by_id(filter_id)
|
||||
function_module.valves = function_module.Valves(
|
||||
**(valves if valves else {})
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
content={"detail": str(e)},
|
||||
)
|
||||
try:
|
||||
if hasattr(function_module, "inlet"):
|
||||
inlet = function_module.inlet
|
||||
|
||||
# Get the signature of the function
|
||||
sig = inspect.signature(inlet)
|
||||
params = {"body": data}
|
||||
|
||||
if "__user__" in sig.parameters:
|
||||
__user__ = {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
}
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "UserValves"):
|
||||
__user__["valves"] = function_module.UserValves(
|
||||
**Functions.get_user_valves_by_id_and_user_id(
|
||||
filter_id, user.id
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
params = {**params, "__user__": __user__}
|
||||
|
||||
if "__id__" in sig.parameters:
|
||||
params = {
|
||||
**params,
|
||||
"__id__": filter_id,
|
||||
}
|
||||
|
||||
if inspect.iscoroutinefunction(inlet):
|
||||
data = await inlet(**params)
|
||||
else:
|
||||
data = inlet(**params)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
content={"detail": str(e)},
|
||||
)
|
||||
|
||||
# Set the task model
|
||||
task_model_id = data["model"]
|
||||
|
|
@ -857,12 +918,6 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
|
|||
|
||||
pipe = model.get("pipe")
|
||||
if pipe:
|
||||
form_data["user"] = {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
}
|
||||
|
||||
async def job():
|
||||
pipe_id = form_data["model"]
|
||||
|
|
@ -870,14 +925,62 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
|
|||
pipe_id, sub_pipe_id = pipe_id.split(".", 1)
|
||||
print(pipe_id)
|
||||
|
||||
pipe = webui_app.state.FUNCTIONS[pipe_id].pipe
|
||||
# Check if function is already loaded
|
||||
if pipe_id not in webui_app.state.FUNCTIONS:
|
||||
function_module, function_type, frontmatter = (
|
||||
load_function_module_by_id(pipe_id)
|
||||
)
|
||||
webui_app.state.FUNCTIONS[pipe_id] = function_module
|
||||
else:
|
||||
function_module = webui_app.state.FUNCTIONS[pipe_id]
|
||||
|
||||
if hasattr(function_module, "valves") and hasattr(
|
||||
function_module, "Valves"
|
||||
):
|
||||
|
||||
valves = Functions.get_function_valves_by_id(pipe_id)
|
||||
function_module.valves = function_module.Valves(
|
||||
**(valves if valves else {})
|
||||
)
|
||||
|
||||
pipe = function_module.pipe
|
||||
|
||||
# Get the signature of the function
|
||||
sig = inspect.signature(pipe)
|
||||
params = {"body": form_data}
|
||||
|
||||
if "__user__" in sig.parameters:
|
||||
__user__ = {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
}
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "UserValves"):
|
||||
__user__["valves"] = function_module.UserValves(
|
||||
**Functions.get_user_valves_by_id_and_user_id(
|
||||
pipe_id, user.id
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
params = {**params, "__user__": __user__}
|
||||
|
||||
if form_data["stream"]:
|
||||
|
||||
async def stream_content():
|
||||
if inspect.iscoroutinefunction(pipe):
|
||||
res = await pipe(body=form_data)
|
||||
else:
|
||||
res = pipe(body=form_data)
|
||||
try:
|
||||
if inspect.iscoroutinefunction(pipe):
|
||||
res = await pipe(**params)
|
||||
else:
|
||||
res = pipe(**params)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
yield f"data: {json.dumps({'error': {'detail':str(e)}})}\n\n"
|
||||
return
|
||||
|
||||
if isinstance(res, str):
|
||||
message = stream_message_template(form_data["model"], res)
|
||||
|
|
@ -922,10 +1025,20 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
|
|||
stream_content(), media_type="text/event-stream"
|
||||
)
|
||||
else:
|
||||
|
||||
try:
|
||||
if inspect.iscoroutinefunction(pipe):
|
||||
res = await pipe(**params)
|
||||
else:
|
||||
res = pipe(**params)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return {"error": {"detail": str(e)}}
|
||||
|
||||
if inspect.iscoroutinefunction(pipe):
|
||||
res = await pipe(body=form_data)
|
||||
res = await pipe(**params)
|
||||
else:
|
||||
res = pipe(body=form_data)
|
||||
res = pipe(**params)
|
||||
|
||||
if isinstance(res, dict):
|
||||
return res
|
||||
|
|
@ -1008,7 +1121,12 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
|
|||
f"{url}/{filter['id']}/filter/outlet",
|
||||
headers=headers,
|
||||
json={
|
||||
"user": {"id": user.id, "name": user.name, "role": user.role},
|
||||
"user": {
|
||||
"id": user.id,
|
||||
"name": user.name,
|
||||
"email": user.email,
|
||||
"role": user.role,
|
||||
},
|
||||
"body": data,
|
||||
},
|
||||
)
|
||||
|
|
@ -1033,49 +1151,88 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
|
|||
else:
|
||||
pass
|
||||
|
||||
def get_priority(function_id):
|
||||
function = Functions.get_function_by_id(function_id)
|
||||
if function is not None and hasattr(function, "valves"):
|
||||
return (function.valves if function.valves else {}).get("priority", 0)
|
||||
return 0
|
||||
|
||||
filter_ids = [
|
||||
function.id
|
||||
for function in Functions.get_functions_by_type("filter", active_only=True)
|
||||
]
|
||||
# Check if the model has any filters
|
||||
if "info" in model and "meta" in model["info"]:
|
||||
for filter_id in model["info"]["meta"].get("filterIds", []):
|
||||
filter = Functions.get_function_by_id(filter_id)
|
||||
if filter:
|
||||
if filter_id in webui_app.state.FUNCTIONS:
|
||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||
else:
|
||||
function_module, function_type = load_function_module_by_id(
|
||||
filter_id
|
||||
)
|
||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||
filter_ids.extend(model["info"]["meta"].get("filterIds", []))
|
||||
filter_ids = list(set(filter_ids))
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "outlet"):
|
||||
outlet = function_module.outlet
|
||||
if inspect.iscoroutinefunction(outlet):
|
||||
data = await outlet(
|
||||
data,
|
||||
{
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
},
|
||||
)
|
||||
else:
|
||||
data = outlet(
|
||||
data,
|
||||
{
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
},
|
||||
)
|
||||
# Sort filter_ids by priority, using the get_priority function
|
||||
filter_ids.sort(key=get_priority)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
content={"detail": str(e)},
|
||||
)
|
||||
for filter_id in filter_ids:
|
||||
filter = Functions.get_function_by_id(filter_id)
|
||||
if filter:
|
||||
if filter_id in webui_app.state.FUNCTIONS:
|
||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||
else:
|
||||
function_module, function_type, frontmatter = (
|
||||
load_function_module_by_id(filter_id)
|
||||
)
|
||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||
|
||||
if hasattr(function_module, "valves") and hasattr(
|
||||
function_module, "Valves"
|
||||
):
|
||||
valves = Functions.get_function_valves_by_id(filter_id)
|
||||
function_module.valves = function_module.Valves(
|
||||
**(valves if valves else {})
|
||||
)
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "outlet"):
|
||||
outlet = function_module.outlet
|
||||
|
||||
# Get the signature of the function
|
||||
sig = inspect.signature(outlet)
|
||||
params = {"body": data}
|
||||
|
||||
if "__user__" in sig.parameters:
|
||||
__user__ = {
|
||||
"id": user.id,
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"role": user.role,
|
||||
}
|
||||
|
||||
try:
|
||||
if hasattr(function_module, "UserValves"):
|
||||
__user__["valves"] = function_module.UserValves(
|
||||
**Functions.get_user_valves_by_id_and_user_id(
|
||||
filter_id, user.id
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
params = {**params, "__user__": __user__}
|
||||
|
||||
if "__id__" in sig.parameters:
|
||||
params = {
|
||||
**params,
|
||||
"__id__": filter_id,
|
||||
}
|
||||
|
||||
if inspect.iscoroutinefunction(outlet):
|
||||
data = await outlet(**params)
|
||||
else:
|
||||
data = outlet(**params)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
content={"detail": str(e)},
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
|
@ -1989,7 +2146,6 @@ async def get_manifest_json():
|
|||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#343541",
|
||||
"theme_color": "#343541",
|
||||
"orientation": "portrait-primary",
|
||||
"icons": [{"src": "/static/logo.png", "type": "image/png", "sizes": "500x500"}],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ peewee-migrate==1.12.2
|
|||
psycopg2-binary==2.9.9
|
||||
PyMySQL==1.1.1
|
||||
bcrypt==4.1.3
|
||||
|
||||
SQLAlchemy
|
||||
pymongo
|
||||
redis
|
||||
boto3==1.34.110
|
||||
|
||||
argon2-cffi==23.1.0
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ def get_tools_specs(tools) -> List[dict]:
|
|||
function_list = [
|
||||
{"name": func, "function": getattr(tools, func)}
|
||||
for func in dir(tools)
|
||||
if callable(getattr(tools, func)) and not func.startswith("__")
|
||||
if callable(getattr(tools, func))
|
||||
and not func.startswith("__")
|
||||
and not inspect.isclass(getattr(tools, func))
|
||||
]
|
||||
|
||||
specs = []
|
||||
|
|
@ -65,6 +67,7 @@ def get_tools_specs(tools) -> List[dict]:
|
|||
function
|
||||
).parameters.items()
|
||||
if param.default is param.empty
|
||||
and not (name.startswith("__") and name.endswith("__"))
|
||||
],
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ math {
|
|||
@apply underline;
|
||||
}
|
||||
|
||||
iframe {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
|
||||
ol > li {
|
||||
counter-increment: list-number;
|
||||
display: block;
|
||||
|
|
|
|||
|
|
@ -191,3 +191,233 @@ export const deleteFunctionById = async (token: string, id: string) => {
|
|||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const toggleFunctionById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/toggle`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getFunctionValvesById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getFunctionValvesSpecById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/spec`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateFunctionValvesById = async (token: string, id: string, valves: object) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...valves
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getUserValvesById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getUserValvesSpecById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/spec`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateUserValvesById = async (token: string, id: string, valves: object) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...valves
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -191,3 +191,201 @@ export const deleteToolById = async (token: string, id: string) => {
|
|||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getToolValvesById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getToolValvesSpecById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/spec`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateToolValvesById = async (token: string, id: string, valves: object) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...valves
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getUserValvesById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getUserValvesSpecById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/spec`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateUserValvesById = async (token: string, id: string, valves: object) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/update`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...valves
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
|
||||
console.log(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
'serper',
|
||||
'serply',
|
||||
'duckduckgo',
|
||||
'tavily'
|
||||
'tavily',
|
||||
'jina'
|
||||
];
|
||||
|
||||
let youtubeLanguage = 'en';
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<script>
|
||||
import { getContext } from 'svelte';
|
||||
import Modal from '../common/Modal.svelte';
|
||||
import Database from './Settings/Database.svelte';
|
||||
|
||||
import General from './Settings/General.svelte';
|
||||
import Users from './Settings/Users.svelte';
|
||||
|
||||
import Banners from '$lib/components/admin/Settings/Banners.svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import Pipelines from './Settings/Pipelines.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let show = false;
|
||||
|
||||
let selectedTab = 'general';
|
||||
</script>
|
||||
|
||||
<Modal bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Admin Settings')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
|
@ -127,6 +127,42 @@
|
|||
}
|
||||
|
||||
onMount(async () => {
|
||||
const onMessageHandler = async (event) => {
|
||||
if (event.origin === window.origin) {
|
||||
// Replace with your iframe's origin
|
||||
console.log('Message received from iframe:', event.data);
|
||||
if (event.data.type === 'input:prompt') {
|
||||
console.log(event.data.text);
|
||||
|
||||
const inputElement = document.getElementById('chat-textarea');
|
||||
|
||||
if (inputElement) {
|
||||
prompt = event.data.text;
|
||||
inputElement.focus();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.data.type === 'action:submit') {
|
||||
console.log(event.data.text);
|
||||
|
||||
if (prompt !== '') {
|
||||
await tick();
|
||||
submitPrompt(prompt);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.data.type === 'input:prompt:submit') {
|
||||
console.log(event.data.text);
|
||||
|
||||
if (prompt !== '') {
|
||||
await tick();
|
||||
submitPrompt(event.data.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', onMessageHandler);
|
||||
|
||||
if (!$chatId) {
|
||||
chatId.subscribe(async (value) => {
|
||||
if (!value) {
|
||||
|
|
@ -138,6 +174,10 @@
|
|||
await goto('/');
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('message', onMessageHandler);
|
||||
};
|
||||
});
|
||||
|
||||
//////////////////////////
|
||||
|
|
@ -600,10 +640,14 @@
|
|||
files = model.info.meta.knowledge;
|
||||
}
|
||||
const lastUserMessage = messages.filter((message) => message.role === 'user').at(-1);
|
||||
|
||||
files = [
|
||||
...files,
|
||||
...(lastUserMessage?.files?.filter((item) =>
|
||||
['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
|
||||
) ?? []),
|
||||
...(responseMessage?.files?.filter((item) =>
|
||||
['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
|
||||
) ?? [])
|
||||
].filter(
|
||||
// Remove duplicates
|
||||
|
|
@ -844,6 +888,9 @@
|
|||
...files,
|
||||
...(lastUserMessage?.files?.filter((item) =>
|
||||
['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
|
||||
) ?? []),
|
||||
...(responseMessage?.files?.filter((item) =>
|
||||
['doc', 'file', 'collection', 'web_search_results'].includes(item.type)
|
||||
) ?? [])
|
||||
].filter(
|
||||
// Remove duplicates
|
||||
|
|
@ -1213,6 +1260,7 @@
|
|||
|
||||
const getWebSearchResults = async (model: string, parentId: string, responseId: string) => {
|
||||
const responseMessage = history.messages[responseId];
|
||||
const userMessage = history.messages[parentId];
|
||||
|
||||
responseMessage.statusHistory = [
|
||||
{
|
||||
|
|
@ -1223,7 +1271,7 @@
|
|||
];
|
||||
messages = messages;
|
||||
|
||||
const prompt = history.messages[parentId].content;
|
||||
const prompt = userMessage.content;
|
||||
let searchQuery = await generateSearchQuery(localStorage.token, model, messages, prompt).catch(
|
||||
(error) => {
|
||||
console.log(error);
|
||||
|
|
|
|||
|
|
@ -321,9 +321,11 @@
|
|||
<div class="flex flex-col max-w-6xl px-2.5 md:px-6 w-full">
|
||||
<div class="relative">
|
||||
{#if autoScroll === false && messages.length > 0}
|
||||
<div class=" absolute -top-12 left-0 right-0 flex justify-center z-30">
|
||||
<div
|
||||
class=" absolute -top-12 left-0 right-0 flex justify-center z-30 pointer-events-none"
|
||||
>
|
||||
<button
|
||||
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
|
||||
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full pointer-events-auto"
|
||||
on:click={() => {
|
||||
autoScroll = true;
|
||||
scrollToBottom();
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if (assistantSpeaking) {
|
||||
if (assistantSpeaking && !($settings?.voiceInterruption ?? false)) {
|
||||
// Mute the audio if the assistant is speaking
|
||||
analyser.maxDecibels = 0;
|
||||
analyser.minDecibels = -1;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
</script>
|
||||
|
||||
{#key mounted}
|
||||
<div class="m-auto w-full max-w-6xl px-8 lg:px-24 pb-10">
|
||||
<div class="m-auto w-full max-w-6xl px-8 lg:px-20 pb-10">
|
||||
<div class="flex justify-start">
|
||||
<div class="flex -space-x-4 mb-1" in:fade={{ duration: 200 }}>
|
||||
{#each models as model, modelIdx}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
let chatDirection: 'LTR' | 'RTL' = 'LTR';
|
||||
|
||||
let showEmojiInCall = false;
|
||||
let voiceInterruption = false;
|
||||
|
||||
const toggleSplitLargeChunks = async () => {
|
||||
splitLargeChunks = !splitLargeChunks;
|
||||
|
|
@ -58,6 +59,11 @@
|
|||
saveSettings({ showEmojiInCall: showEmojiInCall });
|
||||
};
|
||||
|
||||
const toggleVoiceInterruption = async () => {
|
||||
voiceInterruption = !voiceInterruption;
|
||||
saveSettings({ voiceInterruption: voiceInterruption });
|
||||
};
|
||||
|
||||
const toggleUserLocation = async () => {
|
||||
userLocation = !userLocation;
|
||||
|
||||
|
|
@ -128,6 +134,7 @@
|
|||
showUsername = $settings.showUsername ?? false;
|
||||
|
||||
showEmojiInCall = $settings.showEmojiInCall ?? false;
|
||||
voiceInterruption = $settings.voiceInterruption ?? false;
|
||||
|
||||
chatBubble = $settings.chatBubble ?? true;
|
||||
widescreenMode = $settings.widescreenMode ?? false;
|
||||
|
|
@ -399,6 +406,26 @@
|
|||
|
||||
<div class=" my-1.5 text-sm font-medium">{$i18n.t('Voice')}</div>
|
||||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs">{$i18n.t('Allow Voice Interruption in Call')}</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
on:click={() => {
|
||||
toggleVoiceInterruption();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
{#if voiceInterruption === true}
|
||||
<span class="ml-2 self-center">{$i18n.t('On')}</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs">{$i18n.t('Display Emoji in Call')}</div>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
dispatch('save');
|
||||
}}
|
||||
>
|
||||
<div class=" pr-1.5 overflow-y-scroll max-h-[25rem]">
|
||||
<div class=" pr-1.5 py-1 overflow-y-scroll max-h-[25rem]">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<Tooltip
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<div class="mt-1">
|
||||
<div class="">
|
||||
<Switch
|
||||
bind:state={enableMemory}
|
||||
on:change={async () => {
|
||||
|
|
|
|||
245
src/lib/components/chat/Settings/Valves.svelte
Normal file
245
src/lib/components/chat/Settings/Valves.svelte
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
import { config, functions, models, settings, tools, user } from '$lib/stores';
|
||||
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
|
||||
|
||||
import {
|
||||
getUserValvesSpecById as getToolUserValvesSpecById,
|
||||
getUserValvesById as getToolUserValvesById,
|
||||
updateUserValvesById as updateToolUserValvesById
|
||||
} from '$lib/apis/tools';
|
||||
import {
|
||||
getUserValvesSpecById as getFunctionUserValvesSpecById,
|
||||
getUserValvesById as getFunctionUserValvesById,
|
||||
updateUserValvesById as updateFunctionUserValvesById
|
||||
} from '$lib/apis/functions';
|
||||
|
||||
import ManageModal from './Personalization/ManageModal.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let saveSettings: Function;
|
||||
|
||||
let tab = 'tools';
|
||||
let selectedId = '';
|
||||
|
||||
let loading = false;
|
||||
|
||||
let valvesSpec = null;
|
||||
let valves = {};
|
||||
|
||||
const getUserValves = async () => {
|
||||
loading = true;
|
||||
if (tab === 'tools') {
|
||||
valves = await getToolUserValvesById(localStorage.token, selectedId);
|
||||
valvesSpec = await getToolUserValvesSpecById(localStorage.token, selectedId);
|
||||
} else if (tab === 'functions') {
|
||||
valves = await getFunctionUserValvesById(localStorage.token, selectedId);
|
||||
valvesSpec = await getFunctionUserValvesSpecById(localStorage.token, selectedId);
|
||||
}
|
||||
|
||||
if (valvesSpec) {
|
||||
// Convert array to string
|
||||
for (const property in valvesSpec.properties) {
|
||||
if (valvesSpec.properties[property]?.type === 'array') {
|
||||
valves[property] = (valves[property] ?? []).join(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loading = false;
|
||||
};
|
||||
|
||||
const submitHandler = async () => {
|
||||
if (valvesSpec) {
|
||||
// Convert string to array
|
||||
for (const property in valvesSpec.properties) {
|
||||
if (valvesSpec.properties[property]?.type === 'array') {
|
||||
valves[property] = (valves[property] ?? '').split(',').map((v) => v.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (tab === 'tools') {
|
||||
const res = await updateToolUserValvesById(localStorage.token, selectedId, valves).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
if (res) {
|
||||
toast.success('Valves updated');
|
||||
valves = res;
|
||||
}
|
||||
} else if (tab === 'functions') {
|
||||
const res = await updateFunctionUserValvesById(
|
||||
localStorage.token,
|
||||
selectedId,
|
||||
valves
|
||||
).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Valves updated');
|
||||
valves = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$: if (tab) {
|
||||
selectedId = '';
|
||||
}
|
||||
|
||||
$: if (selectedId) {
|
||||
getUserValves();
|
||||
}
|
||||
</script>
|
||||
|
||||
<form
|
||||
class="flex flex-col h-full justify-between space-y-3 text-sm"
|
||||
on:submit|preventDefault={() => {
|
||||
submitHandler();
|
||||
dispatch('save');
|
||||
}}
|
||||
>
|
||||
<div class="flex flex-col pr-1.5 overflow-y-scroll max-h-[25rem]">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<Tooltip content="">
|
||||
<div class="text-sm font-medium">
|
||||
{$i18n.t('Manage Valves')}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<div class=" self-end">
|
||||
<select
|
||||
class=" dark:bg-gray-900 w-fit pr-8 rounded text-xs bg-transparent outline-none text-right"
|
||||
bind:value={tab}
|
||||
placeholder="Select"
|
||||
>
|
||||
<option value="tools">{$i18n.t('Tools')}</option>
|
||||
<option value="functions">{$i18n.t('Functions')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<div class="flex gap-2">
|
||||
<div class="flex-1">
|
||||
<select
|
||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
bind:value={selectedId}
|
||||
on:change={async () => {
|
||||
await tick();
|
||||
}}
|
||||
>
|
||||
{#if tab === 'tools'}
|
||||
<option value="" selected disabled class="bg-gray-100 dark:bg-gray-700"
|
||||
>{$i18n.t('Select a tool')}</option
|
||||
>
|
||||
|
||||
{#each $tools as tool, toolIdx}
|
||||
<option value={tool.id} class="bg-gray-100 dark:bg-gray-700">{tool.name}</option>
|
||||
{/each}
|
||||
{:else if tab === 'functions'}
|
||||
<option value="" selected disabled class="bg-gray-100 dark:bg-gray-700"
|
||||
>{$i18n.t('Select a function')}</option
|
||||
>
|
||||
|
||||
{#each $functions as func, funcIdx}
|
||||
<option value={func.id} class="bg-gray-100 dark:bg-700">{func.name}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if selectedId}
|
||||
<hr class="dark:border-gray-800 my-3 w-full" />
|
||||
|
||||
<div>
|
||||
{#if !loading}
|
||||
{#if valvesSpec}
|
||||
{#each Object.keys(valvesSpec.properties) as property, idx}
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{valvesSpec.properties[property].title}
|
||||
|
||||
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||
<span class=" text-gray-500">*required</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
valves[property] = (valves[property] ?? null) === null ? '' : null;
|
||||
}}
|
||||
>
|
||||
{#if (valves[property] ?? null) === null}
|
||||
<span class="ml-2 self-center">
|
||||
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||
{$i18n.t('None')}
|
||||
{:else}
|
||||
{$i18n.t('Default')}
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if (valves[property] ?? null) !== null}
|
||||
<div class="flex mt-0.5 mb-1.5 space-x-2">
|
||||
<div class=" flex-1">
|
||||
<input
|
||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
type="text"
|
||||
placeholder={valvesSpec.properties[property].title}
|
||||
bind:value={valves[property]}
|
||||
autocomplete="off"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if (valvesSpec.properties[property]?.description ?? null) !== null}
|
||||
<div class="text-xs text-gray-500">
|
||||
{valvesSpec.properties[property].description}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<div>No valves</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<Spinner className="size-5" />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end text-sm font-medium">
|
||||
<button
|
||||
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
|
||||
type="submit"
|
||||
>
|
||||
{$i18n.t('Save')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
import Personalization from './Settings/Personalization.svelte';
|
||||
import { updateUserSettings } from '$lib/apis/users';
|
||||
import { goto } from '$app/navigation';
|
||||
import Valves from './Settings/Valves.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
|
@ -65,8 +66,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'general'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'general';
|
||||
}}
|
||||
|
|
@ -91,8 +92,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'interface'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'interface';
|
||||
}}
|
||||
|
|
@ -117,8 +118,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'personalization'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'personalization';
|
||||
}}
|
||||
|
|
@ -132,8 +133,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'audio'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'audio';
|
||||
}}
|
||||
|
|
@ -156,11 +157,35 @@
|
|||
<div class=" self-center">{$i18n.t('Audio')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'valves'
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'valves';
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="size-4"
|
||||
>
|
||||
<path
|
||||
d="M18.75 12.75h1.5a.75.75 0 0 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM12 6a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 6ZM12 18a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 12 18ZM3.75 6.75h1.5a.75.75 0 1 0 0-1.5h-1.5a.75.75 0 0 0 0 1.5ZM5.25 18.75h-1.5a.75.75 0 0 1 0-1.5h1.5a.75.75 0 0 1 0 1.5ZM3 12a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 3 12ZM9 3.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5ZM12.75 12a2.25 2.25 0 1 1 4.5 0 2.25 2.25 0 0 1-4.5 0ZM9 15.75a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class=" self-center">{$i18n.t('Valves')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'chats'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'chats';
|
||||
}}
|
||||
|
|
@ -185,8 +210,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'account'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'account';
|
||||
}}
|
||||
|
|
@ -212,8 +237,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'admin'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={async () => {
|
||||
await goto('/admin/settings');
|
||||
show = false;
|
||||
|
|
@ -240,8 +265,8 @@
|
|||
<button
|
||||
class="px-2.5 py-2.5 min-w-fit rounded-lg flex-1 md:flex-none flex text-right transition {selectedTab ===
|
||||
'about'
|
||||
? 'bg-gray-200 dark:bg-gray-700'
|
||||
: ' hover:bg-gray-300 dark:hover:bg-gray-800'}"
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ' hover:bg-gray-100 dark:hover:bg-gray-850'}"
|
||||
on:click={() => {
|
||||
selectedTab = 'about';
|
||||
}}
|
||||
|
|
@ -293,6 +318,13 @@
|
|||
toast.success($i18n.t('Settings saved successfully!'));
|
||||
}}
|
||||
/>
|
||||
{:else if selectedTab === 'valves'}
|
||||
<Valves
|
||||
{saveSettings}
|
||||
on:save={() => {
|
||||
toast.success($i18n.t('Settings saved successfully!'));
|
||||
}}
|
||||
/>
|
||||
{:else if selectedTab === 'chats'}
|
||||
<Chats {saveSettings} />
|
||||
{:else if selectedTab === 'account'}
|
||||
|
|
|
|||
19
src/lib/components/icons/Heart.svelte
Normal file
19
src/lib/components/icons/Heart.svelte
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts">
|
||||
export let className = 'size-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="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z"
|
||||
/>
|
||||
</svg>
|
||||
|
|
@ -538,7 +538,9 @@
|
|||
documentsImportInputElement.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Documents Mapping')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">
|
||||
{$i18n.t('Import Documents Mapping')}
|
||||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -565,7 +567,9 @@
|
|||
saveAs(blob, `documents-mapping-export-${Date.now()}.json`);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Documents Mapping')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">
|
||||
{$i18n.t('Export Documents Mapping')}
|
||||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
|
|||
|
|
@ -13,13 +13,20 @@
|
|||
deleteFunctionById,
|
||||
exportFunctions,
|
||||
getFunctionById,
|
||||
getFunctions
|
||||
getFunctions,
|
||||
toggleFunctionById
|
||||
} from '$lib/apis/functions';
|
||||
|
||||
import ArrowDownTray from '../icons/ArrowDownTray.svelte';
|
||||
import Tooltip from '../common/Tooltip.svelte';
|
||||
import ConfirmDialog from '../common/ConfirmDialog.svelte';
|
||||
import { getModels } from '$lib/apis';
|
||||
import FunctionMenu from './Functions/FunctionMenu.svelte';
|
||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||
import Switch from '../common/Switch.svelte';
|
||||
import ValvesModal from './common/ValvesModal.svelte';
|
||||
import ManifestModal from './common/ManifestModal.svelte';
|
||||
import Heart from '../icons/Heart.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
|
@ -28,6 +35,58 @@
|
|||
|
||||
let showConfirm = false;
|
||||
let query = '';
|
||||
|
||||
let showManifestModal = false;
|
||||
let showValvesModal = false;
|
||||
let selectedFunction = null;
|
||||
|
||||
const shareHandler = async (tool) => {
|
||||
console.log(tool);
|
||||
};
|
||||
|
||||
const cloneHandler = async (func) => {
|
||||
const _function = await getFunctionById(localStorage.token, func.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_function) {
|
||||
sessionStorage.function = JSON.stringify({
|
||||
..._function,
|
||||
id: `${_function.id}_clone`,
|
||||
name: `${_function.name} (Clone)`
|
||||
});
|
||||
goto('/workspace/functions/create');
|
||||
}
|
||||
};
|
||||
|
||||
const exportHandler = async (func) => {
|
||||
const _function = await getFunctionById(localStorage.token, func.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_function) {
|
||||
let blob = new Blob([JSON.stringify([_function])], {
|
||||
type: 'application/json'
|
||||
});
|
||||
saveAs(blob, `function-${_function.id}-export-${Date.now()}.json`);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteHandler = async (func) => {
|
||||
const res = await deleteFunctionById(localStorage.token, func.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Function deleted successfully');
|
||||
|
||||
functions.set(await getFunctions(localStorage.token));
|
||||
models.set(await getModels(localStorage.token));
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -87,18 +146,14 @@
|
|||
{#each $functions.filter((f) => query === '' || f.name
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase()) || f.id.toLowerCase().includes(query.toLowerCase())) as func}
|
||||
<button
|
||||
<div
|
||||
class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
goto(`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`);
|
||||
}}
|
||||
>
|
||||
<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
|
||||
<a
|
||||
href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
|
||||
class="flex items-center text-left"
|
||||
>
|
||||
<a
|
||||
class=" flex flex-1 space-x-3.5 cursor-pointer w-full"
|
||||
href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
|
||||
>
|
||||
<div class="flex items-center text-left">
|
||||
<div class=" flex-1 self-center pl-1">
|
||||
<div class=" font-semibold flex items-center gap-1.5">
|
||||
<div
|
||||
|
|
@ -107,150 +162,113 @@
|
|||
{func.type}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{#if func?.meta?.manifest?.version}
|
||||
<div
|
||||
class="text-xs font-black px-1 rounded line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
v{func?.meta?.manifest?.version ?? ''}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class=" line-clamp-1">
|
||||
{func.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1.5 px-1">
|
||||
<div class=" text-gray-500 text-xs font-medium">{func.id}</div>
|
||||
<div class=" text-gray-500 text-xs font-medium flex-shrink-0">{func.id}</div>
|
||||
|
||||
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
|
||||
{func.meta.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex flex-row gap-0.5 self-center">
|
||||
{#if func?.meta?.manifest?.funding_url ?? false}
|
||||
<Tooltip content="Support">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedFunction = func;
|
||||
showManifestModal = true;
|
||||
}}
|
||||
>
|
||||
<Heart />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
<Tooltip content="Valves">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedFunction = func;
|
||||
showValvesModal = true;
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<FunctionMenu
|
||||
editHandler={() => {
|
||||
goto(`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`);
|
||||
}}
|
||||
shareHandler={() => {
|
||||
shareHandler(func);
|
||||
}}
|
||||
cloneHandler={() => {
|
||||
cloneHandler(func);
|
||||
}}
|
||||
exportHandler={() => {
|
||||
exportHandler(func);
|
||||
}}
|
||||
deleteHandler={async () => {
|
||||
deleteHandler(func);
|
||||
}}
|
||||
onClose={() => {}}
|
||||
>
|
||||
<button
|
||||
class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
>
|
||||
<EllipsisHorizontal className="size-5" />
|
||||
</button>
|
||||
</FunctionMenu>
|
||||
|
||||
<div class=" self-center mx-1">
|
||||
<Switch
|
||||
bind:state={func.is_active}
|
||||
on:change={async (e) => {
|
||||
toggleFunctionById(localStorage.token, func.id);
|
||||
models.set(await getModels(localStorage.token));
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row space-x-1 self-center">
|
||||
<Tooltip content="Edit">
|
||||
<a
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
href={`/workspace/functions/edit?id=${encodeURIComponent(func.id)}`}
|
||||
>
|
||||
<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="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>
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Clone">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const _function = await getFunctionById(localStorage.token, func.id).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
if (_function) {
|
||||
sessionStorage.function = JSON.stringify({
|
||||
..._function,
|
||||
id: `${_function.id}_clone`,
|
||||
name: `${_function.name} (Clone)`
|
||||
});
|
||||
goto('/workspace/functions/create');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<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="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Export">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const _function = await getFunctionById(localStorage.token, func.id).catch(
|
||||
(error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
if (_function) {
|
||||
let blob = new Blob([JSON.stringify([_function])], {
|
||||
type: 'application/json'
|
||||
});
|
||||
saveAs(blob, `function-${_function.id}-export-${Date.now()}.json`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArrowDownTray />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Delete">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const res = await deleteFunctionById(localStorage.token, func.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Function deleted successfully');
|
||||
|
||||
functions.set(await getFunctions(localStorage.token));
|
||||
models.set(await getModels(localStorage.token));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<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="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
|
@ -281,7 +299,7 @@
|
|||
functionsImportInputElement.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Functions')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Functions')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -315,7 +333,7 @@
|
|||
}
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Functions')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Functions')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -335,6 +353,42 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-lg font-semibold mb-3 line-clamp-1">
|
||||
{$i18n.t('Made by OpenWebUI Community')}
|
||||
</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
|
||||
href="https://openwebui.com/"
|
||||
target="_blank"
|
||||
>
|
||||
<div class=" self-center w-10 flex-shrink-0">
|
||||
<div
|
||||
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold line-clamp-1">{$i18n.t('Discover a function')}</div>
|
||||
<div class=" text-sm line-clamp-1">
|
||||
{$i18n.t('Discover, download, and explore custom functions')}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ManifestModal bind:show={showManifestModal} manifest={selectedFunction?.meta?.manifest ?? {}} />
|
||||
<ValvesModal bind:show={showValvesModal} type="function" id={selectedFunction?.id ?? null} />
|
||||
|
||||
<ConfirmDialog
|
||||
bind:show={showConfirm}
|
||||
on:confirm={() => {
|
||||
|
|
|
|||
117
src/lib/components/workspace/Functions/FunctionMenu.svelte
Normal file
117
src/lib/components/workspace/Functions/FunctionMenu.svelte
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<script lang="ts">
|
||||
import { DropdownMenu } from 'bits-ui';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Tags from '$lib/components/chat/Tags.svelte';
|
||||
import Share from '$lib/components/icons/Share.svelte';
|
||||
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
||||
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
||||
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let editHandler: Function;
|
||||
export let shareHandler: Function;
|
||||
export let cloneHandler: Function;
|
||||
export let exportHandler: Function;
|
||||
export let deleteHandler: Function;
|
||||
export let onClose: Function;
|
||||
|
||||
let show = false;
|
||||
</script>
|
||||
|
||||
<Dropdown
|
||||
bind:show
|
||||
on:change={(e) => {
|
||||
if (e.detail === false) {
|
||||
onClose();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip content={$i18n.t('More')}>
|
||||
<slot />
|
||||
</Tooltip>
|
||||
|
||||
<div slot="content">
|
||||
<DropdownMenu.Content
|
||||
class="w-full max-w-[160px] rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow"
|
||||
sideOffset={-2}
|
||||
side="bottom"
|
||||
align="start"
|
||||
transition={flyAndScale}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
editHandler();
|
||||
}}
|
||||
>
|
||||
<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="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>
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Edit')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
shareHandler();
|
||||
}}
|
||||
>
|
||||
<Share />
|
||||
<div class="flex items-center">{$i18n.t('Share')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
cloneHandler();
|
||||
}}
|
||||
>
|
||||
<DocumentDuplicate />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Clone')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
exportHandler();
|
||||
}}
|
||||
>
|
||||
<ArrowDownTray />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Export')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<hr class="border-gray-100 dark:border-gray-800 my-1" />
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
deleteHandler();
|
||||
}}
|
||||
>
|
||||
<GarbageBin strokeWidth="2" />
|
||||
<div class="flex items-center">{$i18n.t('Delete')}</div>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
|
@ -256,7 +256,7 @@
|
|||
<hr class=" dark:border-gray-850 my-2.5" />
|
||||
|
||||
<a class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2" href="/workspace/models/create">
|
||||
<div class=" self-center w-10">
|
||||
<div class=" self-center w-10 flex-shrink-0">
|
||||
<div
|
||||
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
>
|
||||
|
|
@ -271,8 +271,8 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">{$i18n.t('Create a model')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Customize models for a specific purpose')}</div>
|
||||
<div class=" font-bold line-clamp-1">{$i18n.t('Create a model')}</div>
|
||||
<div class=" text-sm line-clamp-1">{$i18n.t('Customize models for a specific purpose')}</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
|
@ -412,7 +412,7 @@
|
|||
modelsImportInputElement.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Models')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Models')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -436,7 +436,7 @@
|
|||
downloadModels($models);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Models')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Models')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -494,14 +494,16 @@
|
|||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-lg font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
|
||||
<div class=" text-lg font-semibold mb-3 line-clamp-1">
|
||||
{$i18n.t('Made by OpenWebUI Community')}
|
||||
</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
|
||||
href="https://openwebui.com/"
|
||||
target="_blank"
|
||||
>
|
||||
<div class=" self-center w-10">
|
||||
<div class=" self-center w-10 flex-shrink-0">
|
||||
<div
|
||||
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
>
|
||||
|
|
@ -516,8 +518,10 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">{$i18n.t('Discover a model')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Discover, download, and explore model presets')}</div>
|
||||
<div class=" font-bold line-clamp-1">{$i18n.t('Discover a model')}</div>
|
||||
<div class=" text-sm line-clamp-1">
|
||||
{$i18n.t('Discover, download, and explore model presets')}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,13 +8,16 @@
|
|||
import { createNewPrompt, deletePromptByCommand, getPrompts } from '$lib/apis/prompts';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { goto } from '$app/navigation';
|
||||
import PromptMenu from './Prompts/PromptMenu.svelte';
|
||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
let importFiles = '';
|
||||
let query = '';
|
||||
let promptsImportInputElement: HTMLInputElement;
|
||||
const sharePrompt = async (prompt) => {
|
||||
|
||||
const shareHandler = async (prompt) => {
|
||||
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
|
||||
|
||||
const url = 'https://openwebui.com';
|
||||
|
|
@ -32,7 +35,20 @@
|
|||
);
|
||||
};
|
||||
|
||||
const deletePrompt = async (command) => {
|
||||
const cloneHandler = async (prompt) => {
|
||||
sessionStorage.prompt = JSON.stringify(prompt);
|
||||
goto('/workspace/prompts/create');
|
||||
};
|
||||
|
||||
const exportHandler = async (prompt) => {
|
||||
let blob = new Blob([JSON.stringify([prompt])], {
|
||||
type: 'application/json'
|
||||
});
|
||||
saveAs(blob, `prompt-export-${Date.now()}.json`);
|
||||
};
|
||||
|
||||
const deleteHandler = async (prompt) => {
|
||||
const command = prompt.command;
|
||||
await deletePromptByCommand(localStorage.token, command);
|
||||
await prompts.set(await getPrompts(localStorage.token));
|
||||
};
|
||||
|
|
@ -99,14 +115,14 @@
|
|||
<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
|
||||
<a href={`/workspace/prompts/edit?command=${encodeURIComponent(prompt.command)}`}>
|
||||
<div class=" flex-1 self-center pl-5">
|
||||
<div class=" font-bold">{prompt.command}</div>
|
||||
<div class=" font-bold line-clamp-1">{prompt.command}</div>
|
||||
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
|
||||
{prompt.title}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex flex-row space-x-1 self-center">
|
||||
<div class="flex flex-row gap-0.5 self-center">
|
||||
<a
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
|
|
@ -128,76 +144,28 @@
|
|||
</svg>
|
||||
</a>
|
||||
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
// console.log(modelfile);
|
||||
sessionStorage.prompt = JSON.stringify(prompt);
|
||||
goto('/workspace/prompts/create');
|
||||
<PromptMenu
|
||||
shareHandler={() => {
|
||||
shareHandler(prompt);
|
||||
}}
|
||||
>
|
||||
<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="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
sharePrompt(prompt);
|
||||
cloneHandler={() => {
|
||||
cloneHandler(prompt);
|
||||
}}
|
||||
>
|
||||
<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="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
deletePrompt(prompt.command);
|
||||
exportHandler={() => {
|
||||
exportHandler(prompt);
|
||||
}}
|
||||
deleteHandler={async () => {
|
||||
deleteHandler(prompt);
|
||||
}}
|
||||
onClose={() => {}}
|
||||
>
|
||||
<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"
|
||||
<button
|
||||
class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<EllipsisHorizontal className="size-5" />
|
||||
</button>
|
||||
</PromptMenu>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
@ -245,7 +213,7 @@
|
|||
promptsImportInputElement.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Prompts')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Prompts')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -273,7 +241,7 @@
|
|||
saveAs(blob, `prompts-export-${Date.now()}.json`);
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Prompts')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Prompts')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -302,14 +270,16 @@
|
|||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-lg font-semibold mb-3">{$i18n.t('Made by OpenWebUI Community')}</div>
|
||||
<div class=" text-lg font-semibold mb-3 line-clamp-1">
|
||||
{$i18n.t('Made by OpenWebUI Community')}
|
||||
</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-3 px-3 py-2"
|
||||
href="https://openwebui.com/?type=prompts"
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
|
||||
href="https://openwebui.com/"
|
||||
target="_blank"
|
||||
>
|
||||
<div class=" self-center w-10">
|
||||
<div class=" self-center w-10 flex-shrink-0">
|
||||
<div
|
||||
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
>
|
||||
|
|
@ -324,8 +294,10 @@
|
|||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold">{$i18n.t('Discover a prompt')}</div>
|
||||
<div class=" text-sm">{$i18n.t('Discover, download, and explore custom prompts')}</div>
|
||||
<div class=" font-bold line-clamp-1">{$i18n.t('Discover a prompt')}</div>
|
||||
<div class=" text-sm line-clamp-1">
|
||||
{$i18n.t('Discover, download, and explore custom prompts')}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
92
src/lib/components/workspace/Prompts/PromptMenu.svelte
Normal file
92
src/lib/components/workspace/Prompts/PromptMenu.svelte
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<script lang="ts">
|
||||
import { DropdownMenu } from 'bits-ui';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Tags from '$lib/components/chat/Tags.svelte';
|
||||
import Share from '$lib/components/icons/Share.svelte';
|
||||
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
||||
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
||||
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let shareHandler: Function;
|
||||
export let cloneHandler: Function;
|
||||
export let exportHandler: Function;
|
||||
export let deleteHandler: Function;
|
||||
export let onClose: Function;
|
||||
|
||||
let show = false;
|
||||
</script>
|
||||
|
||||
<Dropdown
|
||||
bind:show
|
||||
on:change={(e) => {
|
||||
if (e.detail === false) {
|
||||
onClose();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip content={$i18n.t('More')}>
|
||||
<slot />
|
||||
</Tooltip>
|
||||
|
||||
<div slot="content">
|
||||
<DropdownMenu.Content
|
||||
class="w-full max-w-[160px] rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow"
|
||||
sideOffset={-2}
|
||||
side="bottom"
|
||||
align="start"
|
||||
transition={flyAndScale}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
shareHandler();
|
||||
}}
|
||||
>
|
||||
<Share />
|
||||
<div class="flex items-center">{$i18n.t('Share')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
cloneHandler();
|
||||
}}
|
||||
>
|
||||
<DocumentDuplicate />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Clone')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
exportHandler();
|
||||
}}
|
||||
>
|
||||
<ArrowDownTray />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Export')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<hr class="border-gray-100 dark:border-gray-800 my-1" />
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
deleteHandler();
|
||||
}}
|
||||
>
|
||||
<GarbageBin strokeWidth="2" />
|
||||
<div class="flex items-center">{$i18n.t('Delete')}</div>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
|
@ -18,6 +18,11 @@
|
|||
import ArrowDownTray from '../icons/ArrowDownTray.svelte';
|
||||
import Tooltip from '../common/Tooltip.svelte';
|
||||
import ConfirmDialog from '../common/ConfirmDialog.svelte';
|
||||
import ToolMenu from './Tools/ToolMenu.svelte';
|
||||
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
|
||||
import ValvesModal from './common/ValvesModal.svelte';
|
||||
import ManifestModal from './common/ManifestModal.svelte';
|
||||
import Heart from '../icons/Heart.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
|
@ -26,6 +31,56 @@
|
|||
|
||||
let showConfirm = false;
|
||||
let query = '';
|
||||
|
||||
let showManifestModal = false;
|
||||
let showValvesModal = false;
|
||||
let selectedTool = null;
|
||||
|
||||
const shareHandler = async (tool) => {
|
||||
console.log(tool);
|
||||
};
|
||||
|
||||
const cloneHandler = async (tool) => {
|
||||
const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_tool) {
|
||||
sessionStorage.tool = JSON.stringify({
|
||||
..._tool,
|
||||
id: `${_tool.id}_clone`,
|
||||
name: `${_tool.name} (Clone)`
|
||||
});
|
||||
goto('/workspace/tools/create');
|
||||
}
|
||||
};
|
||||
|
||||
const exportHandler = async (tool) => {
|
||||
const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_tool) {
|
||||
let blob = new Blob([JSON.stringify([_tool])], {
|
||||
type: 'application/json'
|
||||
});
|
||||
saveAs(blob, `tool-${_tool.id}-export-${Date.now()}.json`);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteHandler = async (tool) => {
|
||||
const res = await deleteToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Tool deleted successfully');
|
||||
tools.set(await getTools(localStorage.token));
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -85,18 +140,14 @@
|
|||
{#each $tools.filter((t) => query === '' || t.name
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase()) || t.id.toLowerCase().includes(query.toLowerCase())) as tool}
|
||||
<button
|
||||
<div
|
||||
class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
goto(`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`);
|
||||
}}
|
||||
>
|
||||
<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
|
||||
<a
|
||||
href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
|
||||
class="flex items-center text-left"
|
||||
>
|
||||
<a
|
||||
class=" flex flex-1 space-x-3.5 cursor-pointer w-full"
|
||||
href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
|
||||
>
|
||||
<div class="flex items-center text-left">
|
||||
<div class=" flex-1 self-center pl-1">
|
||||
<div class=" font-semibold flex items-center gap-1.5">
|
||||
<div
|
||||
|
|
@ -105,144 +156,103 @@
|
|||
TOOL
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{#if tool?.meta?.manifest?.version}
|
||||
<div
|
||||
class="text-xs font-black px-1 rounded line-clamp-1 bg-gray-500/20 text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
v{tool?.meta?.manifest?.version ?? ''}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="line-clamp-1">
|
||||
{tool.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1.5 px-1">
|
||||
<div class=" text-gray-500 text-xs font-medium">{tool.id}</div>
|
||||
<div class=" text-gray-500 text-xs font-medium flex-shrink-0">{tool.id}</div>
|
||||
|
||||
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
|
||||
{tool.meta.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex flex-row gap-0.5 self-center">
|
||||
{#if tool?.meta?.manifest?.funding_url ?? false}
|
||||
<Tooltip content="Support">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTool = tool;
|
||||
showManifestModal = true;
|
||||
}}
|
||||
>
|
||||
<Heart />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
<Tooltip content="Valves">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTool = tool;
|
||||
showValvesModal = true;
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<ToolMenu
|
||||
editHandler={() => {
|
||||
goto(`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`);
|
||||
}}
|
||||
shareHandler={() => {
|
||||
shareHandler(tool);
|
||||
}}
|
||||
cloneHandler={() => {
|
||||
cloneHandler(tool);
|
||||
}}
|
||||
exportHandler={() => {
|
||||
exportHandler(tool);
|
||||
}}
|
||||
deleteHandler={async () => {
|
||||
deleteHandler(tool);
|
||||
}}
|
||||
onClose={() => {}}
|
||||
>
|
||||
<button
|
||||
class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
>
|
||||
<EllipsisHorizontal className="size-5" />
|
||||
</button>
|
||||
</ToolMenu>
|
||||
</div>
|
||||
<div class="flex flex-row space-x-1 self-center">
|
||||
<Tooltip content="Edit">
|
||||
<a
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
href={`/workspace/tools/edit?id=${encodeURIComponent(tool.id)}`}
|
||||
>
|
||||
<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="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>
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Clone">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_tool) {
|
||||
sessionStorage.tool = JSON.stringify({
|
||||
..._tool,
|
||||
id: `${_tool.id}_clone`,
|
||||
name: `${_tool.name} (Clone)`
|
||||
});
|
||||
goto('/workspace/tools/create');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<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="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Export">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const _tool = await getToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (_tool) {
|
||||
let blob = new Blob([JSON.stringify([_tool])], {
|
||||
type: 'application/json'
|
||||
});
|
||||
saveAs(blob, `tool-${_tool.id}-export-${Date.now()}.json`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArrowDownTray />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Delete">
|
||||
<button
|
||||
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
|
||||
type="button"
|
||||
on:click={async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
const res = await deleteToolById(localStorage.token, tool.id).catch((error) => {
|
||||
toast.error(error);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success('Tool deleted successfully');
|
||||
tools.set(await getTools(localStorage.token));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<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="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
|
@ -273,7 +283,7 @@
|
|||
toolsImportInputElement.click();
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Tools')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Import Tools')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -307,7 +317,7 @@
|
|||
}
|
||||
}}
|
||||
>
|
||||
<div class=" self-center mr-2 font-medium">{$i18n.t('Export Tools')}</div>
|
||||
<div class=" self-center mr-2 font-medium line-clamp-1">{$i18n.t('Export Tools')}</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<svg
|
||||
|
|
@ -327,6 +337,42 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" my-16">
|
||||
<div class=" text-lg font-semibold mb-3 line-clamp-1">
|
||||
{$i18n.t('Made by OpenWebUI Community')}
|
||||
</div>
|
||||
|
||||
<a
|
||||
class=" flex space-x-4 cursor-pointer w-full mb-2 px-3 py-2"
|
||||
href="https://openwebui.com/"
|
||||
target="_blank"
|
||||
>
|
||||
<div class=" self-center w-10 flex-shrink-0">
|
||||
<div
|
||||
class="w-full h-10 flex justify-center rounded-full bg-transparent dark:bg-gray-700 border border-dashed border-gray-200"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" self-center">
|
||||
<div class=" font-bold line-clamp-1">{$i18n.t('Discover a tool')}</div>
|
||||
<div class=" text-sm line-clamp-1">
|
||||
{$i18n.t('Discover, download, and explore custom tools')}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ValvesModal bind:show={showValvesModal} type="tool" id={selectedTool?.id ?? null} />
|
||||
<ManifestModal bind:show={showManifestModal} manifest={selectedTool?.meta?.manifest ?? {}} />
|
||||
|
||||
<ConfirmDialog
|
||||
bind:show={showConfirm}
|
||||
on:confirm={() => {
|
||||
|
|
|
|||
117
src/lib/components/workspace/Tools/ToolMenu.svelte
Normal file
117
src/lib/components/workspace/Tools/ToolMenu.svelte
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<script lang="ts">
|
||||
import { DropdownMenu } from 'bits-ui';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
||||
import Pencil from '$lib/components/icons/Pencil.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Tags from '$lib/components/chat/Tags.svelte';
|
||||
import Share from '$lib/components/icons/Share.svelte';
|
||||
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
||||
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
|
||||
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let editHandler: Function;
|
||||
export let shareHandler: Function;
|
||||
export let cloneHandler: Function;
|
||||
export let exportHandler: Function;
|
||||
export let deleteHandler: Function;
|
||||
export let onClose: Function;
|
||||
|
||||
let show = false;
|
||||
</script>
|
||||
|
||||
<Dropdown
|
||||
bind:show
|
||||
on:change={(e) => {
|
||||
if (e.detail === false) {
|
||||
onClose();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip content={$i18n.t('More')}>
|
||||
<slot />
|
||||
</Tooltip>
|
||||
|
||||
<div slot="content">
|
||||
<DropdownMenu.Content
|
||||
class="w-full max-w-[160px] rounded-xl px-1 py-1.5 border border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow"
|
||||
sideOffset={-2}
|
||||
side="bottom"
|
||||
align="start"
|
||||
transition={flyAndScale}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
editHandler();
|
||||
}}
|
||||
>
|
||||
<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="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>
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Edit')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
shareHandler();
|
||||
}}
|
||||
>
|
||||
<Share />
|
||||
<div class="flex items-center">{$i18n.t('Share')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
cloneHandler();
|
||||
}}
|
||||
>
|
||||
<DocumentDuplicate />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Clone')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
exportHandler();
|
||||
}}
|
||||
>
|
||||
<ArrowDownTray />
|
||||
|
||||
<div class="flex items-center">{$i18n.t('Export')}</div>
|
||||
</DropdownMenu.Item>
|
||||
|
||||
<hr class="border-gray-100 dark:border-gray-800 my-1" />
|
||||
|
||||
<DropdownMenu.Item
|
||||
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
|
||||
on:click={() => {
|
||||
deleteHandler();
|
||||
}}
|
||||
>
|
||||
<GarbageBin strokeWidth="2" />
|
||||
<div class="flex items-center">{$i18n.t('Delete')}</div>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</div>
|
||||
</Dropdown>
|
||||
102
src/lib/components/workspace/common/ManifestModal.svelte
Normal file
102
src/lib/components/workspace/common/ManifestModal.svelte
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
|
||||
import Modal from '../../common/Modal.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let show = false;
|
||||
export let manifest = {};
|
||||
</script>
|
||||
|
||||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Show your support!')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col md:flex-row w-full px-5 pb-4 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">
|
||||
<form
|
||||
class="flex flex-col w-full"
|
||||
on:submit|preventDefault={() => {
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
<div class="px-1 text-sm">
|
||||
<div class=" my-2">
|
||||
The developers behind this plugin are passionate volunteers from the community. If you
|
||||
find this plugin helpful, please consider contributing to its development.
|
||||
</div>
|
||||
|
||||
<div class=" my-2">
|
||||
Your entire contribution will go directly to the plugin developer; Open WebUI does not
|
||||
take any percentage. However, the chosen funding platform might have its own fees.
|
||||
</div>
|
||||
|
||||
<hr class=" dark:border-gray-800 my-3" />
|
||||
|
||||
<div class="my-2">
|
||||
Support this plugin: <a
|
||||
href={manifest.funding_url}
|
||||
target="_blank"
|
||||
class=" underline text-blue-400 hover:text-blue-300">{manifest.funding_url}</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pt-3 text-sm font-medium">
|
||||
<button
|
||||
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg flex flex-row space-x-1 items-center"
|
||||
type="submit"
|
||||
>
|
||||
{$i18n.t('Done')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
/* display: none; <- Crashes Chrome on hover */
|
||||
-webkit-appearance: none;
|
||||
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
|
||||
}
|
||||
|
||||
.tabs::-webkit-scrollbar {
|
||||
display: none; /* for Chrome, Safari and Opera */
|
||||
}
|
||||
|
||||
.tabs {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
input[type='number'] {
|
||||
-moz-appearance: textfield; /* Firefox */
|
||||
}
|
||||
</style>
|
||||
256
src/lib/components/workspace/common/ValvesModal.svelte
Normal file
256
src/lib/components/workspace/common/ValvesModal.svelte
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
<script lang="ts">
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { addUser } from '$lib/apis/auths';
|
||||
|
||||
import Modal from '../../common/Modal.svelte';
|
||||
import {
|
||||
getFunctionValvesById,
|
||||
getFunctionValvesSpecById,
|
||||
updateFunctionValvesById
|
||||
} from '$lib/apis/functions';
|
||||
import { getToolValvesById, getToolValvesSpecById, updateToolValvesById } from '$lib/apis/tools';
|
||||
import Spinner from '../../common/Spinner.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let show = false;
|
||||
|
||||
export let type = 'tool';
|
||||
export let id = null;
|
||||
|
||||
let saving = false;
|
||||
let loading = false;
|
||||
|
||||
let valvesSpec = null;
|
||||
let valves = {};
|
||||
|
||||
const submitHandler = async () => {
|
||||
saving = true;
|
||||
|
||||
if (valvesSpec) {
|
||||
// Convert string to array
|
||||
for (const property in valvesSpec.properties) {
|
||||
if (valvesSpec.properties[property]?.type === 'array') {
|
||||
valves[property] = (valves[property] ?? '').split(',').map((v) => v.trim());
|
||||
}
|
||||
}
|
||||
|
||||
let res = null;
|
||||
|
||||
if (type === 'tool') {
|
||||
res = await updateToolValvesById(localStorage.token, id, valves).catch((error) => {
|
||||
toast.error(error);
|
||||
});
|
||||
} else if (type === 'function') {
|
||||
res = await updateFunctionValvesById(localStorage.token, id, valves).catch((error) => {
|
||||
toast.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
if (res) {
|
||||
toast.success('Valves updated successfully');
|
||||
}
|
||||
}
|
||||
|
||||
saving = false;
|
||||
};
|
||||
|
||||
const initHandler = async () => {
|
||||
loading = true;
|
||||
valves = {};
|
||||
valvesSpec = null;
|
||||
|
||||
if (type === 'tool') {
|
||||
valves = await getToolValvesById(localStorage.token, id);
|
||||
valvesSpec = await getToolValvesSpecById(localStorage.token, id);
|
||||
} else if (type === 'function') {
|
||||
valves = await getFunctionValvesById(localStorage.token, id);
|
||||
valvesSpec = await getFunctionValvesSpecById(localStorage.token, id);
|
||||
}
|
||||
|
||||
if (!valves) {
|
||||
valves = {};
|
||||
}
|
||||
|
||||
if (valvesSpec) {
|
||||
// Convert array to string
|
||||
for (const property in valvesSpec.properties) {
|
||||
if (valvesSpec.properties[property]?.type === 'array') {
|
||||
valves[property] = (valves[property] ?? []).join(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loading = false;
|
||||
};
|
||||
|
||||
$: if (show) {
|
||||
initHandler();
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
|
||||
<div class=" text-lg font-medium self-center">{$i18n.t('Valves')}</div>
|
||||
<button
|
||||
class="self-center"
|
||||
on:click={() => {
|
||||
show = false;
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col md:flex-row w-full px-5 pb-4 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">
|
||||
<form
|
||||
class="flex flex-col w-full"
|
||||
on:submit|preventDefault={() => {
|
||||
submitHandler();
|
||||
}}
|
||||
>
|
||||
<div class="px-1">
|
||||
{#if !loading}
|
||||
{#if valvesSpec}
|
||||
{#each Object.keys(valvesSpec.properties) as property, idx}
|
||||
<div class=" py-0.5 w-full justify-between">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{valvesSpec.properties[property].title}
|
||||
|
||||
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||
<span class=" text-gray-500">*required</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
valves[property] = (valves[property] ?? null) === null ? '' : null;
|
||||
}}
|
||||
>
|
||||
{#if (valves[property] ?? null) === null}
|
||||
<span class="ml-2 self-center">
|
||||
{#if (valvesSpec?.required ?? []).includes(property)}
|
||||
{$i18n.t('None')}
|
||||
{:else}
|
||||
{$i18n.t('Default')}
|
||||
{/if}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if (valves[property] ?? null) !== null}
|
||||
<div class="flex mt-0.5 mb-1.5 space-x-2">
|
||||
<div class=" flex-1">
|
||||
<input
|
||||
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
type="text"
|
||||
placeholder={valvesSpec.properties[property].title}
|
||||
bind:value={valves[property]}
|
||||
autocomplete="off"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if (valvesSpec.properties[property]?.description ?? null) !== null}
|
||||
<div class="text-xs text-gray-500">
|
||||
{valvesSpec.properties[property].description}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="text-sm">No valves</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<Spinner className="size-5" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pt-3 text-sm font-medium">
|
||||
<button
|
||||
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg flex flex-row space-x-1 items-center {saving
|
||||
? ' cursor-not-allowed'
|
||||
: ''}"
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
>
|
||||
{$i18n.t('Save')}
|
||||
|
||||
{#if saving}
|
||||
<div class="ml-2 self-center">
|
||||
<svg
|
||||
class=" w-4 h-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>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
/* display: none; <- Crashes Chrome on hover */
|
||||
-webkit-appearance: none;
|
||||
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
|
||||
}
|
||||
|
||||
.tabs::-webkit-scrollbar {
|
||||
display: none; /* for Chrome, Safari and Opera */
|
||||
}
|
||||
|
||||
.tabs {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
input[type='number'] {
|
||||
-moz-appearance: textfield; /* Firefox */
|
||||
}
|
||||
</style>
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "يستطيع حذف المحادثات",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "الأحرف الأبجدية الرقمية والواصلات",
|
||||
"Already have an account?": "هل تملك حساب ؟",
|
||||
"an assistant": "مساعد",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "حذف {{name}}",
|
||||
"Description": "وصف",
|
||||
"Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "اكتشف نموذجا",
|
||||
"Discover a prompt": "اكتشاف موجه",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "اكتشاف وتنزيل واستكشاف المطالبات المخصصة",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "اكتشاف وتنزيل واستكشاف الإعدادات المسبقة للنموذج",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "لا تسمح بذلك",
|
||||
"Don't have an account?": "ليس لديك حساب؟",
|
||||
"Don't like the style": "لا أحب النمط",
|
||||
"Done": "",
|
||||
"Download": "تحميل",
|
||||
"Download canceled": "تم اللغاء التحميل",
|
||||
"Download Database": "تحميل قاعدة البيانات",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "إدارة النماذج",
|
||||
"Manage Ollama Models": "Ollama إدارة موديلات ",
|
||||
"Manage Pipelines": "إدارة خطوط الأنابيب",
|
||||
"Manage Valves": "",
|
||||
"March": "مارس",
|
||||
"Max Tokens (num_predict)": "ماكس توكنز (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "يمكن تنزيل 3 نماذج كحد أقصى في وقت واحد. الرجاء معاودة المحاولة في وقت لاحق.",
|
||||
|
|
@ -463,10 +470,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "حدد نموذجا أساسيا",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "أختار موديل",
|
||||
"Select a model": "أختار الموديل",
|
||||
"Select a pipeline": "حدد مسارا",
|
||||
"Select a pipeline url": "حدد عنوان URL لخط الأنابيب",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "أختار سيرفر ",
|
||||
"Select Documents": "",
|
||||
"Select model": " أختار موديل",
|
||||
|
|
@ -499,6 +508,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "إظهار الاختصارات",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "أظهر الإبداع",
|
||||
"sidebar": "الشريط الجانبي",
|
||||
"Sign in": "تسجيل الدخول",
|
||||
|
|
@ -587,6 +597,7 @@
|
|||
"Users": "المستخدمين",
|
||||
"Utilize": "يستخدم",
|
||||
"Valid time units:": "وحدات زمنية صالحة:",
|
||||
"Valves": "",
|
||||
"variable": "المتغير",
|
||||
"variable to have them replaced with clipboard content.": "متغير لاستبدالها بمحتوى الحافظة.",
|
||||
"Version": "إصدار",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Позволи Изтриване на Чат",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "алфанумерични знаци и тире",
|
||||
"Already have an account?": "Вече имате акаунт? ",
|
||||
"an assistant": "асистент",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Изтрито {{име}}",
|
||||
"Description": "Описание",
|
||||
"Didn't fully follow instructions": "Не следва инструкциите",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Открийте модел",
|
||||
"Discover a prompt": "Откриване на промпт",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Откриване, сваляне и преглед на персонализирани промптове",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Откриване, сваляне и преглед на пресетове на модели",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Не Позволявай",
|
||||
"Don't have an account?": "Нямате акаунт?",
|
||||
"Don't like the style": "Не харесваш стила?",
|
||||
"Done": "",
|
||||
"Download": "Изтегляне отменено",
|
||||
"Download canceled": "Изтегляне отменено",
|
||||
"Download Database": "Сваляне на база данни",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Управление на Моделите",
|
||||
"Manage Ollama Models": "Управление на Ollama Моделите",
|
||||
"Manage Pipelines": "Управление на тръбопроводи",
|
||||
"Manage Valves": "",
|
||||
"March": "Март",
|
||||
"Max Tokens (num_predict)": "Макс токени (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 модели могат да бъдат сваляни едновременно. Моля, опитайте отново по-късно.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Изберете базов модел",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Изберете режим",
|
||||
"Select a model": "Изберете модел",
|
||||
"Select a pipeline": "Изберете тръбопровод",
|
||||
"Select a pipeline url": "Избор на URL адрес на канал",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Изберете Ollama инстанция",
|
||||
"Select Documents": "",
|
||||
"Select model": "Изберете модел",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Покажи",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Показана креативност",
|
||||
"sidebar": "sidebar",
|
||||
"Sign in": "Вписване",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Потребители",
|
||||
"Utilize": "Използване",
|
||||
"Valid time units:": "Валидни единици за време:",
|
||||
"Valves": "",
|
||||
"variable": "променлива",
|
||||
"variable to have them replaced with clipboard content.": "променливи да се заменят съдържанието от клипборд.",
|
||||
"Version": "Версия",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "চ্যাট ডিলিট করতে দিন",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "ইংরেজি অক্ষর, সংখ্যা এবং হাইফেন",
|
||||
"Already have an account?": "আগে থেকেই একাউন্ট আছে?",
|
||||
"an assistant": "একটা এসিস্ট্যান্ট",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}} মোছা হয়েছে",
|
||||
"Description": "বিবরণ",
|
||||
"Didn't fully follow instructions": "ইনস্ট্রাকশন সম্পূর্ণ অনুসরণ করা হয়নি",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "একটি মডেল আবিষ্কার করুন",
|
||||
"Discover a prompt": "একটি প্রম্পট খুঁজে বের করুন",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "কাস্টম প্রম্পটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "মডেল প্রিসেটগুলো আবিস্কার, ডাউনলোড এবং এক্সপ্লোর করুন",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "অনুমোদন দেবেন না",
|
||||
"Don't have an account?": "একাউন্ট নেই?",
|
||||
"Don't like the style": "স্টাইল পছন্দ করেন না",
|
||||
"Done": "",
|
||||
"Download": "ডাউনলোড",
|
||||
"Download canceled": "ডাউনলোড বাতিল করা হয়েছে",
|
||||
"Download Database": "ডেটাবেজ ডাউনলোড করুন",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "মডেলসমূহ ব্যবস্থাপনা করুন",
|
||||
"Manage Ollama Models": "Ollama মডেলসূহ ব্যবস্থাপনা করুন",
|
||||
"Manage Pipelines": "পাইপলাইন পরিচালনা করুন",
|
||||
"Manage Valves": "",
|
||||
"March": "মার্চ",
|
||||
"Max Tokens (num_predict)": "সর্বোচ্চ টোকেন (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "একসঙ্গে সর্বোচ্চ তিনটি মডেল ডাউনলোড করা যায়। দয়া করে পরে আবার চেষ্টা করুন।",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "সীড",
|
||||
"Select a base model": "একটি বেস মডেল নির্বাচন করুন",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "একটি মডেল নির্বাচন করুন",
|
||||
"Select a model": "একটি মডেল নির্বাচন করুন",
|
||||
"Select a pipeline": "একটি পাইপলাইন নির্বাচন করুন",
|
||||
"Select a pipeline url": "একটি পাইপলাইন URL নির্বাচন করুন",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "একটি Ollama ইন্সট্যান্স নির্বাচন করুন",
|
||||
"Select Documents": "",
|
||||
"Select model": "মডেল নির্বাচন করুন",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "শর্টকাটগুলো দেখান",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "সৃজনশীলতা প্রদর্শন",
|
||||
"sidebar": "সাইডবার",
|
||||
"Sign in": "সাইন ইন",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "ব্যাবহারকারীগণ",
|
||||
"Utilize": "ইউটিলাইজ",
|
||||
"Valid time units:": "সময়ের গ্রহণযোগ্য এককসমূহ:",
|
||||
"Valves": "",
|
||||
"variable": "ভেরিয়েবল",
|
||||
"variable to have them replaced with clipboard content.": "ক্লিপবোর্ডের কন্টেন্ট দিয়ে যেই ভেরিয়েবল রিপ্লেস করা যাবে।",
|
||||
"Version": "ভার্সন",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Tugoti nga mapapas ang mga chat",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alphanumeric nga mga karakter ug hyphen",
|
||||
"Already have an account?": "Naa na kay account ?",
|
||||
"an assistant": "usa ka katabang",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "Deskripsyon",
|
||||
"Didn't fully follow instructions": "",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "Pagkaplag usa ka prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Pagdiskubre, pag-download ug pagsuhid sa mga naandan nga pag-aghat",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Pagdiskobre, pag-download, ug pagsuhid sa mga preset sa template",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Dili tugotan",
|
||||
"Don't have an account?": "Wala kay account ?",
|
||||
"Don't like the style": "",
|
||||
"Done": "",
|
||||
"Download": "",
|
||||
"Download canceled": "",
|
||||
"Download Database": "I-download ang database",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Pagdumala sa mga templates",
|
||||
"Manage Ollama Models": "Pagdumala sa mga modelo sa Ollama",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Ang labing taas nga 3 nga mga disenyo mahimong ma-download nga dungan. ",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Binhi",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Pagpili og mode",
|
||||
"Select a model": "Pagpili og modelo",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Pagpili usa ka pananglitan sa Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Pagpili og modelo",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Ipakita ang mga shortcut",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "",
|
||||
"sidebar": "lateral bar",
|
||||
"Sign in": "Para maka log in",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Mga tiggamit",
|
||||
"Utilize": "Sa paggamit",
|
||||
"Valid time units:": "Balido nga mga yunit sa oras:",
|
||||
"Valves": "",
|
||||
"variable": "variable",
|
||||
"variable to have them replaced with clipboard content.": "variable aron pulihan kini sa mga sulud sa clipboard.",
|
||||
"Version": "Bersyon",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Chat Löschung erlauben",
|
||||
"Allow non-local voices": "Nicht-lokale Stimmen erlauben",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alphanumerische Zeichen und Bindestriche",
|
||||
"Already have an account?": "Hast du vielleicht schon ein Account?",
|
||||
"an assistant": "ein Assistent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Gelöscht {{name}}",
|
||||
"Description": "Beschreibung",
|
||||
"Didn't fully follow instructions": "Nicht genau den Answeisungen gefolgt",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Entdecken Sie ein Modell",
|
||||
"Discover a prompt": "Einen Prompt entdecken",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Benutzerdefinierte Prompts entdecken, herunterladen und erkunden",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Modellvorgaben entdecken, herunterladen und erkunden",
|
||||
"Dismissible": "ausblendbar",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Nicht erlauben",
|
||||
"Don't have an account?": "Hast du vielleicht noch kein Konto?",
|
||||
"Don't like the style": "Dir gefällt der Style nicht",
|
||||
"Done": "",
|
||||
"Download": "Herunterladen",
|
||||
"Download canceled": "Download abgebrochen",
|
||||
"Download Database": "Datenbank herunterladen",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Modelle verwalten",
|
||||
"Manage Ollama Models": "Ollama-Modelle verwalten",
|
||||
"Manage Pipelines": "Verwalten von Pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "März",
|
||||
"Max Tokens (num_predict)": "Max. Token (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Es können maximal 3 Modelle gleichzeitig heruntergeladen werden. Bitte versuche es später erneut.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Wählen Sie ein Basismodell",
|
||||
"Select a engine": "Wähle eine Engine",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Einen Modus auswählen",
|
||||
"Select a model": "Ein Modell auswählen",
|
||||
"Select a pipeline": "Wählen Sie eine Pipeline aus",
|
||||
"Select a pipeline url": "Auswählen einer Pipeline-URL",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Eine Ollama Instanz auswählen",
|
||||
"Select Documents": "",
|
||||
"Select model": "Modell auswählen",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Verknüpfungen anzeigen",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Kreativität zur Schau gestellt",
|
||||
"sidebar": "Seitenleiste",
|
||||
"Sign in": "Anmelden",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Benutzer",
|
||||
"Utilize": "Nutze die",
|
||||
"Valid time units:": "Gültige Zeiteinheiten:",
|
||||
"Valves": "",
|
||||
"variable": "Variable",
|
||||
"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
|
||||
"Version": "Version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Allow Delete Chats",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "so alpha, many hyphen",
|
||||
"Already have an account?": "Such account exists?",
|
||||
"an assistant": "such assistant",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "Discover a prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Discover, download, and explore custom prompts",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Discover, download, and explore model presets",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Don't Allow",
|
||||
"Don't have an account?": "No account? Much sad.",
|
||||
"Don't like the style": "",
|
||||
"Done": "",
|
||||
"Download": "",
|
||||
"Download canceled": "",
|
||||
"Download Database": "Download Database",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Manage Wowdels",
|
||||
"Manage Ollama Models": "Manage Ollama Wowdels",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximum of 3 models can be downloaded simultaneously. Please try again later.",
|
||||
|
|
@ -461,10 +468,12 @@
|
|||
"Seed": "Seed very plant",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Select a mode very choose",
|
||||
"Select a model": "Select a model much choice",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Select an Ollama instance very choose",
|
||||
"Select Documents": "",
|
||||
"Select model": "Select model much choice",
|
||||
|
|
@ -497,6 +506,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Show shortcuts much shortcut",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "",
|
||||
"sidebar": "sidebar much side",
|
||||
"Sign in": "Sign in very sign",
|
||||
|
|
@ -585,6 +595,7 @@
|
|||
"Users": "Users much users",
|
||||
"Utilize": "Utilize very use",
|
||||
"Valid time units:": "Valid time units: much time",
|
||||
"Valves": "",
|
||||
"variable": "variable very variable",
|
||||
"variable to have them replaced with clipboard content.": "variable to have them replaced with clipboard content. Very replace.",
|
||||
"Version": "Version much version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "",
|
||||
"Already have an account?": "",
|
||||
"an assistant": "",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "",
|
||||
"Didn't fully follow instructions": "",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "",
|
||||
"Don't have an account?": "",
|
||||
"Don't like the style": "",
|
||||
"Done": "",
|
||||
"Download": "",
|
||||
"Download canceled": "",
|
||||
"Download Database": "",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "",
|
||||
"Manage Ollama Models": "",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "",
|
||||
"Select a model": "",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "",
|
||||
"Select Documents": "",
|
||||
"Select model": "",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "",
|
||||
"sidebar": "",
|
||||
"Sign in": "",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "",
|
||||
"Utilize": "",
|
||||
"Valid time units:": "",
|
||||
"Valves": "",
|
||||
"variable": "",
|
||||
"variable to have them replaced with clipboard content.": "",
|
||||
"Version": "",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "",
|
||||
"Already have an account?": "",
|
||||
"an assistant": "",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "",
|
||||
"Didn't fully follow instructions": "",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "",
|
||||
"Don't have an account?": "",
|
||||
"Don't like the style": "",
|
||||
"Done": "",
|
||||
"Download": "",
|
||||
"Download canceled": "",
|
||||
"Download Database": "",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "",
|
||||
"Manage Ollama Models": "",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "",
|
||||
"Select a model": "",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "",
|
||||
"Select Documents": "",
|
||||
"Select model": "",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "",
|
||||
"sidebar": "",
|
||||
"Sign in": "",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "",
|
||||
"Utilize": "",
|
||||
"Valid time units:": "",
|
||||
"Valves": "",
|
||||
"variable": "",
|
||||
"variable to have them replaced with clipboard content.": "",
|
||||
"Version": "",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Permitir Borrar Chats",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caracteres alfanuméricos y guiones",
|
||||
"Already have an account?": "¿Ya tienes una cuenta?",
|
||||
"an assistant": "un asistente",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Eliminado {{nombre}}",
|
||||
"Description": "Descripción",
|
||||
"Didn't fully follow instructions": "No siguió las instrucciones",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Descubrir un modelo",
|
||||
"Discover a prompt": "Descubre un Prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Descubre, descarga, y explora Prompts personalizados",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Descubre, descarga y explora ajustes preestablecidos de modelos",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "No Permitir",
|
||||
"Don't have an account?": "¿No tienes una cuenta?",
|
||||
"Don't like the style": "No te gusta el estilo?",
|
||||
"Done": "",
|
||||
"Download": "Descargar",
|
||||
"Download canceled": "Descarga cancelada",
|
||||
"Download Database": "Descarga la Base de Datos",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Administrar Modelos",
|
||||
"Manage Ollama Models": "Administrar Modelos Ollama",
|
||||
"Manage Pipelines": "Administrar canalizaciones",
|
||||
"Manage Valves": "",
|
||||
"March": "Marzo",
|
||||
"Max Tokens (num_predict)": "Máximo de fichas (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Se pueden descargar un máximo de 3 modelos simultáneamente. Por favor, inténtelo de nuevo más tarde.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Seleccionar un modelo base",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Selecciona un modo",
|
||||
"Select a model": "Selecciona un modelo",
|
||||
"Select a pipeline": "Selección de una canalización",
|
||||
"Select a pipeline url": "Selección de una dirección URL de canalización",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Seleccione una instancia de Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Selecciona un modelo",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Mostrar atajos",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Mostrar creatividad",
|
||||
"sidebar": "barra lateral",
|
||||
"Sign in": "Iniciar sesión",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Usuarios",
|
||||
"Utilize": "Utilizar",
|
||||
"Valid time units:": "Unidades válidas de tiempo:",
|
||||
"Valves": "",
|
||||
"variable": "variable",
|
||||
"variable to have them replaced with clipboard content.": "variable para reemplazarlos con el contenido del portapapeles.",
|
||||
"Version": "Versión",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "اجازه حذف گپ",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "حروف الفبایی و خط فاصله",
|
||||
"Already have an account?": "از قبل حساب کاربری دارید؟",
|
||||
"an assistant": "یک دستیار",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "حذف شده {{name}}",
|
||||
"Description": "توضیحات",
|
||||
"Didn't fully follow instructions": "نمی تواند دستورالعمل را کامل پیگیری کند",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "کشف یک مدل",
|
||||
"Discover a prompt": "یک اعلان را کشف کنید",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "پرامپت\u200cهای سفارشی را کشف، دانلود و کاوش کنید",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "پیش تنظیمات مدل را کشف، دانلود و کاوش کنید",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "اجازه نده",
|
||||
"Don't have an account?": "حساب کاربری ندارید؟",
|
||||
"Don't like the style": "نظری ندارید؟",
|
||||
"Done": "",
|
||||
"Download": "دانلود کن",
|
||||
"Download canceled": "دانلود لغو شد",
|
||||
"Download Database": "دانلود پایگاه داده",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "مدیریت مدل\u200cها",
|
||||
"Manage Ollama Models": "مدیریت مدل\u200cهای اولاما",
|
||||
"Manage Pipelines": "مدیریت خطوط لوله",
|
||||
"Manage Valves": "",
|
||||
"March": "مارچ",
|
||||
"Max Tokens (num_predict)": "توکنهای بیشینه (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "حداکثر 3 مدل را می توان به طور همزمان دانلود کرد. لطفاً بعداً دوباره امتحان کنید.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "انتخاب یک مدل پایه",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "یک حالت انتخاب کنید",
|
||||
"Select a model": "انتخاب یک مدل",
|
||||
"Select a pipeline": "انتخاب یک خط لوله",
|
||||
"Select a pipeline url": "یک ادرس خط لوله را انتخاب کنید",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "انتخاب یک نمونه از اولاما",
|
||||
"Select Documents": "",
|
||||
"Select model": "انتخاب یک مدل",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "نمایش میانبرها",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "ایده\u200cآفرینی",
|
||||
"sidebar": "نوار کناری",
|
||||
"Sign in": "ورود",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "کاربران",
|
||||
"Utilize": "استفاده کنید",
|
||||
"Valid time units:": "واحدهای زمانی معتبر:",
|
||||
"Valves": "",
|
||||
"variable": "متغیر",
|
||||
"variable to have them replaced with clipboard content.": "متغیر برای جایگزینی آنها با محتوای کلیپ بورد.",
|
||||
"Version": "نسخه",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Salli keskustelujen poisto",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "kirjaimia, numeroita ja väliviivoja",
|
||||
"Already have an account?": "Onko sinulla jo tili?",
|
||||
"an assistant": "avustaja",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Poistettu {{nimi}}",
|
||||
"Description": "Kuvaus",
|
||||
"Didn't fully follow instructions": "Ei noudattanut ohjeita täysin",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Tutustu malliin",
|
||||
"Discover a prompt": "Löydä kehote",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Löydä ja lataa mukautettuja kehotteita",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Löydä ja lataa mallien esiasetuksia",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Älä salli",
|
||||
"Don't have an account?": "Eikö sinulla ole tiliä?",
|
||||
"Don't like the style": "En pidä tyylistä",
|
||||
"Done": "",
|
||||
"Download": "Lataa",
|
||||
"Download canceled": "Lataus peruutettu",
|
||||
"Download Database": "Lataa tietokanta",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Hallitse malleja",
|
||||
"Manage Ollama Models": "Hallitse Ollama-malleja",
|
||||
"Manage Pipelines": "Hallitse putkia",
|
||||
"Manage Valves": "",
|
||||
"March": "maaliskuu",
|
||||
"Max Tokens (num_predict)": "Tokenien enimmäismäärä (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Enintään 3 mallia voidaan ladata samanaikaisesti. Yritä myöhemmin uudelleen.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Siemen",
|
||||
"Select a base model": "Valitse perusmalli",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Valitse tila",
|
||||
"Select a model": "Valitse malli",
|
||||
"Select a pipeline": "Valitse putki",
|
||||
"Select a pipeline url": "Valitse putken URL-osoite",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Valitse Ollama-instanssi",
|
||||
"Select Documents": "",
|
||||
"Select model": "Valitse malli",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Näytä pikanäppäimet",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Näytti luovuutta",
|
||||
"sidebar": "sivupalkki",
|
||||
"Sign in": "Kirjaudu sisään",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Käyttäjät",
|
||||
"Utilize": "Käytä",
|
||||
"Valid time units:": "Kelvolliset aikayksiköt:",
|
||||
"Valves": "",
|
||||
"variable": "muuttuja",
|
||||
"variable to have them replaced with clipboard content.": "muuttuja korvataan leikepöydän sisällöllä.",
|
||||
"Version": "Versio",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Autoriser la suppression des discussions",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
|
||||
"Already have an account?": "Vous avez déjà un compte ?",
|
||||
"an assistant": "un assistant",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Supprimé {{nom}}",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "Ne suit pas les instructions",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Découvrez un modèle",
|
||||
"Discover a prompt": "Découvrir un prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Ne pas autoriser",
|
||||
"Don't have an account?": "Vous n'avez pas de compte ?",
|
||||
"Don't like the style": "Vous n'aimez pas le style ?",
|
||||
"Done": "",
|
||||
"Download": "Télécharger",
|
||||
"Download canceled": "Téléchargement annulé",
|
||||
"Download Database": "Télécharger la base de données",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Gérer les modèles",
|
||||
"Manage Ollama Models": "Gérer les modèles Ollama",
|
||||
"Manage Pipelines": "Gérer les pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Mars",
|
||||
"Max Tokens (num_predict)": "Max Tokens (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Graine",
|
||||
"Select a base model": "Sélectionner un modèle de base",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Sélectionnez un mode",
|
||||
"Select a model": "Sélectionnez un modèle",
|
||||
"Select a pipeline": "Sélectionner un pipeline",
|
||||
"Select a pipeline url": "Sélectionnez une URL de pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Sélectionner une instance Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Sélectionnez un modèle",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Afficher les raccourcis",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Créativité affichée",
|
||||
"sidebar": "barre latérale",
|
||||
"Sign in": "Se connecter",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Utilisateurs",
|
||||
"Utilize": "Utiliser",
|
||||
"Valid time units:": "Unités de temps valides :",
|
||||
"Valves": "",
|
||||
"variable": "variable",
|
||||
"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
|
||||
"Version": "Version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Autoriser la suppression du chat",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caractères alphanumériques et tirets",
|
||||
"Already have an account?": "Vous avez déjà un compte ?",
|
||||
"an assistant": "un assistant",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}} supprimé",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "N'a pas suivi entièrement les instructions",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Découvrir un modèle",
|
||||
"Discover a prompt": "Découvrir un prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Découvrir, télécharger et explorer des prompts personnalisés",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Découvrir, télécharger et explorer des préconfigurations de modèles",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Ne pas autoriser",
|
||||
"Don't have an account?": "Vous n'avez pas de compte ?",
|
||||
"Don't like the style": "N'aime pas le style",
|
||||
"Done": "",
|
||||
"Download": "Télécharger",
|
||||
"Download canceled": "Téléchargement annulé",
|
||||
"Download Database": "Télécharger la base de données",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Gérer les modèles",
|
||||
"Manage Ollama Models": "Gérer les modèles Ollama",
|
||||
"Manage Pipelines": "Gérer les pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Mars",
|
||||
"Max Tokens (num_predict)": "Tokens maximaux (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Un maximum de 3 modèles peut être téléchargé simultanément. Veuillez réessayer plus tard.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Graine",
|
||||
"Select a base model": "Sélectionner un modèle de base",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Sélectionner un mode",
|
||||
"Select a model": "Sélectionner un modèle",
|
||||
"Select a pipeline": "Sélectionner un pipeline",
|
||||
"Select a pipeline url": "Sélectionnez une URL de pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Sélectionner une instance Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Sélectionner un modèle",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Afficher les raccourcis",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Créativité affichée",
|
||||
"sidebar": "barre latérale",
|
||||
"Sign in": "Se connecter",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Utilisateurs",
|
||||
"Utilize": "Utiliser",
|
||||
"Valid time units:": "Unités de temps valides :",
|
||||
"Valves": "",
|
||||
"variable": "variable",
|
||||
"variable to have them replaced with clipboard content.": "variable pour les remplacer par le contenu du presse-papiers.",
|
||||
"Version": "Version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "אפשר מחיקת צ'אט",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "תווים אלפאנומריים ומקפים",
|
||||
"Already have an account?": "כבר יש לך חשבון?",
|
||||
"an assistant": "עוזר",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "נמחק {{name}}",
|
||||
"Description": "תיאור",
|
||||
"Didn't fully follow instructions": "לא עקב אחרי ההוראות באופן מלא",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "גלה מודל",
|
||||
"Discover a prompt": "גלה פקודה",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "גלה, הורד, וחקור פקודות מותאמות אישית",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "גלה, הורד, וחקור הגדרות מודל מוגדרות מראש",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "אל תאפשר",
|
||||
"Don't have an account?": "אין לך חשבון?",
|
||||
"Don't like the style": "לא אוהב את הסגנון",
|
||||
"Done": "",
|
||||
"Download": "הורד",
|
||||
"Download canceled": "ההורדה בוטלה",
|
||||
"Download Database": "הורד מסד נתונים",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "נהל מודלים",
|
||||
"Manage Ollama Models": "נהל מודלים של Ollama",
|
||||
"Manage Pipelines": "ניהול צינורות",
|
||||
"Manage Valves": "",
|
||||
"March": "מרץ",
|
||||
"Max Tokens (num_predict)": "מקסימום אסימונים (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ניתן להוריד מקסימום 3 מודלים בו זמנית. אנא נסה שוב מאוחר יותר.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "זרע",
|
||||
"Select a base model": "בחירת מודל בסיס",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "בחר מצב",
|
||||
"Select a model": "בחר מודל",
|
||||
"Select a pipeline": "בחר קו צינור",
|
||||
"Select a pipeline url": "בחר כתובת URL של קו צינור",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "בחר מופע של Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "בחר מודל",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "הצג קיצורי דרך",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "הצגת יצירתיות",
|
||||
"sidebar": "סרגל צד",
|
||||
"Sign in": "הירשם",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "משתמשים",
|
||||
"Utilize": "שימוש",
|
||||
"Valid time units:": "יחידות זמן תקינות:",
|
||||
"Valves": "",
|
||||
"variable": "משתנה",
|
||||
"variable to have them replaced with clipboard content.": "משתנה להחליפו ב- clipboard תוכן.",
|
||||
"Version": "גרסה",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "चैट हटाने की अनुमति दें",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "अल्फ़ान्यूमेरिक वर्ण और हाइफ़न",
|
||||
"Already have an account?": "क्या आपके पास पहले से एक खाता मौजूद है?",
|
||||
"an assistant": "एक सहायक",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}} हटा दिया गया",
|
||||
"Description": "विवरण",
|
||||
"Didn't fully follow instructions": "निर्देशों का पूरी तरह से पालन नहीं किया",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "एक मॉडल की खोज करें",
|
||||
"Discover a prompt": "प्रॉम्प्ट खोजें",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "कस्टम प्रॉम्प्ट को खोजें, डाउनलोड करें और एक्सप्लोर करें",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "मॉडल प्रीसेट खोजें, डाउनलोड करें और एक्सप्लोर करें",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "अनुमति न दें",
|
||||
"Don't have an account?": "कोई खाता नहीं है?",
|
||||
"Don't like the style": "शैली पसंद नहीं है",
|
||||
"Done": "",
|
||||
"Download": "डाउनलोड",
|
||||
"Download canceled": "डाउनलोड रद्द किया गया",
|
||||
"Download Database": "डेटाबेस डाउनलोड करें",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "मॉडल प्रबंधित करें",
|
||||
"Manage Ollama Models": "Ollama मॉडल प्रबंधित करें",
|
||||
"Manage Pipelines": "पाइपलाइनों का प्रबंधन करें",
|
||||
"Manage Valves": "",
|
||||
"March": "मार्च",
|
||||
"Max Tokens (num_predict)": "अधिकतम टोकन (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "अधिकतम 3 मॉडल एक साथ डाउनलोड किये जा सकते हैं। कृपया बाद में पुन: प्रयास करें।",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "सीड्\u200c",
|
||||
"Select a base model": "एक आधार मॉडल का चयन करें",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "एक मोड चुनें",
|
||||
"Select a model": "एक मॉडल चुनें",
|
||||
"Select a pipeline": "एक पाइपलाइन का चयन करें",
|
||||
"Select a pipeline url": "एक पाइपलाइन url चुनें",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "एक Ollama Instance चुनें",
|
||||
"Select Documents": "",
|
||||
"Select model": "मॉडल चुनें",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "शॉर्टकट दिखाएँ",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "रचनात्मकता का प्रदर्शन किया",
|
||||
"sidebar": "साइड बार",
|
||||
"Sign in": "साइन इन",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "उपयोगकर्ताओं",
|
||||
"Utilize": "उपयोग करें",
|
||||
"Valid time units:": "मान्य समय इकाइयाँ:",
|
||||
"Valves": "",
|
||||
"variable": "वेरिएबल",
|
||||
"variable to have them replaced with clipboard content.": "उन्हें क्लिपबोर्ड सामग्री से बदलने के लिए वेरिएबल।",
|
||||
"Version": "संस्करण",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Dopusti brisanje razgovora",
|
||||
"Allow non-local voices": "Dopusti nelokalne glasove",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alfanumerički znakovi i crtice",
|
||||
"Already have an account?": "Već imate račun?",
|
||||
"an assistant": "asistent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Izbrisano {{name}}",
|
||||
"Description": "Opis",
|
||||
"Didn't fully follow instructions": "Nije u potpunosti slijedio upute",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Otkrijte model",
|
||||
"Discover a prompt": "Otkrijte prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Otkrijte, preuzmite i istražite prilagođene prompte",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Otkrijte, preuzmite i istražite unaprijed postavljene modele",
|
||||
"Dismissible": "Odbaciti",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Ne dopuštaj",
|
||||
"Don't have an account?": "Nemate račun?",
|
||||
"Don't like the style": "Ne sviđa mi se stil",
|
||||
"Done": "",
|
||||
"Download": "Preuzimanje",
|
||||
"Download canceled": "Preuzimanje otkazano",
|
||||
"Download Database": "Preuzmi bazu podataka",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Upravljanje modelima",
|
||||
"Manage Ollama Models": "Upravljanje Ollama modelima",
|
||||
"Manage Pipelines": "Upravljanje cjevovodima",
|
||||
"Manage Valves": "",
|
||||
"March": "Ožujak",
|
||||
"Max Tokens (num_predict)": "Maksimalan broj tokena (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalno 3 modela se mogu preuzeti istovremeno. Pokušajte ponovo kasnije.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Sjeme",
|
||||
"Select a base model": "Odabir osnovnog modela",
|
||||
"Select a engine": "Odaberite pogon",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Odaberite način",
|
||||
"Select a model": "Odaberite model",
|
||||
"Select a pipeline": "Odabir kanala",
|
||||
"Select a pipeline url": "Odabir URL-a kanala",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Odaberite Ollama instancu",
|
||||
"Select Documents": "Odaberite dokumente",
|
||||
"Select model": "Odaberite model",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Pokaži prečace",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Prikazana kreativnost",
|
||||
"sidebar": "bočna traka",
|
||||
"Sign in": "Prijava",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Korisnici",
|
||||
"Utilize": "Iskoristi",
|
||||
"Valid time units:": "Važeće vremenske jedinice:",
|
||||
"Valves": "",
|
||||
"variable": "varijabla",
|
||||
"variable to have them replaced with clipboard content.": "varijabla za zamjenu sadržajem međuspremnika.",
|
||||
"Version": "Verzija",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Consenti l'eliminazione della chat",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caratteri alfanumerici e trattini",
|
||||
"Already have an account?": "Hai già un account?",
|
||||
"an assistant": "un assistente",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Eliminato {{name}}",
|
||||
"Description": "Descrizione",
|
||||
"Didn't fully follow instructions": "Non ha seguito completamente le istruzioni",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Scopri un modello",
|
||||
"Discover a prompt": "Scopri un prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Scopri, scarica ed esplora prompt personalizzati",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Scopri, scarica ed esplora i preset del modello",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Non consentire",
|
||||
"Don't have an account?": "Non hai un account?",
|
||||
"Don't like the style": "Non ti piace lo stile",
|
||||
"Done": "",
|
||||
"Download": "Scarica",
|
||||
"Download canceled": "Scaricamento annullato",
|
||||
"Download Database": "Scarica database",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Gestisci modelli",
|
||||
"Manage Ollama Models": "Gestisci modelli Ollama",
|
||||
"Manage Pipelines": "Gestire le pipeline",
|
||||
"Manage Valves": "",
|
||||
"March": "Marzo",
|
||||
"Max Tokens (num_predict)": "Numero massimo di gettoni (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "È possibile scaricare un massimo di 3 modelli contemporaneamente. Riprova più tardi.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Seme",
|
||||
"Select a base model": "Selezionare un modello di base",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Seleziona una modalità",
|
||||
"Select a model": "Seleziona un modello",
|
||||
"Select a pipeline": "Selezionare una tubazione",
|
||||
"Select a pipeline url": "Selezionare l'URL di una pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Seleziona un'istanza Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Seleziona modello",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Mostra",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Creatività messa in mostra",
|
||||
"sidebar": "barra laterale",
|
||||
"Sign in": "Accedi",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Utenti",
|
||||
"Utilize": "Utilizza",
|
||||
"Valid time units:": "Unità di tempo valide:",
|
||||
"Valves": "",
|
||||
"variable": "variabile",
|
||||
"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
|
||||
"Version": "Versione",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "チャットの削除を許可",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "英数字とハイフン",
|
||||
"Already have an account?": "すでにアカウントをお持ちですか?",
|
||||
"an assistant": "アシスタント",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}}を削除しました",
|
||||
"Description": "説明",
|
||||
"Didn't fully follow instructions": "説明に沿って操作していませんでした",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "モデルを検出する",
|
||||
"Discover a prompt": "プロンプトを見つける",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "許可しない",
|
||||
"Don't have an account?": "アカウントをお持ちではありませんか?",
|
||||
"Don't like the style": "デザインが好きでない",
|
||||
"Done": "",
|
||||
"Download": "ダウンロードをキャンセルしました",
|
||||
"Download canceled": "ダウンロードをキャンセルしました",
|
||||
"Download Database": "データベースをダウンロード",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "モデルを管理",
|
||||
"Manage Ollama Models": "Ollama モデルを管理",
|
||||
"Manage Pipelines": "パイプラインの管理",
|
||||
"Manage Valves": "",
|
||||
"March": "3月",
|
||||
"Max Tokens (num_predict)": "最大トークン数 (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "同時にダウンロードできるモデルは最大 3 つです。後でもう一度お試しください。",
|
||||
|
|
@ -458,10 +465,12 @@
|
|||
"Seed": "シード",
|
||||
"Select a base model": "基本モデルの選択",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "モードを選択",
|
||||
"Select a model": "モデルを選択",
|
||||
"Select a pipeline": "パイプラインの選択",
|
||||
"Select a pipeline url": "パイプラインの URL を選択する",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Ollama インスタンスを選択",
|
||||
"Select Documents": "",
|
||||
"Select model": "モデルを選択",
|
||||
|
|
@ -494,6 +503,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "表示",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "創造性を披露",
|
||||
"sidebar": "サイドバー",
|
||||
"Sign in": "サインイン",
|
||||
|
|
@ -582,6 +592,7 @@
|
|||
"Users": "ユーザー",
|
||||
"Utilize": "活用",
|
||||
"Valid time units:": "有効な時間単位:",
|
||||
"Valves": "",
|
||||
"variable": "変数",
|
||||
"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
|
||||
"Version": "バージョン",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "მიმოწერის წაშლის დაშვება",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "ალფანუმერული სიმბოლოები და დეფისები",
|
||||
"Already have an account?": "უკვე გაქვს ანგარიში?",
|
||||
"an assistant": "ასისტენტი",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Deleted {{name}}",
|
||||
"Description": "აღწერა",
|
||||
"Didn't fully follow instructions": "ვერ ყველა ინფორმაციისთვის ვერ ხელახლა ჩაწერე",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "გაიგეთ მოდელი",
|
||||
"Discover a prompt": "აღმოაჩინეთ მოთხოვნა",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მორგებული მოთხოვნები",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "აღმოაჩინეთ, ჩამოტვირთეთ და შეისწავლეთ მოდელის წინასწარ პარამეტრები",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "არ დაუშვა",
|
||||
"Don't have an account?": "არ გაქვს ანგარიში?",
|
||||
"Don't like the style": "არ ეთიკურია ფართოდ",
|
||||
"Done": "",
|
||||
"Download": "ჩამოტვირთვა გაუქმებულია",
|
||||
"Download canceled": "ჩამოტვირთვა გაუქმებულია",
|
||||
"Download Database": "გადმოწერე მონაცემთა ბაზა",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "მოდელების მართვა",
|
||||
"Manage Ollama Models": "Ollama მოდელების მართვა",
|
||||
"Manage Pipelines": "მილსადენების მართვა",
|
||||
"Manage Valves": "",
|
||||
"March": "მარტივი",
|
||||
"Max Tokens (num_predict)": "მაქს ტოკენსი (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "მაქსიმუმ 3 მოდელის ჩამოტვირთვა შესაძლებელია ერთდროულად. Გთხოვთ სცადოთ მოგვიანებით.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "სიდი",
|
||||
"Select a base model": "აირჩიეთ ბაზის მოდელი",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "რეჟიმის არჩევა",
|
||||
"Select a model": "მოდელის არჩევა",
|
||||
"Select a pipeline": "აირჩიეთ მილსადენი",
|
||||
"Select a pipeline url": "აირჩიეთ მილსადენის url",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Ollama ინსტანსის არჩევა",
|
||||
"Select Documents": "",
|
||||
"Select model": "მოდელის არჩევა",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "მალსახმობების ჩვენება",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "ჩვენებული ქონება",
|
||||
"sidebar": "საიდბარი",
|
||||
"Sign in": "ავტორიზაცია",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "მომხმარებლები",
|
||||
"Utilize": "გამოყენება",
|
||||
"Valid time units:": "მოქმედი დროის ერთეულები",
|
||||
"Valves": "",
|
||||
"variable": "ცვლადი",
|
||||
"variable to have them replaced with clipboard content.": "ცვლადი, რომ შეცვალოს ისინი ბუფერში შიგთავსით.",
|
||||
"Version": "ვერსია",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "채팅 삭제 허용",
|
||||
"Allow non-local voices": "외부 음성 허용",
|
||||
"Allow User Location": "사용자 위치 활용 허용",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "영문자, 숫자, 하이픈",
|
||||
"Already have an account?": "이미 계정이 있으신가요?",
|
||||
"an assistant": "어시스턴트",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}}을(를) 삭제했습니다.",
|
||||
"Description": "설명",
|
||||
"Didn't fully follow instructions": "완전히 지침을 따르지 않음",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "모델 검색",
|
||||
"Discover a prompt": "프롬프트 검색",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "사용자 정의 프롬프트 검색, 다운로드 및 탐색",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "모델 사전 설정 검색, 다운로드 및 탐색",
|
||||
"Dismissible": "제외가능",
|
||||
"Display Emoji in Call": "콜(call)에서 이모지 표시",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "허용 안 함",
|
||||
"Don't have an account?": "계정이 없으신가요?",
|
||||
"Don't like the style": "스타일을 좋아하지 않으세요?",
|
||||
"Done": "",
|
||||
"Download": "다운로드",
|
||||
"Download canceled": "다운로드 취소",
|
||||
"Download Database": "데이터베이스 다운로드",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "모델 관리",
|
||||
"Manage Ollama Models": "Ollama 모델 관리",
|
||||
"Manage Pipelines": "파이프라인 관리",
|
||||
"Manage Valves": "",
|
||||
"March": "3월",
|
||||
"Max Tokens (num_predict)": "최대 토큰(num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "최대 3개의 모델을 동시에 다운로드할 수 있습니다. 나중에 다시 시도하세요.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "시드",
|
||||
"Select a base model": "기본 모델 선택",
|
||||
"Select a engine": "엔진 선택",
|
||||
"Select a function": "",
|
||||
"Select a mode": "모드 선택",
|
||||
"Select a model": "모델 선택",
|
||||
"Select a pipeline": "파이프라인 선택",
|
||||
"Select a pipeline url": "파이프라인 URL 선택",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Ollama 인스턴스 선택",
|
||||
"Select Documents": "문서 선택",
|
||||
"Select model": "모델 선택",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "사용자용 계정 보류 설명창에, 관리자 상세 정보 노출",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "단축키 보기",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "창의성 발휘",
|
||||
"sidebar": "사이드바",
|
||||
"Sign in": "로그인",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "사용자",
|
||||
"Utilize": "활용",
|
||||
"Valid time units:": "유효 시간 단위:",
|
||||
"Valves": "",
|
||||
"variable": "변수",
|
||||
"variable to have them replaced with clipboard content.": "변수를 사용하여 클립보드 내용으로 바꾸세요.",
|
||||
"Version": "버전",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Leisti pokalbių ištrynimą",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "skaičiai, raidės ir brūkšneliai",
|
||||
"Already have an account?": "Ar jau turite paskyrą?",
|
||||
"an assistant": "assistentas",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "Aprašymas",
|
||||
"Didn't fully follow instructions": "Pilnai nesekė instrukcijų",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "Atrasti užklausas",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Atrasti ir parsisiųsti užklausas",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Atrasti ir parsisiųsti modelių konfigūracija",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Neleisti",
|
||||
"Don't have an account?": "Neturite paskyros?",
|
||||
"Don't like the style": "Nepatinka stilius",
|
||||
"Done": "",
|
||||
"Download": "Parsisiųsti",
|
||||
"Download canceled": "Parsisiuntimas atšauktas",
|
||||
"Download Database": "Parsisiųsti duomenų bazę",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Tvarkyti modelius",
|
||||
"Manage Ollama Models": "Tvarkyti Ollama modelius",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "Kovas",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Daugiausiai trys modeliai gali būti parsisiunčiami vienu metu.",
|
||||
|
|
@ -461,10 +468,12 @@
|
|||
"Seed": "Sėkla",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Pasirinkti režimą",
|
||||
"Select a model": "Pasirinkti modelį",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Pasirinkti Ollama instanciją",
|
||||
"Select Documents": "",
|
||||
"Select model": "Pasirinkti modelį",
|
||||
|
|
@ -497,6 +506,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Rodyti trumpinius",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Kūrybingų užklausų paroda",
|
||||
"sidebar": "šoninis meniu",
|
||||
"Sign in": "Prisijungti",
|
||||
|
|
@ -585,6 +595,7 @@
|
|||
"Users": "Naudotojai",
|
||||
"Utilize": "Naudoti",
|
||||
"Valid time units:": "Teisingūs laiko vienetai :",
|
||||
"Valves": "",
|
||||
"variable": "kintamasis",
|
||||
"variable to have them replaced with clipboard content.": "kintamoji pakeičiama kopijuoklės turiniu.",
|
||||
"Version": "Versija",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Tillat sletting av chatter",
|
||||
"Allow non-local voices": "Tillat ikke-lokale stemmer",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alfanumeriske tegn og bindestreker",
|
||||
"Already have an account?": "Har du allerede en konto?",
|
||||
"an assistant": "en assistent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Slettet {{name}}",
|
||||
"Description": "Beskrivelse",
|
||||
"Didn't fully follow instructions": "Fulgte ikke instruksjonene fullt ut",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Oppdag en modell",
|
||||
"Discover a prompt": "Oppdag en prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Oppdag, last ned og utforsk egendefinerte prompts",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Oppdag, last ned og utforsk modellforhåndsinnstillinger",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Ikke tillat",
|
||||
"Don't have an account?": "Har du ikke en konto?",
|
||||
"Don't like the style": "Liker ikke stilen",
|
||||
"Done": "",
|
||||
"Download": "Last ned",
|
||||
"Download canceled": "Nedlasting avbrutt",
|
||||
"Download Database": "Last ned database",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Administrer modeller",
|
||||
"Manage Ollama Models": "Administrer Ollama-modeller",
|
||||
"Manage Pipelines": "Administrer pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Mars",
|
||||
"Max Tokens (num_predict)": "Maks antall tokens (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksimalt 3 modeller kan lastes ned samtidig. Vennligst prøv igjen senere.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Velg en grunnmodell",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Velg en modus",
|
||||
"Select a model": "Velg en modell",
|
||||
"Select a pipeline": "Velg en pipeline",
|
||||
"Select a pipeline url": "Velg en pipeline-URL",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Velg en Ollama-instans",
|
||||
"Select Documents": "",
|
||||
"Select model": "Velg modell",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Vis administratordetaljer i ventende kontooverlay",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Vis snarveier",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Vist frem kreativitet",
|
||||
"sidebar": "sidefelt",
|
||||
"Sign in": "Logg inn",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Brukere",
|
||||
"Utilize": "Utnytt",
|
||||
"Valid time units:": "Gyldige tidsenheter:",
|
||||
"Valves": "",
|
||||
"variable": "variabel",
|
||||
"variable to have them replaced with clipboard content.": "variabel for å få dem erstattet med utklippstavleinnhold.",
|
||||
"Version": "Versjon",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Sta Chat Verwijdering toe",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alfanumerieke karakters en streepjes",
|
||||
"Already have an account?": "Heb je al een account?",
|
||||
"an assistant": "een assistent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}} verwijderd",
|
||||
"Description": "Beschrijving",
|
||||
"Didn't fully follow instructions": "Ik heb niet alle instructies volgt",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Ontdek een model",
|
||||
"Discover a prompt": "Ontdek een prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Ontdek, download en verken aangepaste prompts",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Ontdek, download en verken model presets",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Niet Toestaan",
|
||||
"Don't have an account?": "Heb je geen account?",
|
||||
"Don't like the style": "Je vindt het stijl niet?",
|
||||
"Done": "",
|
||||
"Download": "Download",
|
||||
"Download canceled": "Download geannuleerd",
|
||||
"Download Database": "Download Database",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Beheer Modellen",
|
||||
"Manage Ollama Models": "Beheer Ollama Modellen",
|
||||
"Manage Pipelines": "Pijplijnen beheren",
|
||||
"Manage Valves": "",
|
||||
"March": "Maart",
|
||||
"Max Tokens (num_predict)": "Max Tokens (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maximaal 3 modellen kunnen tegelijkertijd worden gedownload. Probeer het later opnieuw.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Selecteer een basismodel",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Selecteer een modus",
|
||||
"Select a model": "Selecteer een model",
|
||||
"Select a pipeline": "Selecteer een pijplijn",
|
||||
"Select a pipeline url": "Selecteer een pijplijn-URL",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Selecteer een Ollama instantie",
|
||||
"Select Documents": "",
|
||||
"Select model": "Selecteer een model",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Toon snelkoppelingen",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Tooncase creativiteit",
|
||||
"sidebar": "sidebar",
|
||||
"Sign in": "Inloggen",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Gebruikers",
|
||||
"Utilize": "Utilize",
|
||||
"Valid time units:": "Geldige tijdseenheden:",
|
||||
"Valves": "",
|
||||
"variable": "variabele",
|
||||
"variable to have them replaced with clipboard content.": "variabele om ze te laten vervangen door klembord inhoud.",
|
||||
"Version": "Versie",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "ਗੱਲਬਾਤ ਮਿਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "ਅਲਫ਼ਾਨਯੂਮੈਰਿਕ ਅੱਖਰ ਅਤੇ ਹਾਈਫਨ",
|
||||
"Already have an account?": "ਪਹਿਲਾਂ ਹੀ ਖਾਤਾ ਹੈ?",
|
||||
"an assistant": "ਇੱਕ ਸਹਾਇਕ",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "ਮਿਟਾ ਦਿੱਤਾ ਗਿਆ {{name}}",
|
||||
"Description": "ਵਰਣਨਾ",
|
||||
"Didn't fully follow instructions": "ਹਦਾਇਤਾਂ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਫਾਲੋ ਨਹੀਂ ਕੀਤਾ",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "ਇੱਕ ਮਾਡਲ ਲੱਭੋ",
|
||||
"Discover a prompt": "ਇੱਕ ਪ੍ਰੰਪਟ ਖੋਜੋ",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "ਕਸਟਮ ਪ੍ਰੰਪਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "ਮਾਡਲ ਪ੍ਰੀਸੈਟਾਂ ਨੂੰ ਖੋਜੋ, ਡਾਊਨਲੋਡ ਕਰੋ ਅਤੇ ਪੜਚੋਲ ਕਰੋ",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "ਆਗਿਆ ਨਾ ਦਿਓ",
|
||||
"Don't have an account?": "ਖਾਤਾ ਨਹੀਂ ਹੈ?",
|
||||
"Don't like the style": "ਸਟਾਈਲ ਪਸੰਦ ਨਹੀਂ ਹੈ",
|
||||
"Done": "",
|
||||
"Download": "ਡਾਊਨਲੋਡ",
|
||||
"Download canceled": "ਡਾਊਨਲੋਡ ਰੱਦ ਕੀਤਾ ਗਿਆ",
|
||||
"Download Database": "ਡਾਟਾਬੇਸ ਡਾਊਨਲੋਡ ਕਰੋ",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
|
||||
"Manage Ollama Models": "ਓਲਾਮਾ ਮਾਡਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
|
||||
"Manage Pipelines": "ਪਾਈਪਲਾਈਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ",
|
||||
"Manage Valves": "",
|
||||
"March": "ਮਾਰਚ",
|
||||
"Max Tokens (num_predict)": "ਮੈਕਸ ਟੋਕਨ (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "ਇੱਕ ਸਮੇਂ ਵਿੱਚ ਵੱਧ ਤੋਂ ਵੱਧ 3 ਮਾਡਲ ਡਾਊਨਲੋਡ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ। ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "ਬੀਜ",
|
||||
"Select a base model": "ਆਧਾਰ ਮਾਡਲ ਚੁਣੋ",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "ਇੱਕ ਮੋਡ ਚੁਣੋ",
|
||||
"Select a model": "ਇੱਕ ਮਾਡਲ ਚੁਣੋ",
|
||||
"Select a pipeline": "ਪਾਈਪਲਾਈਨ ਚੁਣੋ",
|
||||
"Select a pipeline url": "ਪਾਈਪਲਾਈਨ URL ਚੁਣੋ",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "ਇੱਕ ਓਲਾਮਾ ਇੰਸਟੈਂਸ ਚੁਣੋ",
|
||||
"Select Documents": "",
|
||||
"Select model": "ਮਾਡਲ ਚੁਣੋ",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "ਸ਼ਾਰਟਕਟ ਦਿਖਾਓ",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "ਸਿਰਜਣਾਤਮਕਤਾ ਦਿਖਾਈ",
|
||||
"sidebar": "ਸਾਈਡਬਾਰ",
|
||||
"Sign in": "ਸਾਈਨ ਇਨ ਕਰੋ",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "ਉਪਭੋਗਤਾ",
|
||||
"Utilize": "ਵਰਤੋਂ",
|
||||
"Valid time units:": "ਵੈਧ ਸਮਾਂ ਇਕਾਈਆਂ:",
|
||||
"Valves": "",
|
||||
"variable": "ਵੈਰੀਏਬਲ",
|
||||
"variable to have them replaced with clipboard content.": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਨਾਲ ਬਦਲਣ ਲਈ ਵੈਰੀਏਬਲ।",
|
||||
"Version": "ਵਰਜਨ",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Pozwól na usuwanie czatu",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "znaki alfanumeryczne i myślniki",
|
||||
"Already have an account?": "Masz już konto?",
|
||||
"an assistant": "asystent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Usunięto {{name}}",
|
||||
"Description": "Opis",
|
||||
"Didn't fully follow instructions": "Nie postępował zgodnie z instrukcjami",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Odkryj model",
|
||||
"Discover a prompt": "Odkryj prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Odkryj, pobierz i eksploruj niestandardowe prompty",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Odkryj, pobierz i eksploruj ustawienia modeli",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Nie zezwalaj",
|
||||
"Don't have an account?": "Nie masz konta?",
|
||||
"Don't like the style": "Nie podobał mi się styl",
|
||||
"Done": "",
|
||||
"Download": "Pobieranie",
|
||||
"Download canceled": "Pobieranie przerwane",
|
||||
"Download Database": "Pobierz bazę danych",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Zarządzaj modelami",
|
||||
"Manage Ollama Models": "Zarządzaj modelami Ollama",
|
||||
"Manage Pipelines": "Zarządzanie potokami",
|
||||
"Manage Valves": "",
|
||||
"March": "Marzec",
|
||||
"Max Tokens (num_predict)": "Maksymalna liczba żetonów (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Maksymalnie 3 modele można pobierać jednocześnie. Spróbuj ponownie później.",
|
||||
|
|
@ -461,10 +468,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Wybieranie modelu bazowego",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Wybierz tryb",
|
||||
"Select a model": "Wybierz model",
|
||||
"Select a pipeline": "Wybieranie potoku",
|
||||
"Select a pipeline url": "Wybieranie adresu URL potoku",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Wybierz instancję Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Wybierz model",
|
||||
|
|
@ -497,6 +506,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Pokaż skróty",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Pokaz kreatywności",
|
||||
"sidebar": "Panel boczny",
|
||||
"Sign in": "Zaloguj się",
|
||||
|
|
@ -585,6 +595,7 @@
|
|||
"Users": "Użytkownicy",
|
||||
"Utilize": "Wykorzystaj",
|
||||
"Valid time units:": "Poprawne jednostki czasu:",
|
||||
"Valves": "",
|
||||
"variable": "zmienna",
|
||||
"variable to have them replaced with clipboard content.": "zmienna która zostanie zastąpiona zawartością schowka.",
|
||||
"Version": "Wersja",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Permitir Exclusão de Bate-papo",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
|
||||
"Already have an account?": "Já tem uma conta?",
|
||||
"an assistant": "um assistente",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Excluído {{nome}}",
|
||||
"Description": "Descrição",
|
||||
"Didn't fully follow instructions": "Não seguiu instruções com precisão",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Descubra um modelo",
|
||||
"Discover a prompt": "Descobrir um prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Descubra, baixe e explore prompts personalizados",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Descubra, baixe e explore predefinições de modelo",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Não Permitir",
|
||||
"Don't have an account?": "Não tem uma conta?",
|
||||
"Don't like the style": "Não gosta do estilo",
|
||||
"Done": "",
|
||||
"Download": "Baixar",
|
||||
"Download canceled": "Download cancelado",
|
||||
"Download Database": "Baixar Banco de Dados",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Gerenciar Modelos",
|
||||
"Manage Ollama Models": "Gerenciar Modelos Ollama",
|
||||
"Manage Pipelines": "Gerenciar pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Março",
|
||||
"Max Tokens (num_predict)": "Fichas máximas (num_predict)",
|
||||
"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.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Semente",
|
||||
"Select a base model": "Selecione um modelo base",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Selecione um modo",
|
||||
"Select a model": "Selecione um modelo",
|
||||
"Select a pipeline": "Selecione um pipeline",
|
||||
"Select a pipeline url": "Selecione uma URL de pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Selecione uma instância Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Selecione um modelo",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Mostrar",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Criatividade Exibida",
|
||||
"sidebar": "barra lateral",
|
||||
"Sign in": "Entrar",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Usuários",
|
||||
"Utilize": "Utilizar",
|
||||
"Valid time units:": "Unidades de tempo válidas:",
|
||||
"Valves": "",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Permitir Exclusão de Conversa",
|
||||
"Allow non-local voices": "Permitir vozes não locais",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "caracteres alfanuméricos e hífens",
|
||||
"Already have an account?": "Já tem uma conta?",
|
||||
"an assistant": "um assistente",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Apagado {{name}}",
|
||||
"Description": "Descrição",
|
||||
"Didn't fully follow instructions": "Não seguiu instruções com precisão",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Descubra um modelo",
|
||||
"Discover a prompt": "Descobrir um prompt",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Descubra, descarregue e explore prompts personalizados",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Descubra, descarregue e explore predefinições de modelo",
|
||||
"Dismissible": "Dispensável",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Não Permitir",
|
||||
"Don't have an account?": "Não tem uma conta?",
|
||||
"Don't like the style": "Não gosta do estilo",
|
||||
"Done": "",
|
||||
"Download": "Descarregar",
|
||||
"Download canceled": "Download cancelado",
|
||||
"Download Database": "Descarregar Base de Dados",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Gerir Modelos",
|
||||
"Manage Ollama Models": "Gerir Modelos Ollama",
|
||||
"Manage Pipelines": "Gerir pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Março",
|
||||
"Max Tokens (num_predict)": "Máx Tokens (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "O máximo de 3 modelos podem ser descarregados simultaneamente. Tente novamente mais tarde.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Semente",
|
||||
"Select a base model": "Selecione um modelo base",
|
||||
"Select a engine": "Selecione um motor",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Selecione um modo",
|
||||
"Select a model": "Selecione um modelo",
|
||||
"Select a pipeline": "Selecione um pipeline",
|
||||
"Select a pipeline url": "Selecione um URL de pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Selecione uma instância Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Selecione o modelo",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Mostrar Detalhes do Administrador na sobreposição de Conta Pendente",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Mostrar atalhos",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Criatividade Exibida",
|
||||
"sidebar": "barra lateral",
|
||||
"Sign in": "Entrar",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Utilizadores",
|
||||
"Utilize": "Utilizar",
|
||||
"Valid time units:": "Unidades de tempo válidas:",
|
||||
"Valves": "",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Дозволять удаление чат",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "буквенно цифровые символы и дефисы",
|
||||
"Already have an account?": "у вас уже есть аккаунт?",
|
||||
"an assistant": "ассистент",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Удалено {{name}}",
|
||||
"Description": "Описание",
|
||||
"Didn't fully follow instructions": "Не полностью следул инструкциям",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Откройте для себя модель",
|
||||
"Discover a prompt": "Найти промт",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Находите, загружайте и исследуйте настраиваемые промты",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Находите, загружайте и исследуйте предустановки модели",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Не разрешать",
|
||||
"Don't have an account?": "у вас не есть аккаунт?",
|
||||
"Don't like the style": "Не нравится стиль",
|
||||
"Done": "",
|
||||
"Download": "Загрузить",
|
||||
"Download canceled": "Загрузка отменена",
|
||||
"Download Database": "Загрузить базу данных",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Управление моделями",
|
||||
"Manage Ollama Models": "Управление моделями Ollama",
|
||||
"Manage Pipelines": "Управление конвейерами",
|
||||
"Manage Valves": "",
|
||||
"March": "Март",
|
||||
"Max Tokens (num_predict)": "Максимальное количество жетонов (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимальное количество моделей для загрузки одновременно - 3. Пожалуйста, попробуйте позже.",
|
||||
|
|
@ -461,10 +468,12 @@
|
|||
"Seed": "Сид",
|
||||
"Select a base model": "Выбор базовой модели",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Выберите режим",
|
||||
"Select a model": "Выберите модель",
|
||||
"Select a pipeline": "Выбор конвейера",
|
||||
"Select a pipeline url": "Выберите URL-адрес конвейера",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Выберите экземпляр Ollama",
|
||||
"Select Documents": "",
|
||||
"Select model": "Выберите модель",
|
||||
|
|
@ -497,6 +506,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Показать клавиатурные сокращения",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Показать творчество",
|
||||
"sidebar": "боковая панель",
|
||||
"Sign in": "Войти",
|
||||
|
|
@ -585,6 +595,7 @@
|
|||
"Users": "Пользователи",
|
||||
"Utilize": "Использовать",
|
||||
"Valid time units:": "Допустимые единицы времени:",
|
||||
"Valves": "",
|
||||
"variable": "переменная",
|
||||
"variable to have them replaced with clipboard content.": "переменная, чтобы их заменить содержимым буфера обмена.",
|
||||
"Version": "Версия",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Дозволи брисање ћаскања",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "алфанумерички знакови и цртице",
|
||||
"Already have an account?": "Већ имате налог?",
|
||||
"an assistant": "помоћник",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Избрисано {{наме}}",
|
||||
"Description": "Опис",
|
||||
"Didn't fully follow instructions": "Упутства нису праћена у потпуности",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Откријте модел",
|
||||
"Discover a prompt": "Откриј упит",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Откријте, преузмите и истражите прилагођене упите",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Откријте, преузмите и истражите образце модела",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Не дозволи",
|
||||
"Don't have an account?": "Немате налог?",
|
||||
"Don't like the style": "Не свиђа ми се стил",
|
||||
"Done": "",
|
||||
"Download": "Преузми",
|
||||
"Download canceled": "Преузимање отказано",
|
||||
"Download Database": "Преузми базу података",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Управљај моделима",
|
||||
"Manage Ollama Models": "Управљај Ollama моделима",
|
||||
"Manage Pipelines": "Управљање цевоводима",
|
||||
"Manage Valves": "",
|
||||
"March": "Март",
|
||||
"Max Tokens (num_predict)": "Маx Токенс (нум_предицт)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Највише 3 модела могу бити преузета истовремено. Покушајте поново касније.",
|
||||
|
|
@ -460,10 +467,12 @@
|
|||
"Seed": "Семе",
|
||||
"Select a base model": "Избор основног модела",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Изабери режим",
|
||||
"Select a model": "Изабери модел",
|
||||
"Select a pipeline": "Избор цевовода",
|
||||
"Select a pipeline url": "Избор урл адресе цевовода",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Изабери Ollama инстанцу",
|
||||
"Select Documents": "",
|
||||
"Select model": "Изабери модел",
|
||||
|
|
@ -496,6 +505,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Прикажи пречице",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Приказана креативност",
|
||||
"sidebar": "бочна трака",
|
||||
"Sign in": "Пријави се",
|
||||
|
|
@ -584,6 +594,7 @@
|
|||
"Users": "Корисници",
|
||||
"Utilize": "Искористи",
|
||||
"Valid time units:": "Важеће временске јединице:",
|
||||
"Valves": "",
|
||||
"variable": "променљива",
|
||||
"variable to have them replaced with clipboard content.": "променљива за замену са садржајем оставе.",
|
||||
"Version": "Издање",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Tillåt chattborttagning",
|
||||
"Allow non-local voices": "Tillåt icke-lokala röster",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alfanumeriska tecken och bindestreck",
|
||||
"Already have an account?": "Har du redan ett konto?",
|
||||
"an assistant": "en assistent",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Borttagen {{name}}",
|
||||
"Description": "Beskrivning",
|
||||
"Didn't fully follow instructions": "Följde inte instruktionerna",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Upptäck en modell",
|
||||
"Discover a prompt": "Upptäck en instruktion",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Upptäck, ladda ner och utforska anpassade instruktioner",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Upptäck, ladda ner och utforska modellförinställningar",
|
||||
"Dismissible": "Kan stängas",
|
||||
"Display Emoji in Call": "Visa Emoji under samtal",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Tillåt inte",
|
||||
"Don't have an account?": "Har du inget konto?",
|
||||
"Don't like the style": "Tycker inte om utseendet",
|
||||
"Done": "",
|
||||
"Download": "Ladda ner",
|
||||
"Download canceled": "Nedladdning avbruten",
|
||||
"Download Database": "Ladda ner databas",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Hantera modeller",
|
||||
"Manage Ollama Models": "Hantera Ollama-modeller",
|
||||
"Manage Pipelines": "Hantera rörledningar",
|
||||
"Manage Valves": "",
|
||||
"March": "mars",
|
||||
"Max Tokens (num_predict)": "Maximalt antal tokens (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Högst 3 modeller kan laddas ner samtidigt. Vänligen försök igen senare.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Välj en basmodell",
|
||||
"Select a engine": "Välj en motor",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Välj ett läge",
|
||||
"Select a model": "Välj en modell",
|
||||
"Select a pipeline": "Välj en rörledning",
|
||||
"Select a pipeline url": "Välj en URL för rörledningen",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Välj en Ollama-instans",
|
||||
"Select Documents": "Välj dokument",
|
||||
"Select model": "Välj en modell",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Visa administratörsinformation till väntande konton",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Visa genvägar",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Visade kreativitet",
|
||||
"sidebar": "sidofält",
|
||||
"Sign in": "Logga in",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Användare",
|
||||
"Utilize": "Använd",
|
||||
"Valid time units:": "Giltiga tidsenheter:",
|
||||
"Valves": "",
|
||||
"variable": "variabel",
|
||||
"variable to have them replaced with clipboard content.": "variabel för att få dem ersatta med urklippsinnehåll.",
|
||||
"Version": "Version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "",
|
||||
"Already have an account?": "",
|
||||
"an assistant": "",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "",
|
||||
"Description": "",
|
||||
"Didn't fully follow instructions": "",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "",
|
||||
"Discover a prompt": "",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "",
|
||||
"Don't have an account?": "",
|
||||
"Don't like the style": "",
|
||||
"Done": "",
|
||||
"Download": "",
|
||||
"Download canceled": "",
|
||||
"Download Database": "",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "",
|
||||
"Manage Ollama Models": "",
|
||||
"Manage Pipelines": "",
|
||||
"Manage Valves": "",
|
||||
"March": "",
|
||||
"Max Tokens (num_predict)": "",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "",
|
||||
"Select a base model": "",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "",
|
||||
"Select a model": "",
|
||||
"Select a pipeline": "",
|
||||
"Select a pipeline url": "",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "",
|
||||
"Select Documents": "",
|
||||
"Select model": "",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "",
|
||||
"sidebar": "",
|
||||
"Sign in": "",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "",
|
||||
"Utilize": "",
|
||||
"Valid time units:": "",
|
||||
"Valves": "",
|
||||
"variable": "",
|
||||
"variable to have them replaced with clipboard content.": "",
|
||||
"Version": "",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Sohbet Silmeye İzin Ver",
|
||||
"Allow non-local voices": "Yerel olmayan seslere izin verin",
|
||||
"Allow User Location": "",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "alfanumerik karakterler ve tireler",
|
||||
"Already have an account?": "Zaten bir hesabınız mı var?",
|
||||
"an assistant": "bir asistan",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "{{name}} silindi",
|
||||
"Description": "Açıklama",
|
||||
"Didn't fully follow instructions": "Talimatları tam olarak takip etmedi",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Bir model keşfedin",
|
||||
"Discover a prompt": "Bir prompt keşfedin",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Özel promptları keşfedin, indirin ve inceleyin",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Model ön ayarlarını keşfedin, indirin ve inceleyin",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "İzin Verme",
|
||||
"Don't have an account?": "Hesabınız yok mu?",
|
||||
"Don't like the style": "Tarzını beğenmedim",
|
||||
"Done": "",
|
||||
"Download": "İndir",
|
||||
"Download canceled": "İndirme iptal edildi",
|
||||
"Download Database": "Veritabanını İndir",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Modelleri Yönet",
|
||||
"Manage Ollama Models": "Ollama Modellerini Yönet",
|
||||
"Manage Pipelines": "Pipeline'ları Yönet",
|
||||
"Manage Valves": "",
|
||||
"March": "Mart",
|
||||
"Max Tokens (num_predict)": "Maksimum Token (num_predict)",
|
||||
"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.",
|
||||
|
|
@ -459,10 +466,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Bir temel model seç",
|
||||
"Select a engine": "",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Bir mod seç",
|
||||
"Select a model": "Bir model seç",
|
||||
"Select a pipeline": "Bir pipeline seç",
|
||||
"Select a pipeline url": "Bir pipeline URL'si seç",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Bir Ollama örneği seçin",
|
||||
"Select Documents": "",
|
||||
"Select model": "Model seç",
|
||||
|
|
@ -495,6 +504,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show shortcuts": "Kısayolları göster",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Sergilenen yaratıcılık",
|
||||
"sidebar": "kenar çubuğu",
|
||||
"Sign in": "Oturum aç",
|
||||
|
|
@ -583,6 +593,7 @@
|
|||
"Users": "Kullanıcılar",
|
||||
"Utilize": "Kullan",
|
||||
"Valid time units:": "Geçerli zaman birimleri:",
|
||||
"Valves": "",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Дозволити видалення чату",
|
||||
"Allow non-local voices": "Дозволити не локальні голоси",
|
||||
"Allow User Location": "Доступ до місцезнаходження",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "алфавітно-цифрові символи та дефіси",
|
||||
"Already have an account?": "Вже є обліковий запис?",
|
||||
"an assistant": "асистента",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Видалено {{name}}",
|
||||
"Description": "Опис",
|
||||
"Didn't fully follow instructions": "Не повністю дотримувалися інструкцій",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Знайдіть модель",
|
||||
"Discover a prompt": "Знайти промт",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "Знайдіть, завантажте та досліджуйте налаштовані промти",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "Знайдіть, завантажте та досліджуйте налаштовані налаштування моделі",
|
||||
"Dismissible": "Неприйнятно",
|
||||
"Display Emoji in Call": "Відображати емодзі у викликах",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Не дозволяти",
|
||||
"Don't have an account?": "Немає облікового запису?",
|
||||
"Don't like the style": "Не подобається стиль",
|
||||
"Done": "",
|
||||
"Download": "Завантажити",
|
||||
"Download canceled": "Завантаження скасовано",
|
||||
"Download Database": "Завантажити базу даних",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Керування моделями",
|
||||
"Manage Ollama Models": "Керування моделями Ollama",
|
||||
"Manage Pipelines": "Управління Pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Березень",
|
||||
"Max Tokens (num_predict)": "Макс токенів (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Максимум 3 моделі можна завантажити одночасно. Будь ласка, спробуйте пізніше.",
|
||||
|
|
@ -461,10 +468,12 @@
|
|||
"Seed": "Сід",
|
||||
"Select a base model": "Вибрати базову модель",
|
||||
"Select a engine": "Виберіть рушій",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Оберіть режим",
|
||||
"Select a model": "Виберіть модель",
|
||||
"Select a pipeline": "Виберіть pipeline",
|
||||
"Select a pipeline url": "Виберіть адресу pipeline",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Виберіть екземпляр Ollama",
|
||||
"Select Documents": "Виберіть документи",
|
||||
"Select model": "Вибрати модель",
|
||||
|
|
@ -497,6 +506,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Відобразити дані адміна у вікні очікування облікового запису",
|
||||
"Show Model": "Показати модель",
|
||||
"Show shortcuts": "Показати клавіатурні скорочення",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Продемонстрований креатив",
|
||||
"sidebar": "бокова панель",
|
||||
"Sign in": "Увійти",
|
||||
|
|
@ -585,6 +595,7 @@
|
|||
"Users": "Користувачі",
|
||||
"Utilize": "Використовувати",
|
||||
"Valid time units:": "Дійсні одиниці часу:",
|
||||
"Valves": "",
|
||||
"variable": "змінна",
|
||||
"variable to have them replaced with clipboard content.": "змінна, щоб замінити їх вмістом буфера обміну.",
|
||||
"Version": "Версія",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "Cho phép Xóa nội dung chat",
|
||||
"Allow non-local voices": "Cho phép giọng nói không bản xứ",
|
||||
"Allow User Location": "Cho phép sử dụng vị trí người dùng",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "ký tự số và gạch nối",
|
||||
"Already have an account?": "Bạn đã có tài khoản?",
|
||||
"an assistant": "trợ lý",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "Đã xóa {{name}}",
|
||||
"Description": "Mô tả",
|
||||
"Didn't fully follow instructions": "Không tuân theo chỉ dẫn một cách đầy đủ",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "Khám phá model",
|
||||
"Discover a prompt": "Khám phá thêm prompt mới",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"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 tools": "",
|
||||
"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",
|
||||
"Dismissible": "Có thể loại bỏ",
|
||||
"Display Emoji in Call": "Hiển thị Emoji trong cuộc gọi",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "Không Cho phép",
|
||||
"Don't have an account?": "Không có tài khoản?",
|
||||
"Don't like the style": "Không thích phong cách trả lời",
|
||||
"Done": "",
|
||||
"Download": "Tải về",
|
||||
"Download canceled": "Đã hủy download",
|
||||
"Download Database": "Tải xuống Cơ sở dữ liệu",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "Quản lý mô hình",
|
||||
"Manage Ollama Models": "Quản lý mô hình với Ollama",
|
||||
"Manage Pipelines": "Quản lý Pipelines",
|
||||
"Manage Valves": "",
|
||||
"March": "Tháng 3",
|
||||
"Max Tokens (num_predict)": "Tokens tối đa (num_predict)",
|
||||
"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.",
|
||||
|
|
@ -458,10 +465,12 @@
|
|||
"Seed": "Seed",
|
||||
"Select a base model": "Chọn một base model",
|
||||
"Select a engine": "Chọn dịch vụ",
|
||||
"Select a function": "",
|
||||
"Select a mode": "Chọn một chế độ",
|
||||
"Select a model": "Chọn mô hình",
|
||||
"Select a pipeline": "Chọn một quy trình",
|
||||
"Select a pipeline url": "Chọn url quy trình",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "Chọn một thực thể Ollama",
|
||||
"Select Documents": "Chọn tài liệu",
|
||||
"Select model": "Chọn model",
|
||||
|
|
@ -494,6 +503,7 @@
|
|||
"Show Admin Details in Account Pending Overlay": "Hiển thị thông tin của Quản trị viên trên màn hình hiển thị Tài khoản đang chờ xử lý",
|
||||
"Show Model": "Hiện mô hình",
|
||||
"Show shortcuts": "Hiển thị phím tắt",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "Thể hiện sự sáng tạo",
|
||||
"sidebar": "thanh bên",
|
||||
"Sign in": "Đăng nhập",
|
||||
|
|
@ -582,6 +592,7 @@
|
|||
"Users": "Người sử dụng",
|
||||
"Utilize": "Sử dụng",
|
||||
"Valid time units:": "Đơn vị thời gian hợp lệ:",
|
||||
"Valves": "",
|
||||
"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.",
|
||||
"Version": "Version",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"Allow Chat Deletion": "允许删除聊天记录",
|
||||
"Allow non-local voices": "允许调用非本地音色",
|
||||
"Allow User Location": "允许获取您的位置",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "字母数字字符和连字符",
|
||||
"Already have an account?": "已经拥有账号了?",
|
||||
"an assistant": "助手",
|
||||
|
|
@ -99,7 +100,7 @@
|
|||
"Clear memory": "清除记忆",
|
||||
"Click here for help.": "点击这里获取帮助。",
|
||||
"Click here to": "单击",
|
||||
"Click here to download user import template file.": "",
|
||||
"Click here to download user import template file.": "单击此处下载用户导入所需的模板文件。",
|
||||
"Click here to select": "点击这里选择",
|
||||
"Click here to select a csv file.": "单击此处选择 csv 文件。",
|
||||
"Click here to select a py file.": "单击此处选择 py 文件。",
|
||||
|
|
@ -135,8 +136,8 @@
|
|||
"Create new secret key": "创建新安全密钥",
|
||||
"Created at": "创建于",
|
||||
"Created At": "创建于",
|
||||
"Created by": "",
|
||||
"CSV Import": "",
|
||||
"Created by": "作者",
|
||||
"CSV Import": "通过 CSV 文件导入",
|
||||
"Current Model": "当前模型",
|
||||
"Current Password": "当前密码",
|
||||
"Custom": "自定义",
|
||||
|
|
@ -165,9 +166,13 @@
|
|||
"Deleted {{name}}": "已删除 {{name}}",
|
||||
"Description": "描述",
|
||||
"Didn't fully follow instructions": "没有完全遵照指示",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "发现更多模型",
|
||||
"Discover a prompt": "发现更多提示词",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "发现、下载并探索更多自定义提示词",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "发现、下载并探索更多模型预设",
|
||||
"Dismissible": "是否可关闭",
|
||||
"Display Emoji in Call": "在通话中显示 Emoji 表情符号",
|
||||
|
|
@ -180,6 +185,7 @@
|
|||
"Don't Allow": "不允许",
|
||||
"Don't have an account?": "没有账号?",
|
||||
"Don't like the style": "不喜欢这个文风",
|
||||
"Done": "",
|
||||
"Download": "下载",
|
||||
"Download canceled": "下载已取消",
|
||||
"Download Database": "下载数据库",
|
||||
|
|
@ -250,7 +256,7 @@
|
|||
"Fluidly stream large external response chunks": "流畅地传输外部大型响应块数据",
|
||||
"Focus chat input": "聚焦对话输入",
|
||||
"Followed instructions perfectly": "完全按照指示执行",
|
||||
"Form": "",
|
||||
"Form": "手动创建",
|
||||
"Format your variables using square brackets like this:": "使用这样的方括号格式化你的变量:",
|
||||
"Frequency Penalty": "频率惩罚",
|
||||
"Functions": "功能",
|
||||
|
|
@ -267,7 +273,7 @@
|
|||
"Hello, {{name}}": "您好,{{name}}",
|
||||
"Help": "帮助",
|
||||
"Hide": "隐藏",
|
||||
"Hide Model": "隐藏模型",
|
||||
"Hide Model": "隐藏",
|
||||
"How can I help you today?": "有什么我能帮您的吗?",
|
||||
"Hybrid Search": "混合搜索",
|
||||
"Image Generation (Experimental)": "图像生成(实验性)",
|
||||
|
|
@ -312,6 +318,7 @@
|
|||
"Manage Models": "管理模型",
|
||||
"Manage Ollama Models": "管理 Ollama 模型",
|
||||
"Manage Pipelines": "管理 Pipeline",
|
||||
"Manage Valves": "",
|
||||
"March": "三月",
|
||||
"Max Tokens (num_predict)": "最多 Token (num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同时下载 3 个模型,请稍后重试。",
|
||||
|
|
@ -458,10 +465,12 @@
|
|||
"Seed": "种子 (Seed)",
|
||||
"Select a base model": "选择一个基础模型",
|
||||
"Select a engine": "选择一个搜索引擎",
|
||||
"Select a function": "",
|
||||
"Select a mode": "选择一个模式",
|
||||
"Select a model": "选择一个模型",
|
||||
"Select a pipeline": "选择一个管道",
|
||||
"Select a pipeline url": "选择一个管道 URL",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "选择一个 Ollama 实例",
|
||||
"Select Documents": "选择文档",
|
||||
"Select model": "选择模型",
|
||||
|
|
@ -492,8 +501,9 @@
|
|||
"short-summary": "简短总结",
|
||||
"Show": "显示",
|
||||
"Show Admin Details in Account Pending Overlay": "在用户待激活界面中显示管理员邮箱等详细信息",
|
||||
"Show Model": "显示模型",
|
||||
"Show Model": "显示",
|
||||
"Show shortcuts": "显示快捷方式",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "很有创意",
|
||||
"sidebar": "侧边栏",
|
||||
"Sign in": "登录",
|
||||
|
|
@ -582,6 +592,7 @@
|
|||
"Users": "用户",
|
||||
"Utilize": "利用",
|
||||
"Valid time units:": "有效时间单位:",
|
||||
"Valves": "",
|
||||
"variable": "变量",
|
||||
"variable to have them replaced with clipboard content.": "变量将被剪贴板内容替换。",
|
||||
"Version": "版本",
|
||||
|
|
|
|||
|
|
@ -4,36 +4,36 @@
|
|||
"(e.g. `sh webui.sh --api`)": "(例如 `sh webui.sh --api`)",
|
||||
"(latest)": "(最新版)",
|
||||
"{{ models }}": "{{ models }}",
|
||||
"{{ owner }}: You cannot delete a base model": "{{ owner }}:你無法刪除基本模型",
|
||||
"{{ owner }}: You cannot delete a base model": "{{ owner }}:您無法刪除基礎模型",
|
||||
"{{modelName}} is thinking...": "{{modelName}} 正在思考...",
|
||||
"{{user}}'s Chats": "{{user}} 的聊天",
|
||||
"{{webUIName}} Backend Required": "需要 {{webUIName}} 後台",
|
||||
"A task model is used when performing tasks such as generating titles for chats and web search queries": "在執行任務時使用任務模型,例如為聊天和網絡搜索查詢生成標題",
|
||||
"{{webUIName}} Backend Required": "需要 {{webUIName}} 後端",
|
||||
"A task model is used when performing tasks such as generating titles for chats and web search queries": "在執行任務時使用任務模型,例如為聊天和網頁搜尋查詢生成標題",
|
||||
"a user": "使用者",
|
||||
"About": "關於",
|
||||
"Account": "帳號",
|
||||
"Account Activation Pending": "",
|
||||
"Accurate information": "準確信息",
|
||||
"Active Users": "",
|
||||
"Account Activation Pending": "帳號啟用中",
|
||||
"Accurate information": "準確資訊",
|
||||
"Active Users": "活躍使用者",
|
||||
"Add": "新增",
|
||||
"Add a model id": "新增模型 ID",
|
||||
"Add a short description about what this model does": "為這個模型添加一個簡短描述",
|
||||
"Add a short title for this prompt": "為這個提示詞添加一個簡短的標題",
|
||||
"Add a short description about what this model does": "為這個模型新增一個簡短描述",
|
||||
"Add a short title for this prompt": "為這個提示詞新增一個簡短的標題",
|
||||
"Add a tag": "新增標籤",
|
||||
"Add custom prompt": "新增自定義提示詞",
|
||||
"Add custom prompt": "新增自訂提示詞",
|
||||
"Add Docs": "新增文件",
|
||||
"Add Files": "新增檔案",
|
||||
"Add Memory": "新增記憶",
|
||||
"Add message": "新增訊息",
|
||||
"Add Model": "新增模型",
|
||||
"Add Tags": "新增標籤",
|
||||
"Add User": "新增用户",
|
||||
"Add User": "新增使用者",
|
||||
"Adjusting these settings will apply changes universally to all users.": "調整這些設定將對所有使用者進行更改。",
|
||||
"admin": "管理員",
|
||||
"Admin": "",
|
||||
"Admin": "管理員",
|
||||
"Admin Panel": "管理員控制台",
|
||||
"Admin Settings": "管理設定",
|
||||
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "",
|
||||
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理員隨時可以使用所有工具;使用者需要在工作區中為每個模型分配工具。",
|
||||
"Advanced Parameters": "進階參數",
|
||||
"Advanced Params": "進階參數",
|
||||
"all": "所有",
|
||||
|
|
@ -41,43 +41,44 @@
|
|||
"All Users": "所有使用者",
|
||||
"Allow": "允許",
|
||||
"Allow Chat Deletion": "允許刪除聊天紀錄",
|
||||
"Allow non-local voices": "",
|
||||
"Allow User Location": "",
|
||||
"alphanumeric characters and hyphens": "英文字母、數字(0~9)和連字符(-)",
|
||||
"Allow non-local voices": "允許非本機語音",
|
||||
"Allow User Location": "允許使用者位置",
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"alphanumeric characters and hyphens": "英文字母、數字(0~9)和連字元(-)",
|
||||
"Already have an account?": "已經有帳號了嗎?",
|
||||
"an assistant": "助手",
|
||||
"and": "和",
|
||||
"and create a new shared link.": "創建一個新的共享連結。",
|
||||
"and create a new shared link.": "並建立一個新的共享連結。",
|
||||
"API Base URL": "API 基本 URL",
|
||||
"API Key": "API Key",
|
||||
"API Key created.": "API Key",
|
||||
"API keys": "API Keys",
|
||||
"April": "4月",
|
||||
"Archive": "存檔",
|
||||
"Archive All Chats": "存檔所有聊天紀錄",
|
||||
"Archived Chats": "聊天記錄存檔",
|
||||
"API Key": "API 金鑰",
|
||||
"API Key created.": "API 金鑰已建立。",
|
||||
"API keys": "API 金鑰",
|
||||
"April": "4 月",
|
||||
"Archive": "封存",
|
||||
"Archive All Chats": "封存所有聊天紀錄",
|
||||
"Archived Chats": "已封存的聊天紀錄",
|
||||
"are allowed - Activate this command by typing": "是允許的 - 透過輸入",
|
||||
"Are you sure?": "你確定嗎?",
|
||||
"Are you sure?": "您確定嗎?",
|
||||
"Attach file": "附加檔案",
|
||||
"Attention to detail": "細節精確",
|
||||
"Audio": "音訊",
|
||||
"August": "8月",
|
||||
"August": "8 月",
|
||||
"Auto-playback response": "自動播放回答",
|
||||
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 基本 URL",
|
||||
"AUTOMATIC1111 Base URL is required.": "需要 AUTOMATIC1111 基本 URL",
|
||||
"available!": "可以使用!",
|
||||
"available!": "可用!",
|
||||
"Back": "返回",
|
||||
"Bad Response": "錯誤回應",
|
||||
"Banners": "橫幅",
|
||||
"Base Model (From)": "基本模型(來自)",
|
||||
"Batch Size (num_batch)": "",
|
||||
"Base Model (From)": "基礎模型(來自)",
|
||||
"Batch Size (num_batch)": "批次大小(num_batch)",
|
||||
"before": "前",
|
||||
"Being lazy": "懶人模式",
|
||||
"Brave Search API Key": "搜尋 API Key",
|
||||
"Bypass SSL verification for Websites": "跳過 SSL 驗證",
|
||||
"Call": "",
|
||||
"Call feature is not supported when using Web STT engine": "",
|
||||
"Camera": "",
|
||||
"Brave Search API Key": "Brave 搜尋 API 金鑰",
|
||||
"Bypass SSL verification for Websites": "跳過網站的 SSL 驗證",
|
||||
"Call": "呼叫",
|
||||
"Call feature is not supported when using Web STT engine": "使用 Web STT 引擎時不支援呼叫功能",
|
||||
"Camera": "相機",
|
||||
"Cancel": "取消",
|
||||
"Capabilities": "功能",
|
||||
"Change Password": "修改密碼",
|
||||
|
|
@ -85,27 +86,27 @@
|
|||
"Chat Background Image": "",
|
||||
"Chat Bubble UI": "聊天氣泡介面",
|
||||
"Chat direction": "聊天方向",
|
||||
"Chat History": "聊天紀錄功能",
|
||||
"Chat History is off for this browser.": "此瀏覽器已關閉聊天紀錄功能。",
|
||||
"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 參數",
|
||||
"Chunk Size": "Chunk 大小",
|
||||
"Chunk Overlap": "區塊重疊",
|
||||
"Chunk Params": "區塊參數",
|
||||
"Chunk Size": "區塊大小",
|
||||
"Citation": "引文",
|
||||
"Clear memory": "",
|
||||
"Click here for help.": "點擊這裡尋找幫助。",
|
||||
"Click here to": "點擊這裡",
|
||||
"Click here to download user import template file.": "",
|
||||
"Click here to select": "點擊這裡選擇",
|
||||
"Click here to select a csv file.": "點擊這裡選擇 csv 檔案。",
|
||||
"Click here to select a py file.": "",
|
||||
"Click here to select documents.": "點擊這裡選擇文件。",
|
||||
"click here.": "點擊這裡。",
|
||||
"Click on the user role button to change a user's role.": "點擊使用者 Role 按鈕以更改使用者的 Role。",
|
||||
"Clear memory": "清除記憶",
|
||||
"Click here for help.": "點選這裡尋求幫助。",
|
||||
"Click here to": "點選這裡",
|
||||
"Click here to download user import template file.": "點選這裡下載使用者匯入的範本",
|
||||
"Click here to select": "點選這裡選擇",
|
||||
"Click here to select a csv file.": "點選這裡選擇 csv 檔案。",
|
||||
"Click here to select a py file.": "點選這裡選擇 py 檔案。",
|
||||
"Click here to select documents.": "點選這裡選擇文件。",
|
||||
"click here.": "點選這裡。",
|
||||
"Click on the user role button to change a user's role.": "點選使用者角色按鈕以更改使用者的角色。",
|
||||
"Clone": "複製",
|
||||
"Close": "關閉",
|
||||
"Collection": "收藏",
|
||||
|
|
@ -118,7 +119,7 @@
|
|||
"Confirm Password": "確認密碼",
|
||||
"Confirm your action": "",
|
||||
"Connections": "連線",
|
||||
"Contact Admin for WebUI Access": "",
|
||||
"Contact Admin for WebUI Access": "聯絡管理員以取得 WebUI 存取權",
|
||||
"Content": "內容",
|
||||
"Context Length": "上下文長度",
|
||||
"Continue Response": "繼續回答",
|
||||
|
|
@ -131,8 +132,8 @@
|
|||
"Copying to clipboard was successful!": "成功複製到剪貼簿!",
|
||||
"Create a model": "建立模型",
|
||||
"Create Account": "建立帳號",
|
||||
"Create new key": "建立新密鑰",
|
||||
"Create new secret key": "建立新密鑰",
|
||||
"Create new key": "建立新金鑰",
|
||||
"Create new secret key": "建立新金鑰",
|
||||
"Created at": "建立於",
|
||||
"Created At": "建立於",
|
||||
"Created by": "",
|
||||
|
|
@ -140,18 +141,18 @@
|
|||
"Current Model": "目前模型",
|
||||
"Current Password": "目前密碼",
|
||||
"Custom": "自訂",
|
||||
"Customize models for a specific purpose": "為特定目的自定義模型",
|
||||
"Customize models for a specific purpose": "為特定目的自訂模型",
|
||||
"Dark": "暗色",
|
||||
"Dashboard": "",
|
||||
"Dashboard": "儀表板",
|
||||
"Database": "資料庫",
|
||||
"December": "12月",
|
||||
"December": "12 月",
|
||||
"Default": "預設",
|
||||
"Default (Automatic1111)": "預設(Automatic1111)",
|
||||
"Default (SentenceTransformers)": "預設(SentenceTransformers)",
|
||||
"Default Model": "預設模型",
|
||||
"Default model updated": "預設模型已更新",
|
||||
"Default Prompt Suggestions": "預設提示詞建議",
|
||||
"Default User Role": "預設用戶 Role",
|
||||
"Default User Role": "預設使用者角色",
|
||||
"delete": "刪除",
|
||||
"Delete": "刪除",
|
||||
"Delete a model": "刪除一個模型",
|
||||
|
|
@ -160,178 +161,184 @@
|
|||
"Delete Chat": "刪除聊天紀錄",
|
||||
"Delete chat?": "",
|
||||
"delete this link": "刪除此連結",
|
||||
"Delete User": "刪除用戶",
|
||||
"Delete User": "刪除使用者",
|
||||
"Deleted {{deleteModelTag}}": "已刪除 {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "已刪除 {{name}}",
|
||||
"Description": "描述",
|
||||
"Didn't fully follow instructions": "無法完全遵循指示",
|
||||
"Didn't fully follow instructions": "未完全遵循指示",
|
||||
"Discover a function": "",
|
||||
"Discover a model": "發現新模型",
|
||||
"Discover a prompt": "發現新提示詞",
|
||||
"Discover, download, and explore custom prompts": "發現、下載並探索他人設置的提示詞",
|
||||
"Discover, download, and explore model presets": "發現、下載並探索他人設置的模型",
|
||||
"Dismissible": "",
|
||||
"Display Emoji in Call": "",
|
||||
"Display the username instead of You in the Chat": "在聊天中顯示使用者名稱而不是「你」",
|
||||
"Discover a tool": "",
|
||||
"Discover, download, and explore custom functions": "",
|
||||
"Discover, download, and explore custom prompts": "發現、下載並探索自訂提示詞",
|
||||
"Discover, download, and explore custom tools": "",
|
||||
"Discover, download, and explore model presets": "發現、下載並探索模型預設值",
|
||||
"Dismissible": "可忽略",
|
||||
"Display Emoji in Call": "在呼叫中顯示表情符號",
|
||||
"Display the username instead of You in the Chat": "在聊天中顯示使用者名稱而不是「您」",
|
||||
"Document": "文件",
|
||||
"Document Settings": "文件設定",
|
||||
"Documentation": "",
|
||||
"Documentation": "文件",
|
||||
"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 have an account?": "還沒有註冊帳號?",
|
||||
"Don't like the style": "不喜歡這個樣式?",
|
||||
"Done": "",
|
||||
"Download": "下載",
|
||||
"Download canceled": "下載已取消",
|
||||
"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'.": "例如 '30s', '10m'。有效的時間單位為 's', 'm', 'h'。",
|
||||
"Edit": "編輯",
|
||||
"Edit Doc": "編輯文件",
|
||||
"Edit Memory": "",
|
||||
"Edit Memory": "編輯記憶",
|
||||
"Edit User": "編輯使用者",
|
||||
"Email": "電子郵件",
|
||||
"Embedding Batch Size": "",
|
||||
"Embedding Batch Size": "嵌入批次大小",
|
||||
"Embedding Model": "嵌入模型",
|
||||
"Embedding Model Engine": "嵌入模型引擎",
|
||||
"Embedding model set to \"{{embedding_model}}\"": "嵌入模型已設定為 \"{{embedding_model}}\"",
|
||||
"Enable Chat History": "啟用聊天歷史",
|
||||
"Enable Community Sharing": "啟用社區分享",
|
||||
"Enable Chat History": "啟用聊天紀錄",
|
||||
"Enable Community Sharing": "啟用社群分享",
|
||||
"Enable New Sign Ups": "允許註冊新帳號",
|
||||
"Enable Web Search": "啟用網絡搜索",
|
||||
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確保你的 CSV 檔案包含這四個欄位,並按照此順序:名稱、電子郵件、密碼、角色。",
|
||||
"Enable Web Search": "啟用網頁搜尋",
|
||||
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確保您的 CSV 檔案包含這四個欄位,並按照此順序:名稱、電子郵件、密碼、角色。",
|
||||
"Enter {{role}} message here": "在這裡輸入 {{role}} 訊息",
|
||||
"Enter a detail about yourself for your LLMs to recall": "輸入 LLM 記憶的詳細內容",
|
||||
"Enter Brave Search API Key": "輸入 Brave Search API Key",
|
||||
"Enter Chunk Overlap": "輸入 Chunk Overlap",
|
||||
"Enter Chunk Size": "輸入 Chunk 大小",
|
||||
"Enter Brave Search API Key": "輸入 Brave 搜尋 API 金鑰",
|
||||
"Enter Chunk Overlap": "輸入區塊重疊",
|
||||
"Enter Chunk Size": "輸入區塊大小",
|
||||
"Enter Github Raw URL": "輸入 Github Raw URL",
|
||||
"Enter Google PSE API Key": "輸入 Google PSE API Key",
|
||||
"Enter Google PSE Engine Id": "輸入 Google PSE Engine Id",
|
||||
"Enter Google PSE API Key": "輸入 Google PSE API 金鑰",
|
||||
"Enter Google PSE Engine Id": "輸入 Google PSE 引擎 ID",
|
||||
"Enter Image Size (e.g. 512x512)": "輸入圖片大小(例如 512x512)",
|
||||
"Enter language codes": "輸入語言代碼",
|
||||
"Enter model tag (e.g. {{modelTag}})": "輸入模型標籤(例如 {{modelTag}})",
|
||||
"Enter Number of Steps (e.g. 50)": "輸入步數(例如 50)",
|
||||
"Enter Score": "輸入分數",
|
||||
"Enter Searxng Query URL": "輸入 Searxng 查詢 URL",
|
||||
"Enter Serper API Key": "輸入 Serper API Key",
|
||||
"Enter Serply API Key": "",
|
||||
"Enter Serpstack API Key": "輸入 Serpstack API Key",
|
||||
"Enter Serper API Key": "輸入 Serper API 金鑰",
|
||||
"Enter Serply API Key": "輸入 Serply API 金鑰",
|
||||
"Enter Serpstack API Key": "輸入 Serpstack API 金鑰",
|
||||
"Enter stop sequence": "輸入停止序列",
|
||||
"Enter Tavily API Key": "",
|
||||
"Enter Tavily API Key": "輸入 Tavily API 金鑰",
|
||||
"Enter Top K": "輸入 Top K",
|
||||
"Enter URL (e.g. http://127.0.0.1:7860/)": "輸入 URL(例如 http://127.0.0.1:7860/)",
|
||||
"Enter URL (e.g. http://localhost:11434)": "輸入 URL(例如 http://localhost:11434)",
|
||||
"Enter Your Email": "輸入你的電子郵件",
|
||||
"Enter Your Full Name": "輸入你的全名",
|
||||
"Enter Your Password": "輸入你的密碼",
|
||||
"Enter Your Role": "輸入你的角色",
|
||||
"Enter Your Email": "輸入您的電子郵件",
|
||||
"Enter Your Full Name": "輸入您的全名",
|
||||
"Enter Your Password": "輸入您的密碼",
|
||||
"Enter Your Role": "輸入您的角色",
|
||||
"Error": "錯誤",
|
||||
"Experimental": "實驗功能",
|
||||
"Export": "出口",
|
||||
"Experimental": "實驗性功能",
|
||||
"Export": "匯出",
|
||||
"Export All Chats (All Users)": "匯出所有聊天紀錄(所有使用者)",
|
||||
"Export chat (.json)": "",
|
||||
"Export chat (.json)": "匯出聊天紀錄(.json)",
|
||||
"Export Chats": "匯出聊天紀錄",
|
||||
"Export Documents Mapping": "匯出文件映射",
|
||||
"Export Functions": "",
|
||||
"Export Documents Mapping": "匯出文件對映",
|
||||
"Export Functions": "匯出功能",
|
||||
"Export Models": "匯出模型",
|
||||
"Export Prompts": "匯出提示詞",
|
||||
"Export Tools": "",
|
||||
"External Models": "",
|
||||
"Failed to create API Key.": "無法創建 API 金鑰。",
|
||||
"Export Tools": "匯出工具",
|
||||
"External Models": "外部模型",
|
||||
"Failed to create API Key.": "無法建立 API 金鑰。",
|
||||
"Failed to read clipboard contents": "無法讀取剪貼簿內容",
|
||||
"Failed to update settings": "",
|
||||
"February": "2月",
|
||||
"Feel free to add specific details": "請自由添加詳細內容。",
|
||||
"File": "",
|
||||
"Failed to update settings": "無法更新設定",
|
||||
"February": "2 月",
|
||||
"Feel free to add specific details": "請隨意新增詳細內容。",
|
||||
"File": "檔案",
|
||||
"File Mode": "檔案模式",
|
||||
"File not found.": "找不到檔案。",
|
||||
"Filters": "",
|
||||
"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "偽裝偽裝檢測:無法使用頭像作為頭像。預設為預設頭像。",
|
||||
"Fluidly stream large external response chunks": "流暢地傳輸大型外部響應區塊",
|
||||
"Filters": "篩選器",
|
||||
"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "偽造偵測:無法使用初始頭像。預設為預設個人影象。",
|
||||
"Fluidly stream large external response chunks": "流暢地傳輸大型外部回應區塊",
|
||||
"Focus chat input": "聚焦聊天輸入框",
|
||||
"Followed instructions perfectly": "完全遵循指示",
|
||||
"Form": "",
|
||||
"Format your variables using square brackets like this:": "像這樣使用方括號來格式化你的變數:",
|
||||
"Form": "表單",
|
||||
"Format your variables using square brackets like this:": "像這樣使用方括號來格式化您的變數:",
|
||||
"Frequency Penalty": "頻率懲罰",
|
||||
"Functions": "",
|
||||
"Functions": "功能",
|
||||
"General": "常用",
|
||||
"General Settings": "常用設定",
|
||||
"Generate Image": "",
|
||||
"Generating search query": "生成搜索查詢",
|
||||
"Generation Info": "生成信息",
|
||||
"Generate Image": "生成圖片",
|
||||
"Generating search query": "生成搜尋查詢",
|
||||
"Generation Info": "生成資訊",
|
||||
"Good Response": "優秀的回應",
|
||||
"Google PSE API Key": "Google PSE API Key",
|
||||
"Google PSE Engine Id": "Google PSE Engine Id",
|
||||
"Google PSE API Key": "Google PSE API 金鑰",
|
||||
"Google PSE Engine Id": "Google PSE 引擎 ID",
|
||||
"h:mm a": "h:mm a",
|
||||
"has no conversations.": "沒有對話",
|
||||
"Hello, {{name}}": "你好,{{name}}",
|
||||
"Hello, {{name}}": "您好,{{name}}",
|
||||
"Help": "幫助",
|
||||
"Hide": "隱藏",
|
||||
"Hide Model": "",
|
||||
"How can I help you today?": "今天能為你做什麼?",
|
||||
"Hybrid Search": "混合搜索",
|
||||
"Image Generation (Experimental)": "圖像生成(實驗功能)",
|
||||
"Image Generation Engine": "圖像生成引擎",
|
||||
"Hide Model": "隱藏模型",
|
||||
"How can I help you today?": "今天能為您做些什麼?",
|
||||
"Hybrid Search": "混合搜尋",
|
||||
"Image Generation (Experimental)": "影像生成(實驗性功能)",
|
||||
"Image Generation Engine": "影像生成引擎",
|
||||
"Image Settings": "圖片設定",
|
||||
"Images": "圖片",
|
||||
"Import Chats": "匯入聊天紀錄",
|
||||
"Import Documents Mapping": "匯入文件映射",
|
||||
"Import Functions": "",
|
||||
"Import Documents Mapping": "匯入文件對映",
|
||||
"Import Functions": "匯入功能",
|
||||
"Import Models": "匯入模型",
|
||||
"Import Prompts": "匯入提示詞",
|
||||
"Import Tools": "",
|
||||
"Include `--api` flag when running stable-diffusion-webui": "在運行 stable-diffusion-webui 時加上 `--api` 標誌",
|
||||
"Import Tools": "匯入工具",
|
||||
"Include `--api` flag when running stable-diffusion-webui": "在執行 stable-diffusion-webui 時加上 `--api` 標誌",
|
||||
"Info": "資訊",
|
||||
"Input commands": "輸入命令",
|
||||
"Install from Github URL": "從 Github URL 安裝",
|
||||
"Instant Auto-Send After Voice Transcription": "",
|
||||
"Instant Auto-Send After Voice Transcription": "語音轉錄後立即自動傳送",
|
||||
"Interface": "介面",
|
||||
"Invalid Tag": "無效標籤",
|
||||
"January": "1月",
|
||||
"join our Discord for help.": "加入我們的 Discord 尋找幫助。",
|
||||
"January": "1 月",
|
||||
"join our Discord for help.": "加入我們的 Discord 尋求幫助。",
|
||||
"JSON": "JSON",
|
||||
"JSON Preview": "JSON 預覽",
|
||||
"July": "7月",
|
||||
"June": "6月",
|
||||
"July": "7 月",
|
||||
"June": "6 月",
|
||||
"JWT Expiration": "JWT 過期時間",
|
||||
"JWT Token": "JWT Token",
|
||||
"Keep Alive": "保持活躍",
|
||||
"Keyboard shortcuts": "鍵盤快速鍵",
|
||||
"Knowledge": "",
|
||||
"Knowledge": "知識",
|
||||
"Language": "語言",
|
||||
"Last Active": "最後活動",
|
||||
"Last Modified": "",
|
||||
"Last Modified": "最後修改",
|
||||
"Light": "亮色",
|
||||
"Listening...": "",
|
||||
"Listening...": "正在聆聽...",
|
||||
"LLMs can make mistakes. Verify important information.": "LLM 可能會產生錯誤。請驗證重要資訊。",
|
||||
"Local Models": "",
|
||||
"Local Models": "本機模型",
|
||||
"LTR": "LTR",
|
||||
"Made by OpenWebUI Community": "由 OpenWebUI 社區製作",
|
||||
"Made by OpenWebUI Community": "由 OpenWebUI 社群製作",
|
||||
"Make sure to enclose them with": "請確保變數有被以下符號框住:",
|
||||
"Manage": "",
|
||||
"Manage Models": "管理模組",
|
||||
"Manage": "管理",
|
||||
"Manage Models": "管理模型",
|
||||
"Manage Ollama Models": "管理 Ollama 模型",
|
||||
"Manage Pipelines": "管理管道",
|
||||
"March": "3月",
|
||||
"Manage Pipelines": "管理管線",
|
||||
"Manage Valves": "",
|
||||
"March": "3 月",
|
||||
"Max Tokens (num_predict)": "最大 Token(num_predict)",
|
||||
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可以同時下載 3 個模型。請稍後再試。",
|
||||
"May": "5月",
|
||||
"May": "5 月",
|
||||
"Memories accessible by LLMs will be shown here.": "LLM 記憶將會顯示在此處。",
|
||||
"Memory": "記憶",
|
||||
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "創建連結後發送的訊息將不會被共享。具有 URL 的用戶將會能夠檢視共享的聊天。",
|
||||
"Minimum Score": "最小分數",
|
||||
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "建立連結後傳送的訊息將不會被共享。具有 URL 的使用者將會能夠檢視共享的聊天。",
|
||||
"Minimum Score": "最低分數",
|
||||
"Mirostat": "Mirostat",
|
||||
"Mirostat Eta": "Mirostat Eta",
|
||||
"Mirostat Tau": "Mirostat Tau",
|
||||
"MMMM DD, YYYY": "MMMM DD, YYYY",
|
||||
"MMMM DD, YYYY HH:mm": "MMMM DD, YYYY HH:mm",
|
||||
"MMMM DD, YYYY hh:mm:ss A": "",
|
||||
"MMMM DD, YYYY hh:mm:ss A": "MMMM DD, YYYY hh:mm:ss A",
|
||||
"Model '{{modelName}}' has been successfully downloaded.": "'{{modelName}}' 模型已成功下載。",
|
||||
"Model '{{modelTag}}' is already in queue for downloading.": "'{{modelTag}}' 模型已經在下載佇列中。",
|
||||
"Model {{modelId}} not found": "找不到 {{modelId}} 模型",
|
||||
"Model {{modelName}} is not vision capable": "{{modelName}} 模型不適用於視覺",
|
||||
"Model {{name}} is now {{status}}": "{{name}} 模型現在是 {{status}}",
|
||||
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "模型文件系統路徑已檢測。需要更新模型短名,無法繼續。",
|
||||
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "已偵測到模型檔案系統路徑。需要更新模型簡稱,無法繼續。",
|
||||
"Model ID": "模型 ID",
|
||||
"Model not selected": "未選擇模型",
|
||||
"Model Params": "模型參數",
|
||||
|
|
@ -345,33 +352,33 @@
|
|||
"Name your model": "請輸入模型名稱",
|
||||
"New Chat": "新增聊天",
|
||||
"New Password": "新密碼",
|
||||
"No documents found": "",
|
||||
"No documents found": "找不到文件",
|
||||
"No results found": "沒有找到結果",
|
||||
"No search query generated": "沒有生成搜索查詢",
|
||||
"No search query generated": "沒有生成搜尋查詢",
|
||||
"No source available": "沒有可用的來源",
|
||||
"None": "無",
|
||||
"Not factually correct": "與真實資訊不相符",
|
||||
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "註:如果設置最低分數,則搜索將只返回分數大於或等於最低分數的文檔。",
|
||||
"Notifications": "桌面通知",
|
||||
"November": "11月",
|
||||
"num_thread (Ollama)": "num_thread(奧拉馬)",
|
||||
"Not factually correct": "與真實資訊不符",
|
||||
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "註:如果設定最低分數,則搜尋將只返回分數大於或等於最低分數的文件。",
|
||||
"Notifications": "通知",
|
||||
"November": "11 月",
|
||||
"num_thread (Ollama)": "num_thread(Ollama)",
|
||||
"OAuth ID": "",
|
||||
"October": "10 月",
|
||||
"Off": "關閉",
|
||||
"Okay, Let's Go!": "好的,啟動吧!",
|
||||
"OLED Dark": "`",
|
||||
"OLED Dark": "OLED 深色",
|
||||
"Ollama": "Ollama",
|
||||
"Ollama API": "Ollama API",
|
||||
"Ollama API disabled": "Ollama API 已禁用",
|
||||
"Ollama API is disabled": "",
|
||||
"Ollama API disabled": "Ollama API 已停用",
|
||||
"Ollama API is disabled": "Ollama API 已停用",
|
||||
"Ollama Version": "Ollama 版本",
|
||||
"On": "開啟",
|
||||
"Only": "僅有",
|
||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "命令字串中只能包含英文字母、數字(0~9)和連字符(-)。",
|
||||
"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.": "哎呀!請稍等!你的文件還在處理中。我們正最佳化文件,請耐心等待,一旦準備好,我們會通知你。",
|
||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "命令字串中只能包含英文字母、數字(0~9)和連字元(-)。",
|
||||
"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! There was an error in the previous response. Please try again or contact admin.": "",
|
||||
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "哎呀!你正在使用不支援的方法(僅有前台)。請從後台提供 WebUI。",
|
||||
"Oops! There was an error in the previous response. Please try again or contact admin.": "哎呀!先前的回應發生錯誤。請重試或聯絡管理員",
|
||||
"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)": "Open AI (Dall-E)",
|
||||
|
|
@ -385,22 +392,22 @@
|
|||
"Other": "其他",
|
||||
"Password": "密碼",
|
||||
"PDF document (.pdf)": "PDF 文件 (.pdf)",
|
||||
"PDF Extract Images (OCR)": "PDF 圖像擷取(OCR 光學文字辨識)",
|
||||
"PDF Extract Images (OCR)": "PDF 影像擷取(OCR 光學文字辨識)",
|
||||
"pending": "待審查",
|
||||
"Permission denied when accessing media devices": "",
|
||||
"Permission denied when accessing microphone": "",
|
||||
"Permission denied when accessing media devices": "存取媒體裝置時被拒絕權限",
|
||||
"Permission denied when accessing microphone": "存取麥克風時被拒絕權限",
|
||||
"Permission denied when accessing microphone: {{error}}": "存取麥克風時被拒絕權限:{{error}}",
|
||||
"Personalization": "個人化",
|
||||
"Pipelines": "管線",
|
||||
"Pipelines Valves": "管線阀门",
|
||||
"Pipelines Valves": "管線閥門",
|
||||
"Plain text (.txt)": "純文字 (.txt)",
|
||||
"Playground": "AI 對話遊樂場",
|
||||
"Positive attitude": "積極態度",
|
||||
"Previous 30 days": "前 30 天",
|
||||
"Previous 7 days": "前 7 天",
|
||||
"Profile Image": "個人圖像",
|
||||
"Profile Image": "個人影像",
|
||||
"Prompt": "提示詞",
|
||||
"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "提示詞(例如:告訴我關於羅馬帝國的趣味事)",
|
||||
"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "提示詞(例如:告訴我關於羅馬帝國的一些趣事)",
|
||||
"Prompt Content": "提示詞內容",
|
||||
"Prompt suggestions": "提示詞建議",
|
||||
"Prompts": "提示詞",
|
||||
|
|
@ -410,32 +417,32 @@
|
|||
"RAG Template": "RAG 範例",
|
||||
"Read Aloud": "讀出",
|
||||
"Record voice": "錄音",
|
||||
"Redirecting you to OpenWebUI Community": "將你重新導向到 OpenWebUI 社群",
|
||||
"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "",
|
||||
"Refused when it shouldn't have": "拒絕時不該拒絕",
|
||||
"Redirecting you to OpenWebUI Community": "將您重新導向到 OpenWebUI 社群",
|
||||
"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "將自己稱為「使用者」(例如,「使用者正在學習西班牙語」)",
|
||||
"Refused when it shouldn't have": "不該拒絕時拒絕了",
|
||||
"Regenerate": "重新生成",
|
||||
"Release Notes": "發布說明",
|
||||
"Remove": "移除",
|
||||
"Remove Model": "移除模型",
|
||||
"Rename": "重命名",
|
||||
"Rename": "重新命名",
|
||||
"Repeat Last N": "重複最後 N 次",
|
||||
"Request Mode": "請求模式",
|
||||
"Reranking Model": "重新排序模型",
|
||||
"Reranking model disabled": "重新排序模型已禁用",
|
||||
"Reranking model disabled": "重新排序模型已停用",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "重新排序模型設定為 \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage": "重置向量儲存空間",
|
||||
"Reset": "重設",
|
||||
"Reset Upload Directory": "重設上傳目錄",
|
||||
"Reset Vector Storage": "重設向量儲存空間",
|
||||
"Response AutoCopy to Clipboard": "自動複製回答到剪貼簿",
|
||||
"Role": "Role",
|
||||
"Role": "角色",
|
||||
"Rosé Pine": "玫瑰松",
|
||||
"Rosé Pine Dawn": "黎明玫瑰松",
|
||||
"RTL": "RTL",
|
||||
"Running": "",
|
||||
"Running": "運作中",
|
||||
"Save": "儲存",
|
||||
"Save & Create": "儲存並建立",
|
||||
"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 complete!": "掃描完成!",
|
||||
"Scan for documents from {{path}}": "從 {{path}} 掃描文件",
|
||||
|
|
@ -443,37 +450,39 @@
|
|||
"Search a model": "搜尋模型",
|
||||
"Search Chats": "搜尋聊天",
|
||||
"Search Documents": "搜尋文件",
|
||||
"Search Functions": "",
|
||||
"Search Functions": "搜尋功能",
|
||||
"Search Models": "搜尋模型",
|
||||
"Search Prompts": "搜尋提示詞",
|
||||
"Search Query Generation Prompt": "",
|
||||
"Search Query Generation Prompt Length Threshold": "",
|
||||
"Search Query Generation Prompt": "搜尋查詢生成提示詞",
|
||||
"Search Query Generation Prompt Length Threshold": "搜尋查詢生成提示詞長度閾值",
|
||||
"Search Result Count": "搜尋結果數量",
|
||||
"Search Tools": "",
|
||||
"Searched {{count}} sites_other": "掃描 {{count}} 個網站_其他",
|
||||
"Searching \"{{searchQuery}}\"": "",
|
||||
"Search Tools": "搜尋工具",
|
||||
"Searched {{count}} sites_other": "搜尋了 {{count}} 個網站",
|
||||
"Searching \"{{searchQuery}}\"": "正在搜尋 \"{{searchQuery}}\"",
|
||||
"Searxng Query URL": "Searxng 查詢 URL",
|
||||
"See readme.md for instructions": "查看 readme.md 獲取指南",
|
||||
"See what's new": "查看最新內容",
|
||||
"See readme.md for instructions": "檢視 readme.md 取得指南",
|
||||
"See what's new": "檢視最新內容",
|
||||
"Seed": "種子",
|
||||
"Select a base model": "選擇基礎模型",
|
||||
"Select a engine": "",
|
||||
"Select a engine": "選擇引擎",
|
||||
"Select a function": "",
|
||||
"Select a mode": "選擇模式",
|
||||
"Select a model": "選擇一個模型",
|
||||
"Select a pipeline": "選擇管道",
|
||||
"Select a pipeline url": "選擇管道 URL",
|
||||
"Select an Ollama instance": "選擇 Ollama 實例",
|
||||
"Select Documents": "",
|
||||
"Select a pipeline": "選擇管線",
|
||||
"Select a pipeline url": "選擇管線 URL",
|
||||
"Select a tool": "",
|
||||
"Select an Ollama instance": "選擇 Ollama 執行個體",
|
||||
"Select Documents": "選擇文件",
|
||||
"Select model": "選擇模型",
|
||||
"Select only one model to call": "",
|
||||
"Selected model(s) do not support image inputs": "已選擇模型不支持圖像輸入",
|
||||
"Select only one model to call": "僅選擇一個模型來呼叫",
|
||||
"Selected model(s) do not support image inputs": "已選擇模型不支援影像輸入",
|
||||
"Send": "傳送",
|
||||
"Send a Message": "傳送訊息",
|
||||
"Send message": "傳送訊息",
|
||||
"September": "九月",
|
||||
"Serper API Key": "Serper API Key",
|
||||
"Serply API Key": "",
|
||||
"Serpstack API Key": "Serpstack API Key",
|
||||
"September": "9 月",
|
||||
"Serper API Key": "Serper API 金鑰",
|
||||
"Serply API Key": "Serply API 金鑰",
|
||||
"Serpstack API Key": "Serpstack API 金鑰",
|
||||
"Server connection verified": "已驗證伺服器連線",
|
||||
"Set as default": "設為預設",
|
||||
"Set Default Model": "設定預設模型",
|
||||
|
|
@ -485,15 +494,16 @@
|
|||
"Set Voice": "設定語音",
|
||||
"Settings": "設定",
|
||||
"Settings saved successfully!": "成功儲存設定",
|
||||
"Settings updated successfully": "",
|
||||
"Settings updated successfully": "設定更新成功",
|
||||
"Share": "分享",
|
||||
"Share Chat": "分享聊天",
|
||||
"Share to OpenWebUI Community": "分享到 OpenWebUI 社群",
|
||||
"short-summary": "簡短摘要",
|
||||
"Show": "顯示",
|
||||
"Show Admin Details in Account Pending Overlay": "",
|
||||
"Show Model": "",
|
||||
"Show Admin Details in Account Pending Overlay": "在帳號待審覆蓋層中顯示管理員詳細資訊",
|
||||
"Show Model": "顯示模型",
|
||||
"Show shortcuts": "顯示快速鍵",
|
||||
"Show your support!": "",
|
||||
"Showcased creativity": "展示創造性",
|
||||
"sidebar": "側邊欄",
|
||||
"Sign in": "登入",
|
||||
|
|
@ -504,115 +514,116 @@
|
|||
"Speech recognition error: {{error}}": "語音識別錯誤:{{error}}",
|
||||
"Speech-to-Text Engine": "語音轉文字引擎",
|
||||
"Stop Sequence": "停止序列",
|
||||
"STT Model": "",
|
||||
"STT Model": "STT 模型",
|
||||
"STT Settings": "語音轉文字設定",
|
||||
"Submit": "提交",
|
||||
"Subtitle (e.g. about the Roman Empire)": "標題(例如:關於羅馬帝國)",
|
||||
"Subtitle (e.g. about the Roman Empire)": "副標題(例如:關於羅馬帝國)",
|
||||
"Success": "成功",
|
||||
"Successfully updated.": "更新成功。",
|
||||
"Suggested": "建議",
|
||||
"System": "系統",
|
||||
"System Prompt": "系統提示詞",
|
||||
"Tags": "標籤",
|
||||
"Tap to interrupt": "",
|
||||
"Tavily API Key": "",
|
||||
"Tap to interrupt": "點選以中斷",
|
||||
"Tavily API Key": "Tavily API 金鑰",
|
||||
"Tell us more:": "告訴我們更多:",
|
||||
"Temperature": "溫度",
|
||||
"Template": "模板",
|
||||
"Text Completion": "文本補全(Text Completion)",
|
||||
"Template": "範本",
|
||||
"Text Completion": "文字補全",
|
||||
"Text-to-Speech Engine": "文字轉語音引擎",
|
||||
"Tfs Z": "Tfs Z",
|
||||
"Thanks for your feedback!": "感謝你的回饋!",
|
||||
"Thanks for your feedback!": "感謝您的回饋!",
|
||||
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分數應該介於 0.0(0%)和 1.0(100%)之間。",
|
||||
"Theme": "主題",
|
||||
"Thinking...": "",
|
||||
"This action cannot be undone. Do you wish to continue?": "",
|
||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "這確保你寶貴的對話安全地儲存到你的後台資料庫。謝謝!",
|
||||
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
|
||||
"Thinking...": "正在思考...",
|
||||
"This action cannot be undone. Do you wish to continue?": "此動作無法被復原。您想要繼續進行嗎?",
|
||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "這確保您寶貴的對話安全地儲存到您的後端資料庫。謝謝!",
|
||||
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "這是一個實驗性功能,可能無法如預期運作,並且隨時可能更改。",
|
||||
"This setting does not sync across browsers or devices.": "此設定不會在瀏覽器或裝置間同步。",
|
||||
"This will delete": "",
|
||||
"Thorough explanation": "詳細說明",
|
||||
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "提示:透過在每次替換後在聊天輸入框中按 Tab 鍵連續更新多個變數。",
|
||||
"Title": "標題",
|
||||
"Title (e.g. Tell me a fun fact)": "標題(例如:告訴我一個有趣的事)",
|
||||
"Title Auto-Generation": "自動生成標題",
|
||||
"Title Auto-Generation": "自動產生標題",
|
||||
"Title cannot be an empty string.": "標題不能為空字串",
|
||||
"Title Generation Prompt": "自動生成標題的提示詞",
|
||||
"Title Generation Prompt": "自動產生標題的提示詞",
|
||||
"to": "到",
|
||||
"To access the available model names for downloading,": "若想查看可供下載的模型名稱,",
|
||||
"To access the GGUF models available for downloading,": "若想查看可供下載的 GGUF 模型名稱,",
|
||||
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
|
||||
"To add documents here, upload them to the \"Documents\" workspace first.": "",
|
||||
"To access the available model names for downloading,": "若想檢視可供下載的模型名稱,",
|
||||
"To access the GGUF models available for downloading,": "若想檢視可供下載的 GGUF 模型名稱,",
|
||||
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "若要存取 WebUI,請聯絡管理員。管理員可以從管理面板管理使用者狀態。",
|
||||
"To add documents here, upload them to the \"Documents\" workspace first.": "若要在此新增文件,請先將它們上傳到「文件」工作區。",
|
||||
"to chat input.": "到聊天輸入框來啟動此命令。",
|
||||
"To select filters here, add them to the \"Functions\" workspace first.": "",
|
||||
"To select toolkits here, add them to the \"Tools\" workspace first.": "",
|
||||
"To select filters here, add them to the \"Functions\" workspace first.": "若要在此選擇篩選器,請先將它們新增到「功能」工作區。",
|
||||
"To select toolkits here, add them to the \"Tools\" workspace first.": "若要在此選擇工具包,請先將它們新增到「工具」工作區。",
|
||||
"Today": "今天",
|
||||
"Toggle settings": "切換設定",
|
||||
"Toggle sidebar": "切換側邊欄",
|
||||
"Tokens To Keep On Context Refresh (num_keep)": "",
|
||||
"Tools": "",
|
||||
"Tokens To Keep On Context Refresh (num_keep)": "上下文重新整理時保留的 Token 數量(num_keep)",
|
||||
"Tools": "工具",
|
||||
"Top K": "Top K",
|
||||
"Top P": "Top P",
|
||||
"Trouble accessing Ollama?": "存取 Ollama 時遇到問題?",
|
||||
"TTS Model": "",
|
||||
"TTS Settings": "文字轉語音設定",
|
||||
"TTS Voice": "",
|
||||
"TTS Model": "文字轉語音(TTS)模型",
|
||||
"TTS Settings": "文字轉語音(TTS)設定",
|
||||
"TTS Voice": "文字轉語音(TTS)聲調",
|
||||
"Type": "類型",
|
||||
"Type Hugging Face Resolve (Download) URL": "輸入 Hugging Face 解析後的(下載)URL",
|
||||
"Uh-oh! There was an issue connecting to {{provider}}.": "哎呀!連線到 {{provider}} 時出現問題。",
|
||||
"UI": "",
|
||||
"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "",
|
||||
"Update": "",
|
||||
"UI": "使用者界面",
|
||||
"Unknown file type '{{file_type}}'. Proceeding with the file upload anyway.": "未知的檔案類型 '{{file_type}}'。但仍會繼續上傳。",
|
||||
"Update": "更新",
|
||||
"Update and Copy Link": "更新並複製連結",
|
||||
"Update password": "更新密碼",
|
||||
"Updated at": "",
|
||||
"Upload": "",
|
||||
"Updated at": "更新於",
|
||||
"Upload": "上傳",
|
||||
"Upload a GGUF model": "上傳一個 GGUF 模型",
|
||||
"Upload Files": "上傳文件",
|
||||
"Upload Pipeline": "",
|
||||
"Upload Files": "上傳檔案",
|
||||
"Upload Pipeline": "上傳管線",
|
||||
"Upload Progress": "上傳進度",
|
||||
"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 Initials": "使用初始头像",
|
||||
"use_mlock (Ollama)": "use_mlock(奧拉馬)",
|
||||
"use_mmap (Ollama)": "use_mmap (Ollama)",
|
||||
"Use Initials": "使用初始頭像",
|
||||
"use_mlock (Ollama)": "use_mlock(Ollama)",
|
||||
"use_mmap (Ollama)": "use_mmap(Ollama)",
|
||||
"user": "使用者",
|
||||
"User Permissions": "使用者權限",
|
||||
"Users": "使用者",
|
||||
"Utilize": "使用",
|
||||
"Valid time units:": "有效時間單位:",
|
||||
"Valves": "",
|
||||
"variable": "變數",
|
||||
"variable to have them replaced with clipboard content.": "變數將替換為剪貼簿內容",
|
||||
"Version": "版本",
|
||||
"Voice": "",
|
||||
"Warning": "警告",
|
||||
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "警告:如果更新或更改你的嵌入模型,則需要重新導入所有文件",
|
||||
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "警告:如果更新或更改您的嵌入模型,則需要重新匯入所有文件",
|
||||
"Web": "網頁",
|
||||
"Web API": "",
|
||||
"Web Loader Settings": "Web 載入器設定",
|
||||
"Web Params": "Web 參數",
|
||||
"Web Search": "Web 搜尋",
|
||||
"Web Search Engine": "Web 搜尋引擎",
|
||||
"Web API": "網頁 API",
|
||||
"Web Loader Settings": "網頁載入器設定",
|
||||
"Web Params": "網頁參數",
|
||||
"Web Search": "網頁搜尋",
|
||||
"Web Search Engine": "網頁搜尋引擎",
|
||||
"Webhook URL": "Webhook URL",
|
||||
"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)": "",
|
||||
"Widescreen Mode": "",
|
||||
"Whisper (Local)": "Whisper(本地)",
|
||||
"Widescreen Mode": "寬螢幕模式",
|
||||
"Workspace": "工作區",
|
||||
"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 字的摘要來概括 [主題或關鍵詞]。",
|
||||
"Yesterday": "昨天",
|
||||
"You": "你",
|
||||
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "",
|
||||
"You cannot clone a base model": "你不能複製基礎模型",
|
||||
"You have no archived conversations.": "你沒有任何已封存的對話",
|
||||
"You have shared this chat": "你已分享此聊天",
|
||||
"You're a helpful assistant.": "你是一位善於協助他人的助手。",
|
||||
"You": "您",
|
||||
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "您可以透過下方的「管理」按鈕新增記憶,個人化您的 LLM 互動,使其更有幫助並更符合您的需求。",
|
||||
"You cannot clone a base model": "您不能複製基礎模型",
|
||||
"You have no archived conversations.": "您沒有任何已封存的對話",
|
||||
"You have shared this chat": "您已分享此聊天",
|
||||
"You're a helpful assistant.": "您是一位善於協助他人的助手。",
|
||||
"You're now logged in.": "已登入。",
|
||||
"Your account status is currently pending activation.": "",
|
||||
"Your account status is currently pending activation.": "您的帳號狀態目前待啟用。",
|
||||
"Youtube": "Youtube",
|
||||
"Youtube Loader Settings": "Youtube 載入器設定"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -506,13 +506,36 @@ export const removeEmojis = (str) => {
|
|||
return str.replace(emojiRegex, '');
|
||||
};
|
||||
|
||||
export const removeFormattings = (str) => {
|
||||
return str.replace(/(\*)(.*?)\1/g, '').replace(/(```)(.*?)\1/gs, '');
|
||||
};
|
||||
|
||||
export const extractSentences = (text) => {
|
||||
// Split the paragraph into sentences based on common punctuation marks
|
||||
const sentences = text.split(/(?<=[.!?])\s+/);
|
||||
// This regular expression matches code blocks marked by triple backticks
|
||||
const codeBlockRegex = /```[\s\S]*?```/g;
|
||||
|
||||
let codeBlocks = [];
|
||||
let index = 0;
|
||||
|
||||
// Temporarily replace code blocks with placeholders and store the blocks separately
|
||||
text = text.replace(codeBlockRegex, (match) => {
|
||||
let placeholder = `\u0000${index}\u0000`; // Use a unique placeholder
|
||||
codeBlocks[index++] = match;
|
||||
return placeholder;
|
||||
});
|
||||
|
||||
// Split the modified text into sentences based on common punctuation marks, avoiding these blocks
|
||||
let sentences = text.split(/(?<=[.!?])\s+/);
|
||||
|
||||
// Restore code blocks and process sentences
|
||||
sentences = sentences.map((sentence) => {
|
||||
// Check if the sentence includes a placeholder for a code block
|
||||
return sentence.replace(/\u0000(\d+)\u0000/g, (_, idx) => codeBlocks[idx]);
|
||||
});
|
||||
|
||||
return sentences
|
||||
.map((sentence) => removeEmojis(sentence.trim()))
|
||||
.filter((sentence) => sentence !== '');
|
||||
.map((sentence) => removeFormattings(removeEmojis(sentence.trim())))
|
||||
.filter((sentence) => sentence);
|
||||
};
|
||||
|
||||
export const extractSentencesForAudio = (text) => {
|
||||
|
|
|
|||
|
|
@ -29,13 +29,15 @@
|
|||
showChangelog,
|
||||
config,
|
||||
showCallOverlay,
|
||||
tools
|
||||
tools,
|
||||
functions
|
||||
} from '$lib/stores';
|
||||
|
||||
import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
|
||||
import Sidebar from '$lib/components/layout/Sidebar.svelte';
|
||||
import ChangelogModal from '$lib/components/ChangelogModal.svelte';
|
||||
import AccountPending from '$lib/components/layout/Overlay/AccountPending.svelte';
|
||||
import { getFunctions } from '$lib/apis/functions';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
|
|
@ -93,6 +95,9 @@
|
|||
(async () => {
|
||||
tools.set(await getTools(localStorage.token));
|
||||
})(),
|
||||
(async () => {
|
||||
functions.set(await getFunctions(localStorage.token));
|
||||
})(),
|
||||
(async () => {
|
||||
banners.set(await getBanners(localStorage.token));
|
||||
})(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { showSidebar } from '$lib/stores';
|
||||
|
||||
import Playground from '$lib/components/workspace/Playground.svelte';
|
||||
import Playground from '$lib/components/playground/Playground.svelte';
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
const i18n = getContext('i18n');
|
||||
|
||||
onMount(async () => {
|
||||
functions.set(await getFunctions(localStorage.token));
|
||||
// functions.set(await getFunctions(localStorage.token));
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
let loaded = false;
|
||||
const BREAKPOINT = 768;
|
||||
|
||||
let wakeLock = null;
|
||||
|
||||
onMount(async () => {
|
||||
theme.set(localStorage.theme);
|
||||
|
||||
|
|
@ -51,6 +53,31 @@
|
|||
|
||||
window.addEventListener('resize', onResize);
|
||||
|
||||
const setWakeLock = async () => {
|
||||
try {
|
||||
wakeLock = await navigator.wakeLock.request('screen');
|
||||
} catch (err) {
|
||||
// The Wake Lock request has failed - usually system related, such as battery.
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
wakeLock.addEventListener('release', () => {
|
||||
// the wake lock has been released
|
||||
console.log('Wake Lock released');
|
||||
});
|
||||
};
|
||||
|
||||
if ('wakeLock' in navigator) {
|
||||
await setWakeLock();
|
||||
|
||||
document.addEventListener('visibilitychange', async () => {
|
||||
// Re-request the wake lock if the document becomes visible
|
||||
if (wakeLock !== null && document.visibilityState === 'visible') {
|
||||
await setWakeLock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let backendConfig = null;
|
||||
try {
|
||||
backendConfig = await getBackendConfig();
|
||||
|
|
|
|||
Loading…
Reference in a new issue