Compare commits
@@ -28,6 +28,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
|
||||
- name: Remove git history
|
||||
run: rm -rf .git
|
||||
@@ -52,7 +54,9 @@ jobs:
|
||||
- name: Set up Git and push to Space
|
||||
run: |
|
||||
git init --initial-branch=main
|
||||
git lfs install
|
||||
git lfs track "*.ttf"
|
||||
git lfs track "*.jpg"
|
||||
rm demo.gif
|
||||
git add .
|
||||
git commit -m "GitHub deploy: ${{ github.sha }}"
|
||||
|
||||
@@ -5,6 +5,88 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.4.6] - 2024-11-26
|
||||
|
||||
### Added
|
||||
|
||||
- **🌍 Enhanced Translations**: Various language translations improved to make the WebUI more accessible and user-friendly worldwide.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **✏️ Textarea Shifting Bug**: Resolved the issue where the textarea shifted unexpectedly, ensuring a smoother typing experience.
|
||||
- **⚙️ Model Configuration Modal**: Fixed the issue where the models configuration modal introduced in 0.4.5 wasn’t working for some users.
|
||||
- **🔍 Legacy Query Support**: Restored functionality for custom query generation in RAG when using legacy prompts, ensuring both default and custom templates now work seamlessly.
|
||||
- **⚡ Improved General Reliability**: Various minor fixes improve platform stability and ensure a smoother overall experience across workflows.
|
||||
|
||||
## [0.4.5] - 2024-11-26
|
||||
|
||||
### Added
|
||||
|
||||
- **🎨 Model Order/Defaults Reintroduced**: Brought back the ability to set model order and default models, now configurable via Admin Settings > Models > Configure (Gear Icon).
|
||||
|
||||
### Fixed
|
||||
|
||||
- **🔍 Query Generation Issue**: Resolved an error in web search query generation, enhancing search accuracy and ensuring smoother search workflows.
|
||||
- **📏 Textarea Auto Height Bug**: Fixed a layout issue where textarea input height was shifting unpredictably, particularly when editing system prompts.
|
||||
- **🔑 Ollama Authentication**: Corrected an issue with Ollama’s authorization headers, guaranteeing reliable authentication across all endpoints.
|
||||
- **⚙️ Missing Min_P Save**: Resolved an issue where the 'min_p' parameter was not being saved in configurations.
|
||||
- **🛠️ Tools Description**: Fixed a key issue that omitted tool descriptions in tools payload.
|
||||
|
||||
## [0.4.4] - 2024-11-22
|
||||
|
||||
### Added
|
||||
|
||||
- **🌐 Translation Updates**: Refreshed Catalan, Brazilian Portuguese, German, and Ukrainian translations, further enhancing the platform's accessibility and improving the experience for international users.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **📱 Mobile Controls Visibility**: Resolved an issue where the controls button was not displaying on the new chats page for mobile users, ensuring smoother navigation and functionality on smaller screens.
|
||||
- **📷 LDAP Profile Image Issue**: Fixed an LDAP integration bug related to profile images, ensuring seamless authentication and a reliable login experience for users.
|
||||
- **⏳ RAG Query Generation Issue**: Addressed a significant problem where RAG query generation occurred unnecessarily without attached files, drastically improving speed and reducing delays during chat completions.
|
||||
|
||||
### Changed
|
||||
|
||||
- **⚙️ Legacy Event Emitter Support**: Reintroduced compatibility with legacy "citation" types for event emitters in tools and functions, providing smoother workflows and broader tool support for users.
|
||||
|
||||
## [0.4.3] - 2024-11-21
|
||||
|
||||
### Added
|
||||
|
||||
- **📚 Inline Citations for RAG Results**: Get seamless inline citations for Retrieval-Augmented Generation (RAG) responses using the default RAG prompt. Note: This feature only supports newly uploaded files, improving traceability and providing source clarity.
|
||||
- **🎨 Better Rich Text Input Support**: Enjoy smoother and more reliable rich text formatting for chats, enhancing communication quality.
|
||||
- **⚡ Faster Model Retrieval**: Implemented caching optimizations for faster model loading, providing a noticeable speed boost across workflows. Further improvements are on the way!
|
||||
|
||||
### Fixed
|
||||
|
||||
- **🔗 Pipelines Feature Restored**: Resolved a critical issue that previously prevented Pipelines from functioning, ensuring seamless workflows.
|
||||
- **✏️ Missing Suffix Field in Ollama Form**: Added the missing "suffix" field to the Ollama generate form, enhancing customization options.
|
||||
|
||||
### Changed
|
||||
|
||||
- **🗂️ Renamed "Citations" to "Sources"**: Improved clarity and consistency by renaming the "citations" field to "sources" in messages.
|
||||
|
||||
## [0.4.2] - 2024-11-20
|
||||
|
||||
### Fixed
|
||||
|
||||
- **📁 Knowledge Files Visibility Issue**: Resolved the bug preventing individual files in knowledge collections from displaying when referenced with '#'.
|
||||
- **🔗 OpenAI Endpoint Prefix**: Fixed the issue where certain OpenAI connections that deviate from the official API spec weren’t working correctly with prefixes.
|
||||
- **⚔️ Arena Model Access Control**: Corrected an issue where arena model access control settings were not being saved.
|
||||
- **🔧 Usage Capability Selector**: Fixed the broken usage capabilities selector in the model editor.
|
||||
|
||||
## [0.4.1] - 2024-11-19
|
||||
|
||||
### Added
|
||||
|
||||
- **📊 Enhanced Feedback System**: Introduced a detailed 1-10 rating scale for feedback alongside thumbs up/down, preparing for more precise model fine-tuning and improving feedback quality.
|
||||
- **ℹ️ Tool Descriptions on Hover**: Easily access tool descriptions by hovering over the message input, providing a smoother workflow with more context when utilizing tools.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **🗑️ Graceful Handling of Deleted Users**: Resolved an issue where deleted users caused workspace items (models, knowledge, prompts, tools) to fail, ensuring reliable workspace loading.
|
||||
- **🔑 API Key Creation**: Fixed an issue preventing users from creating new API keys, restoring secure and seamless API management.
|
||||
- **🔗 HTTPS Proxy Fix**: Corrected HTTPS proxy issues affecting the '/api/v1/models/' endpoint, ensuring smoother, uninterrupted model management.
|
||||
|
||||
## [0.4.0] - 2024-11-19
|
||||
|
||||
### Added
|
||||
|
||||
+60
-38
@@ -2,76 +2,98 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
As members, contributors, and leaders of this community, we pledge to make participation in our open-source project a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
||||
We are committed to creating and maintaining an open, respectful, and professional environment where positive contributions and meaningful discussions can flourish. By participating in this project, you agree to uphold these values and align your behavior to the standards outlined in this Code of Conduct.
|
||||
|
||||
## Why These Standards Are Important
|
||||
|
||||
Open-source projects rely on a community of volunteers dedicating their time, expertise, and effort toward a shared goal. These projects are inherently collaborative but also fragile, as the success of the project depends on the goodwill, energy, and productivity of those involved.
|
||||
|
||||
Maintaining a positive and respectful environment is essential to safeguarding the integrity of this project and protecting contributors' efforts. Behavior that disrupts this atmosphere—whether through hostility, entitlement, or unprofessional conduct—can severely harm the morale and productivity of the community. **Strict enforcement of these standards ensures a safe and supportive space for meaningful collaboration.**
|
||||
|
||||
This is a community where **respect and professionalism are mandatory.** Violations of these standards will result in **zero tolerance** and immediate enforcement to prevent disruption and ensure the well-being of all participants.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contribute to a positive environment for our community include:
|
||||
Examples of behavior that contribute to a positive and professional community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
- **Respecting others.** Be considerate, listen actively, and engage with empathy toward others' viewpoints and experiences.
|
||||
- **Constructive feedback.** Provide actionable, thoughtful, and respectful feedback that helps improve the project and encourages collaboration. Avoid unproductive negativity or hypercriticism.
|
||||
- **Recognizing volunteer contributions.** Appreciate that contributors dedicate their free time and resources selflessly. Approach them with gratitude and patience.
|
||||
- **Focusing on shared goals.** Collaborate in ways that prioritize the health, success, and sustainability of the community over individual agendas.
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
- **Spamming of any kind**
|
||||
- Aggressive sales tactics targeting our community members are strictly prohibited. You can mention your product if it's relevant to the discussion, but under no circumstances should you push it forcefully
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
- The use of discriminatory, demeaning, or sexualized language or behavior.
|
||||
- Personal attacks, derogatory comments, trolling, or inflammatory political or ideological arguments.
|
||||
- Harassment, intimidation, or any behavior intended to create a hostile, uncomfortable, or unsafe environment.
|
||||
- Publishing others' private information (e.g., physical or email addresses) without explicit permission.
|
||||
- **Entitlement, demand, or aggression toward contributors.** Volunteers are under no obligation to provide immediate or personalized support. Rude or dismissive behavior will not be tolerated.
|
||||
- **Unproductive or destructive behavior.** This includes venting frustration as hostility ("tantrums"), hypercriticism, attention-seeking negativity, or anything that distracts from the project's goals.
|
||||
- **Spamming and promotional exploitation.** Sharing irrelevant product promotions or self-promotion in the community is not allowed unless it directly contributes value to the discussion.
|
||||
|
||||
### Feedback and Community Engagement
|
||||
|
||||
- **Constructive feedback is encouraged, but hostile or entitled behavior will result in immediate action.** If you disagree with elements of the project, we encourage you to offer meaningful improvements or fork the project if necessary. Healthy discussions and technical disagreements are welcome only when handled with professionalism.
|
||||
- **Respect contributors' time and efforts.** No one is entitled to personalized or on-demand assistance. This is a community built on collaboration and shared effort; demanding or demeaning behavior undermines that trust and will not be allowed.
|
||||
|
||||
### Zero Tolerance: No Warnings, Immediate Action
|
||||
|
||||
This community operates under a **zero-tolerance policy.** Any behavior deemed unacceptable under this Code of Conduct will result in **immediate enforcement, without prior warning.**
|
||||
|
||||
We employ this approach to ensure that unproductive or disruptive behavior does not escalate further or cause unnecessary harm to other contributors. The standards are clear, and violations of any kind—whether mild or severe—will be addressed decisively to protect the community.
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
Community leaders are responsible for upholding and enforcing these standards. They are empowered to take **immediate and appropriate action** to address any behaviors they deem unacceptable under this Code of Conduct. These actions are taken with the goal of protecting the community and preserving its safe, positive, and productive environment.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
This Code of Conduct applies to all community spaces, including forums, repositories, social media accounts, and in-person events. It also applies when an individual represents the community in public settings, such as conferences or official communications.
|
||||
|
||||
## Enforcement
|
||||
Additionally, any behavior outside of these defined spaces that negatively impacts the community or its members may fall within the scope of this Code of Conduct.
|
||||
|
||||
Instances of abusive, harassing, spamming, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at hello@openwebui.com. All complaints will be reviewed and investigated promptly and fairly.
|
||||
## Reporting Violations
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
||||
Instances of unacceptable behavior can be reported to the leadership team at **hello@openwebui.com**. Reports will be handled promptly, confidentially, and with consideration for the safety and well-being of the reporter.
|
||||
|
||||
All community leaders are required to uphold confidentiality and impartiality when addressing reports of violations.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
||||
### Ban
|
||||
|
||||
### 1. Temporary Ban
|
||||
**Community Impact**: Community leaders will issue a ban to any participant whose behavior is deemed unacceptable according to this Code of Conduct. Bans are enforced immediately and without prior notice.
|
||||
|
||||
**Community Impact**: Any violation of community standards, including but not limited to inappropriate language, unprofessional behavior, harassment, or spamming.
|
||||
A ban may be temporary or permanent, depending on the severity of the violation. This includes—but is not limited to—behavior such as:
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
||||
- Harassment or abusive behavior toward contributors.
|
||||
- Persistent negativity or hostility that disrupts the collaborative environment.
|
||||
- Disrespectful, demanding, or aggressive interactions with others.
|
||||
- Attempts to cause harm or sabotage the community.
|
||||
|
||||
### 2. Permanent Ban
|
||||
**Consequence**: A banned individual is immediately removed from access to all community spaces, communication channels, and events. Community leaders reserve the right to enforce either a time-limited suspension or a permanent ban based on the specific circumstances of the violation.
|
||||
|
||||
**Community Impact**: Repeated or severe violations of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
This approach ensures that disruptive behaviors are addressed swiftly and decisively in order to maintain the integrity and productivity of the community.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
## Why Zero Tolerance Is Necessary
|
||||
|
||||
Open-source projects thrive on collaboration, goodwill, and mutual respect. Toxic behaviors—such as entitlement, hostility, or persistent negativity—threaten not just individual contributors but the health of the project as a whole. Allowing such behaviors to persist robs contributors of their time, energy, and enthusiasm for the work they do.
|
||||
|
||||
By enforcing a zero-tolerance policy, we ensure that the community remains a safe, welcoming space for all participants. These measures are not about harshness—they are about protecting contributors and fostering a productive environment where innovation can thrive.
|
||||
|
||||
Our expectations are clear, and our enforcement reflects our commitment to this project's long-term success.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
|
||||
@@ -21,7 +21,7 @@ Open WebUI is an [extensible](https://github.com/open-webui/pipelines), feature-
|
||||
|
||||
- 🤝 **Ollama/OpenAI API Integration**: Effortlessly integrate OpenAI-compatible APIs for versatile conversations alongside Ollama models. Customize the OpenAI API URL to link with **LMStudio, GroqCloud, Mistral, OpenRouter, and more**.
|
||||
|
||||
- 🧩 **Pipelines, Open WebUI Plugin Support**: Seamlessly integrate custom logic and Python libraries into Open WebUI using [Pipelines Plugin Framework](https://github.com/open-webui/pipelines). Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. [Examples](https://github.com/open-webui/pipelines/tree/main/examples) include **Function Calling**, User **Rate Limiting** to control access, **Usage Monitoring** with tools like Langfuse, **Live Translation with LibreTranslate** for multilingual support, **Toxic Message Filtering** and much more.
|
||||
- 🛡️ **Granular Permissions and User Groups**: By allowing administrators to create detailed user roles and permissions, we ensure a secure user environment. This granularity not only enhances security but also allows for customized user experiences, fostering a sense of ownership and responsibility amongst users.
|
||||
|
||||
- 📱 **Responsive Design**: Enjoy a seamless experience across Desktop PC, Laptop, and Mobile devices.
|
||||
|
||||
@@ -49,6 +49,8 @@ Open WebUI is an [extensible](https://github.com/open-webui/pipelines), feature-
|
||||
|
||||
- 🌐🌍 **Multilingual Support**: Experience Open WebUI in your preferred language with our internationalization (i18n) support. Join us in expanding our supported languages! We're actively seeking contributors!
|
||||
|
||||
- 🧩 **Pipelines, Open WebUI Plugin Support**: Seamlessly integrate custom logic and Python libraries into Open WebUI using [Pipelines Plugin Framework](https://github.com/open-webui/pipelines). Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. [Examples](https://github.com/open-webui/pipelines/tree/main/examples) include **Function Calling**, User **Rate Limiting** to control access, **Usage Monitoring** with tools like Langfuse, **Live Translation with LibreTranslate** for multilingual support, **Toxic Message Filtering** and much more.
|
||||
|
||||
- 🌟 **Continuous Updates**: We are committed to improving Open WebUI with regular updates, fixes, and new features.
|
||||
|
||||
Want to learn more about Open WebUI's features? Check out our [Open WebUI documentation](https://docs.openwebui.com/features) for a comprehensive overview!
|
||||
|
||||
@@ -8,6 +8,8 @@ from pathlib import Path
|
||||
from pydub import AudioSegment
|
||||
from pydub.silence import split_on_silence
|
||||
|
||||
import aiohttp
|
||||
import aiofiles
|
||||
import requests
|
||||
from open_webui.config import (
|
||||
AUDIO_STT_ENGINE,
|
||||
@@ -292,46 +294,39 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
r = None
|
||||
try:
|
||||
r = requests.post(
|
||||
url=f"{app.state.config.TTS_OPENAI_API_BASE_URL}/audio/speech",
|
||||
data=body,
|
||||
headers=headers,
|
||||
stream=True,
|
||||
)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(
|
||||
url=f"{app.state.config.TTS_OPENAI_API_BASE_URL}/audio/speech",
|
||||
data=body,
|
||||
headers=headers,
|
||||
) as r:
|
||||
r.raise_for_status()
|
||||
async with aiofiles.open(file_path, "wb") as f:
|
||||
await f.write(await r.read())
|
||||
|
||||
r.raise_for_status()
|
||||
async with aiofiles.open(file_body_path, "w") as f:
|
||||
await f.write(json.dumps(json.loads(body.decode("utf-8"))))
|
||||
|
||||
# Save the streaming content to a file
|
||||
with open(file_path, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
with open(file_body_path, "w") as f:
|
||||
json.dump(json.loads(body.decode("utf-8")), f)
|
||||
|
||||
# Return the saved file
|
||||
return FileResponse(file_path)
|
||||
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
error_detail = "Open WebUI: Server Connection Error"
|
||||
if r is not None:
|
||||
try:
|
||||
res = r.json()
|
||||
try:
|
||||
if r.status != 200:
|
||||
res = await r.json()
|
||||
if "error" in res:
|
||||
error_detail = f"External: {res['error']['message']}"
|
||||
except Exception:
|
||||
error_detail = f"External: {e}"
|
||||
except Exception:
|
||||
error_detail = f"External: {e}"
|
||||
|
||||
raise HTTPException(
|
||||
status_code=r.status_code if r != None else 500,
|
||||
status_code=getattr(r, "status", 500),
|
||||
detail=error_detail,
|
||||
)
|
||||
|
||||
elif app.state.config.TTS_ENGINE == "elevenlabs":
|
||||
payload = None
|
||||
try:
|
||||
payload = json.loads(body.decode("utf-8"))
|
||||
except Exception as e:
|
||||
@@ -339,7 +334,6 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
raise HTTPException(status_code=400, detail="Invalid JSON payload")
|
||||
|
||||
voice_id = payload.get("voice", "")
|
||||
|
||||
if voice_id not in get_available_voices():
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
@@ -347,13 +341,11 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
)
|
||||
|
||||
url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}"
|
||||
|
||||
headers = {
|
||||
"Accept": "audio/mpeg",
|
||||
"Content-Type": "application/json",
|
||||
"xi-api-key": app.state.config.TTS_API_KEY,
|
||||
}
|
||||
|
||||
data = {
|
||||
"text": payload["input"],
|
||||
"model_id": app.state.config.TTS_MODEL,
|
||||
@@ -361,39 +353,34 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
}
|
||||
|
||||
try:
|
||||
r = requests.post(url, json=data, headers=headers)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, json=data, headers=headers) as r:
|
||||
r.raise_for_status()
|
||||
async with aiofiles.open(file_path, "wb") as f:
|
||||
await f.write(await r.read())
|
||||
|
||||
r.raise_for_status()
|
||||
async with aiofiles.open(file_body_path, "w") as f:
|
||||
await f.write(json.dumps(json.loads(body.decode("utf-8"))))
|
||||
|
||||
# Save the streaming content to a file
|
||||
with open(file_path, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
with open(file_body_path, "w") as f:
|
||||
json.dump(json.loads(body.decode("utf-8")), f)
|
||||
|
||||
# Return the saved file
|
||||
return FileResponse(file_path)
|
||||
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
error_detail = "Open WebUI: Server Connection Error"
|
||||
if r is not None:
|
||||
try:
|
||||
res = r.json()
|
||||
try:
|
||||
if r.status != 200:
|
||||
res = await r.json()
|
||||
if "error" in res:
|
||||
error_detail = f"External: {res['error']['message']}"
|
||||
except Exception:
|
||||
error_detail = f"External: {e}"
|
||||
except Exception:
|
||||
error_detail = f"External: {e}"
|
||||
|
||||
raise HTTPException(
|
||||
status_code=r.status_code if r != None else 500,
|
||||
status_code=getattr(r, "status", 500),
|
||||
detail=error_detail,
|
||||
)
|
||||
|
||||
elif app.state.config.TTS_ENGINE == "azure":
|
||||
payload = None
|
||||
try:
|
||||
payload = json.loads(body.decode("utf-8"))
|
||||
except Exception as e:
|
||||
@@ -416,17 +403,20 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
<voice name="{language}">{payload["input"]}</voice>
|
||||
</speak>"""
|
||||
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
|
||||
if response.status_code == 200:
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(response.content)
|
||||
return FileResponse(file_path)
|
||||
else:
|
||||
log.error(f"Error synthesizing speech - {response.reason}")
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"Error synthesizing speech - {response.reason}"
|
||||
)
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, headers=headers, data=data) as response:
|
||||
if response.status == 200:
|
||||
async with aiofiles.open(file_path, "wb") as f:
|
||||
await f.write(await response.read())
|
||||
return FileResponse(file_path)
|
||||
else:
|
||||
error_msg = f"Error synthesizing speech - {response.reason}"
|
||||
log.error(error_msg)
|
||||
raise HTTPException(status_code=500, detail=error_msg)
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
elif app.state.config.TTS_ENGINE == "transformers":
|
||||
payload = None
|
||||
try:
|
||||
|
||||
@@ -9,6 +9,8 @@ from typing import Optional, Union
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import aiohttp
|
||||
from aiocache import cached
|
||||
|
||||
import requests
|
||||
from open_webui.apps.webui.models.models import Models
|
||||
from open_webui.config import (
|
||||
@@ -193,7 +195,10 @@ async def post_streaming_url(
|
||||
trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT)
|
||||
)
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -208,13 +213,13 @@ async def post_streaming_url(
|
||||
r.raise_for_status()
|
||||
|
||||
if stream:
|
||||
headers = dict(r.headers)
|
||||
response_headers = dict(r.headers)
|
||||
if content_type:
|
||||
headers["Content-Type"] = content_type
|
||||
response_headers["Content-Type"] = content_type
|
||||
return StreamingResponse(
|
||||
r.content,
|
||||
status_code=r.status,
|
||||
headers=headers,
|
||||
headers=response_headers,
|
||||
background=BackgroundTask(
|
||||
cleanup_response, response=r, session=session
|
||||
),
|
||||
@@ -256,6 +261,7 @@ def merge_models_lists(model_lists):
|
||||
return list(merged_models.values())
|
||||
|
||||
|
||||
@cached(ttl=3)
|
||||
async def get_all_models():
|
||||
log.info("get_all_models()")
|
||||
if app.state.config.ENABLE_OLLAMA_API:
|
||||
@@ -295,8 +301,6 @@ async def get_all_models():
|
||||
for model in response.get("models", []):
|
||||
model["model"] = f"{prefix_id}.{model['model']}"
|
||||
|
||||
print(responses)
|
||||
|
||||
models = {
|
||||
"models": merge_models_lists(
|
||||
map(
|
||||
@@ -323,7 +327,10 @@ async def get_ollama_tags(
|
||||
else:
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {}
|
||||
@@ -524,7 +531,10 @@ async def copy_model(
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
log.info(f"url: {url}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -583,7 +593,10 @@ async def delete_model(
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
log.info(f"url: {url}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -634,7 +647,10 @@ async def show_model_info(form_data: ModelNameForm, user=Depends(get_verified_us
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
log.info(f"url: {url}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -729,7 +745,10 @@ async def generate_ollama_embeddings(
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
log.info(f"url: {url}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -796,7 +815,10 @@ async def generate_ollama_batch_embeddings(
|
||||
url = app.state.config.OLLAMA_BASE_URLS[url_idx]
|
||||
log.info(f"url: {url}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
key = api_config.get("key", None)
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
@@ -837,6 +859,7 @@ async def generate_ollama_batch_embeddings(
|
||||
class GenerateCompletionForm(BaseModel):
|
||||
model: str
|
||||
prompt: str
|
||||
suffix: Optional[str] = None
|
||||
images: Optional[list[str]] = None
|
||||
format: Optional[str] = None
|
||||
options: Optional[dict] = None
|
||||
@@ -972,7 +995,10 @@ async def generate_chat_completion(
|
||||
log.info(f"url: {url}")
|
||||
log.debug(f"generate_chat_completion() - 2.payload = {payload}")
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(url, {})
|
||||
parsed_url = urlparse(url)
|
||||
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
||||
|
||||
api_config = app.state.config.OLLAMA_API_CONFIGS.get(base_url, {})
|
||||
prefix_id = api_config.get("prefix_id", None)
|
||||
if prefix_id:
|
||||
payload["model"] = payload["model"].replace(f"{prefix_id}.", "")
|
||||
|
||||
@@ -6,7 +6,10 @@ from pathlib import Path
|
||||
from typing import Literal, Optional, overload
|
||||
|
||||
import aiohttp
|
||||
from aiocache import cached
|
||||
import requests
|
||||
|
||||
|
||||
from open_webui.apps.webui.models.models import Models
|
||||
from open_webui.config import (
|
||||
CACHE_DIR,
|
||||
@@ -302,6 +305,8 @@ async def get_all_models_responses() -> list:
|
||||
}
|
||||
|
||||
tasks.append(asyncio.ensure_future(asyncio.sleep(0, model_list)))
|
||||
else:
|
||||
tasks.append(asyncio.ensure_future(asyncio.sleep(0, None)))
|
||||
|
||||
responses = await asyncio.gather(*tasks)
|
||||
|
||||
@@ -313,7 +318,9 @@ async def get_all_models_responses() -> list:
|
||||
prefix_id = api_config.get("prefix_id", None)
|
||||
|
||||
if prefix_id:
|
||||
for model in response["data"]:
|
||||
for model in (
|
||||
response if isinstance(response, list) else response.get("data", [])
|
||||
):
|
||||
model["id"] = f"{prefix_id}.{model['id']}"
|
||||
|
||||
log.debug(f"get_all_models:responses() {responses}")
|
||||
@@ -321,6 +328,7 @@ async def get_all_models_responses() -> list:
|
||||
return responses
|
||||
|
||||
|
||||
@cached(ttl=3)
|
||||
async def get_all_models() -> dict[str, list]:
|
||||
log.info("get_all_models()")
|
||||
|
||||
@@ -577,8 +585,6 @@ async def generate_chat_completion(
|
||||
# Convert the modified body back to JSON
|
||||
payload = json.dumps(payload)
|
||||
|
||||
log.debug(payload)
|
||||
|
||||
headers = {}
|
||||
headers["Authorization"] = f"Bearer {key}"
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
from typing import Any, Dict, Generator, List, Optional, Sequence, Union
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
from langchain_core.documents import Document
|
||||
|
||||
|
||||
ALLOWED_SCHEMES = {"http", "https"}
|
||||
ALLOWED_NETLOCS = {
|
||||
"youtu.be",
|
||||
"m.youtube.com",
|
||||
"youtube.com",
|
||||
"www.youtube.com",
|
||||
"www.youtube-nocookie.com",
|
||||
"vid.plus",
|
||||
}
|
||||
|
||||
|
||||
def _parse_video_id(url: str) -> Optional[str]:
|
||||
"""Parse a YouTube URL and return the video ID if valid, otherwise None."""
|
||||
parsed_url = urlparse(url)
|
||||
|
||||
if parsed_url.scheme not in ALLOWED_SCHEMES:
|
||||
return None
|
||||
|
||||
if parsed_url.netloc not in ALLOWED_NETLOCS:
|
||||
return None
|
||||
|
||||
path = parsed_url.path
|
||||
|
||||
if path.endswith("/watch"):
|
||||
query = parsed_url.query
|
||||
parsed_query = parse_qs(query)
|
||||
if "v" in parsed_query:
|
||||
ids = parsed_query["v"]
|
||||
video_id = ids if isinstance(ids, str) else ids[0]
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
path = parsed_url.path.lstrip("/")
|
||||
video_id = path.split("/")[-1]
|
||||
|
||||
if len(video_id) != 11: # Video IDs are 11 characters long
|
||||
return None
|
||||
|
||||
return video_id
|
||||
|
||||
|
||||
class YoutubeLoader:
|
||||
"""Load `YouTube` video transcripts."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
video_id: str,
|
||||
language: Union[str, Sequence[str]] = "en",
|
||||
):
|
||||
"""Initialize with YouTube video ID."""
|
||||
_video_id = _parse_video_id(video_id)
|
||||
self.video_id = _video_id if _video_id is not None else video_id
|
||||
self._metadata = {"source": video_id}
|
||||
self.language = language
|
||||
if isinstance(language, str):
|
||||
self.language = [language]
|
||||
else:
|
||||
self.language = language
|
||||
|
||||
def load(self) -> List[Document]:
|
||||
"""Load YouTube transcripts into `Document` objects."""
|
||||
try:
|
||||
from youtube_transcript_api import (
|
||||
NoTranscriptFound,
|
||||
TranscriptsDisabled,
|
||||
YouTubeTranscriptApi,
|
||||
)
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
'Could not import "youtube_transcript_api" Python package. '
|
||||
"Please install it with `pip install youtube-transcript-api`."
|
||||
)
|
||||
|
||||
try:
|
||||
transcript_list = YouTubeTranscriptApi.list_transcripts(self.video_id)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return []
|
||||
|
||||
try:
|
||||
transcript = transcript_list.find_transcript(self.language)
|
||||
except NoTranscriptFound:
|
||||
transcript = transcript_list.find_transcript(["en"])
|
||||
|
||||
transcript_pieces: List[Dict[str, Any]] = transcript.fetch()
|
||||
|
||||
transcript = " ".join(
|
||||
map(
|
||||
lambda transcript_piece: transcript_piece["text"].strip(" "),
|
||||
transcript_pieces,
|
||||
)
|
||||
)
|
||||
return [Document(page_content=transcript, metadata=self._metadata)]
|
||||
@@ -23,11 +23,13 @@ from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
||||
|
||||
# Document loaders
|
||||
from open_webui.apps.retrieval.loaders.main import Loader
|
||||
from open_webui.apps.retrieval.loaders.youtube import YoutubeLoader
|
||||
|
||||
# Web search engines
|
||||
from open_webui.apps.retrieval.web.main import SearchResult
|
||||
from open_webui.apps.retrieval.web.utils import get_web_loader
|
||||
from open_webui.apps.retrieval.web.brave import search_brave
|
||||
from open_webui.apps.retrieval.web.mojeek import search_mojeek
|
||||
from open_webui.apps.retrieval.web.duckduckgo import search_duckduckgo
|
||||
from open_webui.apps.retrieval.web.google_pse import search_google_pse
|
||||
from open_webui.apps.retrieval.web.jina_search import search_jina
|
||||
@@ -52,6 +54,7 @@ from open_webui.apps.retrieval.utils import (
|
||||
from open_webui.apps.webui.models.files import Files
|
||||
from open_webui.config import (
|
||||
BRAVE_SEARCH_API_KEY,
|
||||
MOJEEK_SEARCH_API_KEY,
|
||||
TIKTOKEN_ENCODING_NAME,
|
||||
RAG_TEXT_SPLITTER,
|
||||
CHUNK_OVERLAP,
|
||||
@@ -120,9 +123,6 @@ from open_webui.utils.misc import (
|
||||
from open_webui.utils.utils import get_admin_user, get_verified_user
|
||||
|
||||
from langchain.text_splitter import RecursiveCharacterTextSplitter, TokenTextSplitter
|
||||
from langchain_community.document_loaders import (
|
||||
YoutubeLoader,
|
||||
)
|
||||
from langchain_core.documents import Document
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ app.state.config.SEARXNG_QUERY_URL = SEARXNG_QUERY_URL
|
||||
app.state.config.GOOGLE_PSE_API_KEY = GOOGLE_PSE_API_KEY
|
||||
app.state.config.GOOGLE_PSE_ENGINE_ID = GOOGLE_PSE_ENGINE_ID
|
||||
app.state.config.BRAVE_SEARCH_API_KEY = BRAVE_SEARCH_API_KEY
|
||||
app.state.config.MOJEEK_SEARCH_API_KEY = MOJEEK_SEARCH_API_KEY
|
||||
app.state.config.SERPSTACK_API_KEY = SERPSTACK_API_KEY
|
||||
app.state.config.SERPSTACK_HTTPS = SERPSTACK_HTTPS
|
||||
app.state.config.SERPER_API_KEY = SERPER_API_KEY
|
||||
@@ -480,6 +481,7 @@ async def get_rag_config(user=Depends(get_admin_user)):
|
||||
"google_pse_api_key": app.state.config.GOOGLE_PSE_API_KEY,
|
||||
"google_pse_engine_id": app.state.config.GOOGLE_PSE_ENGINE_ID,
|
||||
"brave_search_api_key": app.state.config.BRAVE_SEARCH_API_KEY,
|
||||
"mojeek_search_api_key": app.state.config.MOJEEK_SEARCH_API_KEY,
|
||||
"serpstack_api_key": app.state.config.SERPSTACK_API_KEY,
|
||||
"serpstack_https": app.state.config.SERPSTACK_HTTPS,
|
||||
"serper_api_key": app.state.config.SERPER_API_KEY,
|
||||
@@ -525,6 +527,7 @@ class WebSearchConfig(BaseModel):
|
||||
google_pse_api_key: Optional[str] = None
|
||||
google_pse_engine_id: Optional[str] = None
|
||||
brave_search_api_key: Optional[str] = None
|
||||
mojeek_search_api_key: Optional[str] = None
|
||||
serpstack_api_key: Optional[str] = None
|
||||
serpstack_https: Optional[bool] = None
|
||||
serper_api_key: Optional[str] = None
|
||||
@@ -595,6 +598,9 @@ async def update_rag_config(form_data: ConfigUpdateForm, user=Depends(get_admin_
|
||||
app.state.config.BRAVE_SEARCH_API_KEY = (
|
||||
form_data.web.search.brave_search_api_key
|
||||
)
|
||||
app.state.config.MOJEEK_SEARCH_API_KEY = (
|
||||
form_data.web.search.mojeek_search_api_key
|
||||
)
|
||||
app.state.config.SERPSTACK_API_KEY = form_data.web.search.serpstack_api_key
|
||||
app.state.config.SERPSTACK_HTTPS = form_data.web.search.serpstack_https
|
||||
app.state.config.SERPER_API_KEY = form_data.web.search.serper_api_key
|
||||
@@ -645,6 +651,7 @@ async def update_rag_config(form_data: ConfigUpdateForm, user=Depends(get_admin_
|
||||
"google_pse_api_key": app.state.config.GOOGLE_PSE_API_KEY,
|
||||
"google_pse_engine_id": app.state.config.GOOGLE_PSE_ENGINE_ID,
|
||||
"brave_search_api_key": app.state.config.BRAVE_SEARCH_API_KEY,
|
||||
"mojeek_search_api_key": app.state.config.MOJEEK_SEARCH_API_KEY,
|
||||
"serpstack_api_key": app.state.config.SERPSTACK_API_KEY,
|
||||
"serpstack_https": app.state.config.SERPSTACK_HTTPS,
|
||||
"serper_api_key": app.state.config.SERPER_API_KEY,
|
||||
@@ -886,19 +893,17 @@ def process_file(
|
||||
# Update the content in the file
|
||||
# Usage: /files/{file_id}/data/content/update
|
||||
|
||||
VECTOR_DB_CLIENT.delete(
|
||||
collection_name=f"file-{file.id}",
|
||||
filter={"file_id": file.id},
|
||||
)
|
||||
VECTOR_DB_CLIENT.delete_collection(collection_name=f"file-{file.id}")
|
||||
|
||||
docs = [
|
||||
Document(
|
||||
page_content=form_data.content,
|
||||
metadata={
|
||||
"name": file.meta.get("name", file.filename),
|
||||
**file.meta,
|
||||
"name": file.filename,
|
||||
"created_by": file.user_id,
|
||||
"file_id": file.id,
|
||||
**file.meta,
|
||||
"source": file.filename,
|
||||
},
|
||||
)
|
||||
]
|
||||
@@ -925,10 +930,11 @@ def process_file(
|
||||
Document(
|
||||
page_content=file.data.get("content", ""),
|
||||
metadata={
|
||||
"name": file.meta.get("name", file.filename),
|
||||
**file.meta,
|
||||
"name": file.filename,
|
||||
"created_by": file.user_id,
|
||||
"file_id": file.id,
|
||||
**file.meta,
|
||||
"source": file.filename,
|
||||
},
|
||||
)
|
||||
]
|
||||
@@ -948,15 +954,30 @@ def process_file(
|
||||
docs = loader.load(
|
||||
file.filename, file.meta.get("content_type"), file_path
|
||||
)
|
||||
|
||||
docs = [
|
||||
Document(
|
||||
page_content=doc.page_content,
|
||||
metadata={
|
||||
**doc.metadata,
|
||||
"name": file.filename,
|
||||
"created_by": file.user_id,
|
||||
"file_id": file.id,
|
||||
"source": file.filename,
|
||||
},
|
||||
)
|
||||
for doc in docs
|
||||
]
|
||||
else:
|
||||
docs = [
|
||||
Document(
|
||||
page_content=file.data.get("content", ""),
|
||||
metadata={
|
||||
**file.meta,
|
||||
"name": file.filename,
|
||||
"created_by": file.user_id,
|
||||
"file_id": file.id,
|
||||
**file.meta,
|
||||
"source": file.filename,
|
||||
},
|
||||
)
|
||||
]
|
||||
@@ -977,7 +998,7 @@ def process_file(
|
||||
collection_name=collection_name,
|
||||
metadata={
|
||||
"file_id": file.id,
|
||||
"name": file.meta.get("name", file.filename),
|
||||
"name": file.filename,
|
||||
"hash": hash,
|
||||
},
|
||||
add=(True if form_data.collection_name else False),
|
||||
@@ -994,7 +1015,7 @@ def process_file(
|
||||
return {
|
||||
"status": True,
|
||||
"collection_name": collection_name,
|
||||
"filename": file.meta.get("name", file.filename),
|
||||
"filename": file.filename,
|
||||
"content": text_content,
|
||||
}
|
||||
except Exception as e:
|
||||
@@ -1059,12 +1080,10 @@ def process_youtube_video(form_data: ProcessUrlForm, user=Depends(get_verified_u
|
||||
if not collection_name:
|
||||
collection_name = calculate_sha256_string(form_data.url)[:63]
|
||||
|
||||
loader = YoutubeLoader.from_youtube_url(
|
||||
form_data.url,
|
||||
add_video_info=False,
|
||||
language=app.state.config.YOUTUBE_LOADER_LANGUAGE,
|
||||
translation=app.state.YOUTUBE_LOADER_TRANSLATION,
|
||||
loader = YoutubeLoader(
|
||||
form_data.url, language=app.state.config.YOUTUBE_LOADER_LANGUAGE
|
||||
)
|
||||
|
||||
docs = loader.load()
|
||||
content = " ".join([doc.page_content for doc in docs])
|
||||
log.debug(f"text_content: {content}")
|
||||
@@ -1135,6 +1154,7 @@ def search_web(engine: str, query: str) -> list[SearchResult]:
|
||||
- SEARXNG_QUERY_URL
|
||||
- GOOGLE_PSE_API_KEY + GOOGLE_PSE_ENGINE_ID
|
||||
- BRAVE_SEARCH_API_KEY
|
||||
- MOJEEK_SEARCH_API_KEY
|
||||
- SERPSTACK_API_KEY
|
||||
- SERPER_API_KEY
|
||||
- SERPLY_API_KEY
|
||||
@@ -1181,6 +1201,16 @@ def search_web(engine: str, query: str) -> list[SearchResult]:
|
||||
)
|
||||
else:
|
||||
raise Exception("No BRAVE_SEARCH_API_KEY found in environment variables")
|
||||
elif engine == "mojeek":
|
||||
if app.state.config.MOJEEK_SEARCH_API_KEY:
|
||||
return search_mojeek(
|
||||
app.state.config.MOJEEK_SEARCH_API_KEY,
|
||||
query,
|
||||
app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
|
||||
app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST,
|
||||
)
|
||||
else:
|
||||
raise Exception("No MOJEEK_SEARCH_API_KEY found in environment variables")
|
||||
elif engine == "serpstack":
|
||||
if app.state.config.SERPSTACK_API_KEY:
|
||||
return search_serpstack(
|
||||
|
||||
@@ -15,8 +15,6 @@ from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
||||
from open_webui.utils.misc import get_last_user_message
|
||||
|
||||
from open_webui.env import SRC_LOG_LEVELS
|
||||
from open_webui.config import DEFAULT_RAG_TEMPLATE
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["RAG"])
|
||||
@@ -238,44 +236,6 @@ def query_collection_with_hybrid_search(
|
||||
return merge_and_sort_query_results(results, k=k, reverse=True)
|
||||
|
||||
|
||||
def rag_template(template: str, context: str, query: str):
|
||||
if template == "":
|
||||
template = DEFAULT_RAG_TEMPLATE
|
||||
|
||||
if "[context]" not in template and "{{CONTEXT}}" not in template:
|
||||
log.debug(
|
||||
"WARNING: The RAG template does not contain the '[context]' or '{{CONTEXT}}' placeholder."
|
||||
)
|
||||
|
||||
if "<context>" in context and "</context>" in context:
|
||||
log.debug(
|
||||
"WARNING: Potential prompt injection attack: the RAG "
|
||||
"context contains '<context>' and '</context>'. This might be "
|
||||
"nothing, or the user might be trying to hack something."
|
||||
)
|
||||
|
||||
query_placeholders = []
|
||||
if "[query]" in context:
|
||||
query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}"
|
||||
template = template.replace("[query]", query_placeholder)
|
||||
query_placeholders.append(query_placeholder)
|
||||
|
||||
if "{{QUERY}}" in context:
|
||||
query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}"
|
||||
template = template.replace("{{QUERY}}", query_placeholder)
|
||||
query_placeholders.append(query_placeholder)
|
||||
|
||||
template = template.replace("[context]", context)
|
||||
template = template.replace("{{CONTEXT}}", context)
|
||||
template = template.replace("[query]", query)
|
||||
template = template.replace("{{QUERY}}", query)
|
||||
|
||||
for query_placeholder in query_placeholders:
|
||||
template = template.replace(query_placeholder, query)
|
||||
|
||||
return template
|
||||
|
||||
|
||||
def get_embedding_function(
|
||||
embedding_engine,
|
||||
embedding_model,
|
||||
@@ -307,7 +267,7 @@ def get_embedding_function(
|
||||
return lambda query: generate_multiple(query, func)
|
||||
|
||||
|
||||
def get_rag_context(
|
||||
def get_sources_from_files(
|
||||
files,
|
||||
queries,
|
||||
embedding_function,
|
||||
@@ -387,43 +347,24 @@ def get_rag_context(
|
||||
del file["data"]
|
||||
relevant_contexts.append({**context, "file": file})
|
||||
|
||||
contexts = []
|
||||
citations = []
|
||||
sources = []
|
||||
for context in relevant_contexts:
|
||||
try:
|
||||
if "documents" in context:
|
||||
file_names = list(
|
||||
set(
|
||||
[
|
||||
metadata["name"]
|
||||
for metadata in context["metadatas"][0]
|
||||
if metadata is not None and "name" in metadata
|
||||
]
|
||||
)
|
||||
)
|
||||
contexts.append(
|
||||
((", ".join(file_names) + ":\n\n") if file_names else "")
|
||||
+ "\n\n".join(
|
||||
[text for text in context["documents"][0] if text is not None]
|
||||
)
|
||||
)
|
||||
|
||||
if "metadatas" in context:
|
||||
citation = {
|
||||
source = {
|
||||
"source": context["file"],
|
||||
"document": context["documents"][0],
|
||||
"metadata": context["metadatas"][0],
|
||||
}
|
||||
if "distances" in context and context["distances"]:
|
||||
citation["distances"] = context["distances"][0]
|
||||
citations.append(citation)
|
||||
source["distances"] = context["distances"][0]
|
||||
|
||||
sources.append(source)
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
||||
print("contexts", contexts)
|
||||
print("citations", citations)
|
||||
|
||||
return contexts, citations
|
||||
return sources
|
||||
|
||||
|
||||
def get_model_path(model: str, update_model: bool = False):
|
||||
@@ -488,7 +429,7 @@ def generate_openai_batch_embeddings(
|
||||
|
||||
|
||||
def generate_ollama_batch_embeddings(
|
||||
model: str, texts: list[str], url: str, key: str
|
||||
model: str, texts: list[str], url: str, key: str = ""
|
||||
) -> Optional[list[list[float]]]:
|
||||
try:
|
||||
r = requests.post(
|
||||
@@ -502,7 +443,6 @@ def generate_ollama_batch_embeddings(
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
|
||||
print(data)
|
||||
if "embeddings" in data:
|
||||
return data["embeddings"]
|
||||
else:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from opensearchpy import OpenSearch
|
||||
from typing import Optional
|
||||
|
||||
from open_webui.apps.rag.vector.main import VectorItem, SearchResult, GetResult
|
||||
from open_webui.apps.retrieval.vector.main import VectorItem, SearchResult, GetResult
|
||||
from open_webui.config import (
|
||||
OPENSEARCH_URI,
|
||||
OPENSEARCH_SSL,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
from open_webui.apps.retrieval.web.main import SearchResult, get_filtered_results
|
||||
from open_webui.env import SRC_LOG_LEVELS
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["RAG"])
|
||||
|
||||
|
||||
def search_mojeek(
|
||||
api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None
|
||||
) -> list[SearchResult]:
|
||||
"""Search using Mojeek's Search API and return the results as a list of SearchResult objects.
|
||||
|
||||
Args:
|
||||
api_key (str): A Mojeek Search API key
|
||||
query (str): The query to search for
|
||||
"""
|
||||
url = "https://api.mojeek.com/search"
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
}
|
||||
params = {"q": query, "api_key": api_key, "fmt": "json", "t": count}
|
||||
|
||||
response = requests.get(url, headers=headers, params=params)
|
||||
response.raise_for_status()
|
||||
json_response = response.json()
|
||||
results = json_response.get("response", {}).get("results", [])
|
||||
print(results)
|
||||
if filter_list:
|
||||
results = get_filtered_results(results, filter_list)
|
||||
|
||||
return [
|
||||
SearchResult(
|
||||
link=result["url"], title=result.get("title"), snippet=result.get("desc")
|
||||
)
|
||||
for result in results
|
||||
]
|
||||
@@ -31,6 +31,7 @@ from open_webui.config import (
|
||||
DEFAULT_MODELS,
|
||||
DEFAULT_PROMPT_SUGGESTIONS,
|
||||
DEFAULT_USER_ROLE,
|
||||
MODEL_ORDER_LIST,
|
||||
ENABLE_COMMUNITY_SHARING,
|
||||
ENABLE_LOGIN_FORM,
|
||||
ENABLE_MESSAGE_RATING,
|
||||
@@ -68,6 +69,7 @@ from open_webui.config import (
|
||||
)
|
||||
from open_webui.env import (
|
||||
ENV,
|
||||
SRC_LOG_LEVELS,
|
||||
WEBUI_AUTH_TRUSTED_EMAIL_HEADER,
|
||||
WEBUI_AUTH_TRUSTED_NAME_HEADER,
|
||||
)
|
||||
@@ -94,6 +96,7 @@ app = FastAPI(
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["MAIN"])
|
||||
|
||||
app.state.config = AppConfig()
|
||||
|
||||
@@ -118,6 +121,7 @@ app.state.config.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE
|
||||
app.state.config.USER_PERMISSIONS = USER_PERMISSIONS
|
||||
app.state.config.WEBHOOK_URL = WEBHOOK_URL
|
||||
app.state.config.BANNERS = WEBUI_BANNERS
|
||||
app.state.config.MODEL_ORDER_LIST = MODEL_ORDER_LIST
|
||||
|
||||
app.state.config.ENABLE_COMMUNITY_SHARING = ENABLE_COMMUNITY_SHARING
|
||||
app.state.config.ENABLE_MESSAGE_RATING = ENABLE_MESSAGE_RATING
|
||||
@@ -270,7 +274,9 @@ async def get_pipe_models():
|
||||
log.exception(e)
|
||||
sub_pipes = []
|
||||
|
||||
print(sub_pipes)
|
||||
log.debug(
|
||||
f"get_pipe_models: function '{pipe.id}' is a manifold of {sub_pipes}"
|
||||
)
|
||||
|
||||
for p in sub_pipes:
|
||||
sub_pipe_id = f'{pipe.id}.{p["id"]}'
|
||||
@@ -280,6 +286,7 @@ async def get_pipe_models():
|
||||
sub_pipe_name = f"{function_module.name}{sub_pipe_name}"
|
||||
|
||||
pipe_flag = {"type": pipe.type}
|
||||
|
||||
pipe_models.append(
|
||||
{
|
||||
"id": sub_pipe_id,
|
||||
@@ -293,6 +300,10 @@ async def get_pipe_models():
|
||||
else:
|
||||
pipe_flag = {"type": "pipe"}
|
||||
|
||||
log.debug(
|
||||
f"get_pipe_models: function '{pipe.id}' is a single pipe {{ 'id': {pipe.id}, 'name': {pipe.name} }}"
|
||||
)
|
||||
|
||||
pipe_models.append(
|
||||
{
|
||||
"id": pipe.id,
|
||||
@@ -346,7 +357,7 @@ def get_pipe_id(form_data: dict) -> str:
|
||||
pipe_id = form_data["model"]
|
||||
if "." in pipe_id:
|
||||
pipe_id, _ = pipe_id.split(".", 1)
|
||||
print(pipe_id)
|
||||
|
||||
return pipe_id
|
||||
|
||||
|
||||
@@ -453,7 +464,7 @@ async def generate_function_chat_completion(form_data, user, models: dict = {}):
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
log.error(f"Error: {e}")
|
||||
yield f"data: {json.dumps({'error': {'detail':str(e)}})}\n\n"
|
||||
return
|
||||
|
||||
@@ -483,7 +494,7 @@ async def generate_function_chat_completion(form_data, user, models: dict = {}):
|
||||
res = await execute_pipe(pipe, params)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
log.error(f"Error: {e}")
|
||||
return {"error": {"detail": str(e)}}
|
||||
|
||||
if isinstance(res, StreamingResponse) or isinstance(res, dict):
|
||||
|
||||
@@ -128,17 +128,20 @@ class KnowledgeTable:
|
||||
|
||||
def get_knowledge_bases(self) -> list[KnowledgeUserModel]:
|
||||
with get_db() as db:
|
||||
return [
|
||||
KnowledgeUserModel.model_validate(
|
||||
{
|
||||
**KnowledgeModel.model_validate(knowledge).model_dump(),
|
||||
"user": Users.get_user_by_id(knowledge.user_id).model_dump(),
|
||||
}
|
||||
knowledge_bases = []
|
||||
for knowledge in (
|
||||
db.query(Knowledge).order_by(Knowledge.updated_at.desc()).all()
|
||||
):
|
||||
user = Users.get_user_by_id(knowledge.user_id)
|
||||
knowledge_bases.append(
|
||||
KnowledgeUserModel.model_validate(
|
||||
{
|
||||
**KnowledgeModel.model_validate(knowledge).model_dump(),
|
||||
"user": user.model_dump() if user else None,
|
||||
}
|
||||
)
|
||||
)
|
||||
for knowledge in db.query(Knowledge)
|
||||
.order_by(Knowledge.updated_at.desc())
|
||||
.all()
|
||||
]
|
||||
return knowledge_bases
|
||||
|
||||
def get_knowledge_bases_by_user_id(
|
||||
self, user_id: str, permission: str = "write"
|
||||
|
||||
@@ -175,15 +175,18 @@ class ModelsTable:
|
||||
|
||||
def get_models(self) -> list[ModelUserResponse]:
|
||||
with get_db() as db:
|
||||
return [
|
||||
ModelUserResponse.model_validate(
|
||||
{
|
||||
**ModelModel.model_validate(model).model_dump(),
|
||||
"user": Users.get_user_by_id(model.user_id).model_dump(),
|
||||
}
|
||||
models = []
|
||||
for model in db.query(Model).filter(Model.base_model_id != None).all():
|
||||
user = Users.get_user_by_id(model.user_id)
|
||||
models.append(
|
||||
ModelUserResponse.model_validate(
|
||||
{
|
||||
**ModelModel.model_validate(model).model_dump(),
|
||||
"user": user.model_dump() if user else None,
|
||||
}
|
||||
)
|
||||
)
|
||||
for model in db.query(Model).filter(Model.base_model_id != None).all()
|
||||
]
|
||||
return models
|
||||
|
||||
def get_base_models(self) -> list[ModelModel]:
|
||||
with get_db() as db:
|
||||
|
||||
@@ -103,15 +103,20 @@ class PromptsTable:
|
||||
|
||||
def get_prompts(self) -> list[PromptUserResponse]:
|
||||
with get_db() as db:
|
||||
return [
|
||||
PromptUserResponse.model_validate(
|
||||
{
|
||||
**PromptModel.model_validate(prompt).model_dump(),
|
||||
"user": Users.get_user_by_id(prompt.user_id).model_dump(),
|
||||
}
|
||||
prompts = []
|
||||
|
||||
for prompt in db.query(Prompt).order_by(Prompt.timestamp.desc()).all():
|
||||
user = Users.get_user_by_id(prompt.user_id)
|
||||
prompts.append(
|
||||
PromptUserResponse.model_validate(
|
||||
{
|
||||
**PromptModel.model_validate(prompt).model_dump(),
|
||||
"user": user.model_dump() if user else None,
|
||||
}
|
||||
)
|
||||
)
|
||||
for prompt in db.query(Prompt).all()
|
||||
]
|
||||
|
||||
return prompts
|
||||
|
||||
def get_prompts_by_user_id(
|
||||
self, user_id: str, permission: str = "write"
|
||||
|
||||
@@ -140,15 +140,18 @@ class ToolsTable:
|
||||
|
||||
def get_tools(self) -> list[ToolUserResponse]:
|
||||
with get_db() as db:
|
||||
return [
|
||||
ToolUserResponse.model_validate(
|
||||
{
|
||||
**ToolModel.model_validate(tool).model_dump(),
|
||||
"user": Users.get_user_by_id(tool.user_id).model_dump(),
|
||||
}
|
||||
tools = []
|
||||
for tool in db.query(Tool).order_by(Tool.updated_at.desc()).all():
|
||||
user = Users.get_user_by_id(tool.user_id)
|
||||
tools.append(
|
||||
ToolUserResponse.model_validate(
|
||||
{
|
||||
**ToolModel.model_validate(tool).model_dump(),
|
||||
"user": user.model_dump() if user else None,
|
||||
}
|
||||
)
|
||||
)
|
||||
for tool in db.query(Tool).order_by(Tool.updated_at.desc()).all()
|
||||
]
|
||||
return tools
|
||||
|
||||
def get_tools_by_user_id(
|
||||
self, user_id: str, permission: str = "write"
|
||||
|
||||
@@ -238,10 +238,16 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
|
||||
|
||||
user = Users.get_user_by_email(mail)
|
||||
if not user:
|
||||
|
||||
try:
|
||||
hashed = get_password_hash(form_data.password)
|
||||
user = Auths.insert_new_auth(mail, hashed, cn)
|
||||
role = (
|
||||
"admin"
|
||||
if Users.get_num_users() == 0
|
||||
else request.app.state.config.DEFAULT_USER_ROLE
|
||||
)
|
||||
|
||||
user = Auths.insert_new_auth(
|
||||
email=mail, password=str(uuid.uuid4()), name=cn, role=role
|
||||
)
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
@@ -253,7 +259,7 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
|
||||
except Exception as err:
|
||||
raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))
|
||||
|
||||
user = Auths.authenticate_user(mail, password=str(form_data.password))
|
||||
user = Auths.authenticate_user_by_trusted_header(mail)
|
||||
|
||||
if user:
|
||||
token = create_token(
|
||||
@@ -738,8 +744,8 @@ async def update_ldap_config(
|
||||
|
||||
# create api key
|
||||
@router.post("/api_key", response_model=ApiKey)
|
||||
async def create_api_key(request: Request, user=Depends(get_current_user)):
|
||||
if not request.app.config.state.ENABLE_API_KEY:
|
||||
async def generate_api_key(request: Request, user=Depends(get_current_user)):
|
||||
if not request.app.state.config.ENABLE_API_KEY:
|
||||
raise HTTPException(
|
||||
status.HTTP_403_FORBIDDEN,
|
||||
detail=ERROR_MESSAGES.API_KEY_CREATION_NOT_ALLOWED,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from open_webui.config import BannerModel
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from pydantic import BaseModel
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from open_webui.utils.utils import get_admin_user, get_verified_user
|
||||
|
||||
|
||||
from open_webui.config import get_config, save_config
|
||||
from open_webui.config import BannerModel
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -34,8 +36,32 @@ async def export_config(user=Depends(get_admin_user)):
|
||||
return get_config()
|
||||
|
||||
|
||||
class SetDefaultModelsForm(BaseModel):
|
||||
models: str
|
||||
############################
|
||||
# SetDefaultModels
|
||||
############################
|
||||
class ModelsConfigForm(BaseModel):
|
||||
DEFAULT_MODELS: Optional[str]
|
||||
MODEL_ORDER_LIST: Optional[list[str]]
|
||||
|
||||
|
||||
@router.get("/models", response_model=ModelsConfigForm)
|
||||
async def get_models_config(request: Request, user=Depends(get_admin_user)):
|
||||
return {
|
||||
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
|
||||
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
|
||||
}
|
||||
|
||||
|
||||
@router.post("/models", response_model=ModelsConfigForm)
|
||||
async def set_models_config(
|
||||
request: Request, form_data: ModelsConfigForm, user=Depends(get_admin_user)
|
||||
):
|
||||
request.app.state.config.DEFAULT_MODELS = form_data.DEFAULT_MODELS
|
||||
request.app.state.config.MODEL_ORDER_LIST = form_data.MODEL_ORDER_LIST
|
||||
return {
|
||||
"DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS,
|
||||
"MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST,
|
||||
}
|
||||
|
||||
|
||||
class PromptSuggestion(BaseModel):
|
||||
@@ -47,21 +73,8 @@ class SetDefaultSuggestionsForm(BaseModel):
|
||||
suggestions: list[PromptSuggestion]
|
||||
|
||||
|
||||
############################
|
||||
# SetDefaultModels
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/default/models", response_model=str)
|
||||
async def set_global_default_models(
|
||||
request: Request, form_data: SetDefaultModelsForm, user=Depends(get_admin_user)
|
||||
):
|
||||
request.app.state.config.DEFAULT_MODELS = form_data.models
|
||||
return request.app.state.config.DEFAULT_MODELS
|
||||
|
||||
|
||||
@router.post("/default/suggestions", response_model=list[PromptSuggestion])
|
||||
async def set_global_default_suggestions(
|
||||
@router.post("/suggestions", response_model=list[PromptSuggestion])
|
||||
async def set_default_suggestions(
|
||||
request: Request,
|
||||
form_data: SetDefaultSuggestionsForm,
|
||||
user=Depends(get_admin_user),
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
import json
|
||||
from typing import Optional
|
||||
|
||||
from open_webui.apps.webui.models.documents import (
|
||||
DocumentForm,
|
||||
DocumentResponse,
|
||||
Documents,
|
||||
DocumentUpdateForm,
|
||||
)
|
||||
from open_webui.constants import ERROR_MESSAGES
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from pydantic import BaseModel
|
||||
from open_webui.utils.utils import get_admin_user, get_verified_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
############################
|
||||
# GetDocuments
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/", response_model=list[DocumentResponse])
|
||||
async def get_documents(user=Depends(get_verified_user)):
|
||||
docs = [
|
||||
DocumentResponse(
|
||||
**{
|
||||
**doc.model_dump(),
|
||||
"content": json.loads(doc.content if doc.content else "{}"),
|
||||
}
|
||||
)
|
||||
for doc in Documents.get_docs()
|
||||
]
|
||||
return docs
|
||||
|
||||
|
||||
############################
|
||||
# CreateNewDoc
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/create", response_model=Optional[DocumentResponse])
|
||||
async def create_new_doc(form_data: DocumentForm, user=Depends(get_admin_user)):
|
||||
doc = Documents.get_doc_by_name(form_data.name)
|
||||
if doc is None:
|
||||
doc = Documents.insert_new_doc(user.id, form_data)
|
||||
|
||||
if doc:
|
||||
return DocumentResponse(
|
||||
**{
|
||||
**doc.model_dump(),
|
||||
"content": json.loads(doc.content if doc.content else "{}"),
|
||||
}
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.FILE_EXISTS,
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.NAME_TAG_TAKEN,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# GetDocByName
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/doc", response_model=Optional[DocumentResponse])
|
||||
async def get_doc_by_name(name: str, user=Depends(get_verified_user)):
|
||||
doc = Documents.get_doc_by_name(name)
|
||||
|
||||
if doc:
|
||||
return DocumentResponse(
|
||||
**{
|
||||
**doc.model_dump(),
|
||||
"content": json.loads(doc.content if doc.content else "{}"),
|
||||
}
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# TagDocByName
|
||||
############################
|
||||
|
||||
|
||||
class TagItem(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class TagDocumentForm(BaseModel):
|
||||
name: str
|
||||
tags: list[dict]
|
||||
|
||||
|
||||
@router.post("/doc/tags", response_model=Optional[DocumentResponse])
|
||||
async def tag_doc_by_name(form_data: TagDocumentForm, user=Depends(get_verified_user)):
|
||||
doc = Documents.update_doc_content_by_name(form_data.name, {"tags": form_data.tags})
|
||||
|
||||
if doc:
|
||||
return DocumentResponse(
|
||||
**{
|
||||
**doc.model_dump(),
|
||||
"content": json.loads(doc.content if doc.content else "{}"),
|
||||
}
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# UpdateDocByName
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/doc/update", response_model=Optional[DocumentResponse])
|
||||
async def update_doc_by_name(
|
||||
name: str,
|
||||
form_data: DocumentUpdateForm,
|
||||
user=Depends(get_admin_user),
|
||||
):
|
||||
doc = Documents.update_doc_by_name(name, form_data)
|
||||
if doc:
|
||||
return DocumentResponse(
|
||||
**{
|
||||
**doc.model_dump(),
|
||||
"content": json.loads(doc.content if doc.content else "{}"),
|
||||
}
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.NAME_TAG_TAKEN,
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
# DeleteDocByName
|
||||
############################
|
||||
|
||||
|
||||
@router.delete("/doc/delete", response_model=bool)
|
||||
async def delete_doc_by_name(name: str, user=Depends(get_admin_user)):
|
||||
result = Documents.delete_doc_by_name(name)
|
||||
return result
|
||||
@@ -56,7 +56,7 @@ def upload_file(file: UploadFile = File(...), user=Depends(get_verified_user)):
|
||||
FileForm(
|
||||
**{
|
||||
"id": id,
|
||||
"filename": filename,
|
||||
"filename": name,
|
||||
"path": file_path,
|
||||
"meta": {
|
||||
"name": name,
|
||||
|
||||
@@ -43,6 +43,7 @@ async def get_knowledge(user=Depends(get_verified_user)):
|
||||
knowledge_bases = Knowledges.get_knowledge_bases_by_user_id(user.id, "read")
|
||||
|
||||
# Get files for each knowledge base
|
||||
knowledge_with_files = []
|
||||
for knowledge_base in knowledge_bases:
|
||||
files = []
|
||||
if knowledge_base.data:
|
||||
@@ -70,12 +71,14 @@ async def get_knowledge(user=Depends(get_verified_user)):
|
||||
|
||||
files = Files.get_file_metadatas_by_ids(file_ids)
|
||||
|
||||
knowledge_base = KnowledgeResponse(
|
||||
**knowledge_base.model_dump(),
|
||||
files=files,
|
||||
knowledge_with_files.append(
|
||||
KnowledgeUserResponse(
|
||||
**knowledge_base.model_dump(),
|
||||
files=files,
|
||||
)
|
||||
)
|
||||
|
||||
return knowledge_bases
|
||||
return knowledge_with_files
|
||||
|
||||
|
||||
@router.get("/list", response_model=list[KnowledgeUserResponse])
|
||||
@@ -88,6 +91,7 @@ async def get_knowledge_list(user=Depends(get_verified_user)):
|
||||
knowledge_bases = Knowledges.get_knowledge_bases_by_user_id(user.id, "write")
|
||||
|
||||
# Get files for each knowledge base
|
||||
knowledge_with_files = []
|
||||
for knowledge_base in knowledge_bases:
|
||||
files = []
|
||||
if knowledge_base.data:
|
||||
@@ -115,12 +119,13 @@ async def get_knowledge_list(user=Depends(get_verified_user)):
|
||||
|
||||
files = Files.get_file_metadatas_by_ids(file_ids)
|
||||
|
||||
knowledge_base = KnowledgeResponse(
|
||||
**knowledge_base.model_dump(),
|
||||
files=files,
|
||||
knowledge_with_files.append(
|
||||
KnowledgeUserResponse(
|
||||
**knowledge_base.model_dump(),
|
||||
files=files,
|
||||
)
|
||||
)
|
||||
|
||||
return knowledge_bases
|
||||
return knowledge_with_files
|
||||
|
||||
|
||||
############################
|
||||
|
||||
@@ -83,7 +83,8 @@ async def create_new_model(
|
||||
###########################
|
||||
|
||||
|
||||
@router.get("/id/{id}", response_model=Optional[ModelResponse])
|
||||
# Note: We're not using the typical url path param here, but instead using a query parameter to allow '/' in the id
|
||||
@router.get("/model", response_model=Optional[ModelResponse])
|
||||
async def get_model_by_id(id: str, user=Depends(get_verified_user)):
|
||||
model = Models.get_model_by_id(id)
|
||||
if model:
|
||||
@@ -105,7 +106,7 @@ async def get_model_by_id(id: str, user=Depends(get_verified_user)):
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/toggle", response_model=Optional[ModelResponse])
|
||||
@router.post("/model/toggle", response_model=Optional[ModelResponse])
|
||||
async def toggle_model_by_id(id: str, user=Depends(get_verified_user)):
|
||||
model = Models.get_model_by_id(id)
|
||||
if model:
|
||||
@@ -140,7 +141,7 @@ async def toggle_model_by_id(id: str, user=Depends(get_verified_user)):
|
||||
############################
|
||||
|
||||
|
||||
@router.post("/id/{id}/update", response_model=Optional[ModelModel])
|
||||
@router.post("/model/update", response_model=Optional[ModelModel])
|
||||
async def update_model_by_id(
|
||||
id: str,
|
||||
form_data: ModelForm,
|
||||
@@ -163,7 +164,7 @@ async def update_model_by_id(
|
||||
############################
|
||||
|
||||
|
||||
@router.delete("/id/{id}/delete", response_model=bool)
|
||||
@router.delete("/model/delete", response_model=bool)
|
||||
async def delete_model_by_id(id: str, user=Depends(get_verified_user)):
|
||||
model = Models.get_model_by_id(id)
|
||||
if not model:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
@@ -10,7 +9,7 @@ from open_webui.apps.webui.models.tools import (
|
||||
Tools,
|
||||
)
|
||||
from open_webui.apps.webui.utils import load_tools_module_by_id, replace_imports
|
||||
from open_webui.config import CACHE_DIR, DATA_DIR
|
||||
from open_webui.config import CACHE_DIR
|
||||
from open_webui.constants import ERROR_MESSAGES
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||
from open_webui.utils.tools import get_tools_specs
|
||||
@@ -300,38 +299,35 @@ async def update_tools_valves_by_id(
|
||||
request: Request, id: str, form_data: dict, user=Depends(get_verified_user)
|
||||
):
|
||||
tools = Tools.get_tool_by_id(id)
|
||||
if tools:
|
||||
if id in request.app.state.TOOLS:
|
||||
tools_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
tools_module, _ = load_tools_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = tools_module
|
||||
|
||||
if hasattr(tools_module, "Valves"):
|
||||
Valves = tools_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(str(e)),
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
|
||||
else:
|
||||
if not tools:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
if id in request.app.state.TOOLS:
|
||||
tools_module = request.app.state.TOOLS[id]
|
||||
else:
|
||||
tools_module, _ = load_tools_module_by_id(id)
|
||||
request.app.state.TOOLS[id] = tools_module
|
||||
|
||||
if not hasattr(tools_module, "Valves"):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||
)
|
||||
Valves = tools_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(str(e)),
|
||||
)
|
||||
|
||||
|
||||
############################
|
||||
|
||||
@@ -5,10 +5,15 @@ import sys
|
||||
from importlib import util
|
||||
import types
|
||||
import tempfile
|
||||
import logging
|
||||
|
||||
from open_webui.env import SRC_LOG_LEVELS
|
||||
from open_webui.apps.webui.models.functions import Functions
|
||||
from open_webui.apps.webui.models.tools import Tools
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["MAIN"])
|
||||
|
||||
|
||||
def extract_frontmatter(content):
|
||||
"""
|
||||
@@ -95,7 +100,7 @@ def load_tools_module_by_id(toolkit_id, content=None):
|
||||
# Executing the modified content in the created module's namespace
|
||||
exec(content, module.__dict__)
|
||||
frontmatter = extract_frontmatter(content)
|
||||
print(f"Loaded module: {module.__name__}")
|
||||
log.info(f"Loaded module: {module.__name__}")
|
||||
|
||||
# Create and return the object if the class 'Tools' is found in the module
|
||||
if hasattr(module, "Tools"):
|
||||
@@ -103,7 +108,7 @@ def load_tools_module_by_id(toolkit_id, content=None):
|
||||
else:
|
||||
raise Exception("No Tools class found in the module")
|
||||
except Exception as e:
|
||||
print(f"Error loading module: {toolkit_id}: {e}")
|
||||
log.error(f"Error loading module: {toolkit_id}: {e}")
|
||||
del sys.modules[module_name] # Clean up
|
||||
raise e
|
||||
finally:
|
||||
@@ -139,7 +144,7 @@ def load_function_module_by_id(function_id, content=None):
|
||||
# Execute the modified content in the created module's namespace
|
||||
exec(content, module.__dict__)
|
||||
frontmatter = extract_frontmatter(content)
|
||||
print(f"Loaded module: {module.__name__}")
|
||||
log.info(f"Loaded module: {module.__name__}")
|
||||
|
||||
# Create appropriate object based on available class type in the module
|
||||
if hasattr(module, "Pipe"):
|
||||
@@ -151,7 +156,7 @@ def load_function_module_by_id(function_id, content=None):
|
||||
else:
|
||||
raise Exception("No Function class found in the module")
|
||||
except Exception as e:
|
||||
print(f"Error loading module: {function_id}: {e}")
|
||||
log.error(f"Error loading module: {function_id}: {e}")
|
||||
del sys.modules[module_name] # Cleanup by removing the module in case of error
|
||||
|
||||
Functions.update_function_by_id(function_id, {"is_active": False})
|
||||
@@ -164,7 +169,7 @@ def install_frontmatter_requirements(requirements):
|
||||
if requirements:
|
||||
req_list = [req.strip() for req in requirements.split(",")]
|
||||
for req in req_list:
|
||||
print(f"Installing requirement: {req}")
|
||||
log.info(f"Installing requirement: {req}")
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", req])
|
||||
else:
|
||||
print("No requirements found in frontmatter.")
|
||||
log.info("No requirements found in frontmatter.")
|
||||
|
||||
@@ -740,6 +740,12 @@ DEFAULT_PROMPT_SUGGESTIONS = PersistentConfig(
|
||||
],
|
||||
)
|
||||
|
||||
MODEL_ORDER_LIST = PersistentConfig(
|
||||
"MODEL_ORDER_LIST",
|
||||
"ui.model_order_list",
|
||||
[],
|
||||
)
|
||||
|
||||
DEFAULT_USER_ROLE = PersistentConfig(
|
||||
"DEFAULT_USER_ROLE",
|
||||
"ui.default_user_role",
|
||||
@@ -969,19 +975,20 @@ QUERY_GENERATION_PROMPT_TEMPLATE = PersistentConfig(
|
||||
)
|
||||
|
||||
DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE = """### Task:
|
||||
Based on the chat history, determine whether a search is necessary, and if so, generate a 1-3 broad search queries to retrieve comprehensive and updated information. If no search is required, return an empty list.
|
||||
Analyze the chat history to determine the necessity of generating search queries, in the given language. By default, **prioritize generating 1-3 broad and relevant search queries** unless it is absolutely certain that no additional information is required. The aim is to retrieve comprehensive, updated, and valuable information even with minimal uncertainty. If no search is unequivocally needed, return an empty list.
|
||||
|
||||
### Guidelines:
|
||||
- Respond exclusively with a JSON object.
|
||||
- If a search query is needed, return an object like: { "queries": ["query1", "query2"] } where each query is distinct and concise.
|
||||
- If no search query is necessary, output should be: { "queries": [] }
|
||||
- Default to suggesting a search query to ensure accurate and updated information, unless it is definitively clear no search is required.
|
||||
- Be concise, focusing strictly on composing search queries with no additional commentary or text.
|
||||
- When in doubt, prefer to suggest a search for comprehensiveness.
|
||||
- Today's date is: {{CURRENT_DATE}}
|
||||
- Respond **EXCLUSIVELY** with a JSON object. Any form of extra commentary, explanation, or additional text is strictly prohibited.
|
||||
- When generating search queries, respond in the format: { "queries": ["query1", "query2"] }, ensuring each query is distinct, concise, and relevant to the topic.
|
||||
- If and only if it is entirely certain that no useful results can be retrieved by a search, return: { "queries": [] }.
|
||||
- Err on the side of suggesting search queries if there is **any chance** they might provide useful or updated information.
|
||||
- Be concise and focused on composing high-quality search queries, avoiding unnecessary elaboration, commentary, or assumptions.
|
||||
- Today's date is: {{CURRENT_DATE}}.
|
||||
- Always prioritize providing actionable and broad queries that maximize informational coverage.
|
||||
|
||||
### Output:
|
||||
JSON format: {
|
||||
Strictly return in JSON format:
|
||||
{
|
||||
"queries": ["query1", "query2"]
|
||||
}
|
||||
|
||||
@@ -1181,21 +1188,32 @@ CHUNK_OVERLAP = PersistentConfig(
|
||||
int(os.environ.get("CHUNK_OVERLAP", "100")),
|
||||
)
|
||||
|
||||
DEFAULT_RAG_TEMPLATE = """You are given a user query, some textual context and rules, all inside xml tags. You have to answer the query based on the context while respecting the rules.
|
||||
DEFAULT_RAG_TEMPLATE = """### Task:
|
||||
Respond to the user query using the provided context, incorporating inline citations in the format [source_id] **only when the <source_id> tag is explicitly provided** in the context.
|
||||
|
||||
### Guidelines:
|
||||
- If you don't know the answer, clearly state that.
|
||||
- If uncertain, ask the user for clarification.
|
||||
- Respond in the same language as the user's query.
|
||||
- If the context is unreadable or of poor quality, inform the user and provide the best possible answer.
|
||||
- If the answer isn't present in the context but you possess the knowledge, explain this to the user and provide the answer using your own understanding.
|
||||
- **Only include inline citations using [source_id] when a <source_id> tag is explicitly provided in the context.**
|
||||
- Do not cite if the <source_id> tag is not provided in the context.
|
||||
- Do not use XML tags in your response.
|
||||
- Ensure citations are concise and directly related to the information provided.
|
||||
|
||||
### Example of Citation:
|
||||
If the user asks about a specific topic and the information is found in "whitepaper.pdf" with a provided <source_id>, the response should include the citation like so:
|
||||
* "According to the study, the proposed method increases efficiency by 20% [whitepaper.pdf]."
|
||||
If no <source_id> is present, the response should omit the citation.
|
||||
|
||||
### Output:
|
||||
Provide a clear and direct response to the user's query, including inline citations in the format [source_id] only when the <source_id> tag is present in the context.
|
||||
|
||||
<context>
|
||||
{{CONTEXT}}
|
||||
</context>
|
||||
|
||||
<rules>
|
||||
- If you don't know, just say so.
|
||||
- If you are not sure, ask for clarification.
|
||||
- Answer in the same language as the user query.
|
||||
- If the context appears unreadable or of poor quality, tell the user then answer as best as you can.
|
||||
- If the answer is not in the context but you think you know the answer, explain that to the user then answer with your own knowledge.
|
||||
- Answer directly and without using xml tags.
|
||||
</rules>
|
||||
|
||||
<user_query>
|
||||
{{QUERY}}
|
||||
</user_query>
|
||||
@@ -1290,6 +1308,12 @@ BRAVE_SEARCH_API_KEY = PersistentConfig(
|
||||
os.getenv("BRAVE_SEARCH_API_KEY", ""),
|
||||
)
|
||||
|
||||
MOJEEK_SEARCH_API_KEY = PersistentConfig(
|
||||
"MOJEEK_SEARCH_API_KEY",
|
||||
"rag.web.search.mojeek_search_api_key",
|
||||
os.getenv("MOJEEK_SEARCH_API_KEY", ""),
|
||||
)
|
||||
|
||||
SERPSTACK_API_KEY = PersistentConfig(
|
||||
"SERPSTACK_API_KEY",
|
||||
"rag.web.search.serpstack_api_key",
|
||||
|
||||
+155
-91
@@ -49,7 +49,9 @@ from open_webui.apps.openai.main import (
|
||||
get_all_models_responses as get_openai_models_responses,
|
||||
)
|
||||
from open_webui.apps.retrieval.main import app as retrieval_app
|
||||
from open_webui.apps.retrieval.utils import get_rag_context, rag_template
|
||||
from open_webui.apps.retrieval.utils import get_sources_from_files
|
||||
|
||||
|
||||
from open_webui.apps.socket.main import (
|
||||
app as socket_app,
|
||||
periodic_usage_pool_cleanup,
|
||||
@@ -122,11 +124,12 @@ from open_webui.utils.response import (
|
||||
)
|
||||
from open_webui.utils.security_headers import SecurityHeadersMiddleware
|
||||
from open_webui.utils.task import (
|
||||
moa_response_generation_template,
|
||||
tags_generation_template,
|
||||
query_generation_template,
|
||||
emoji_generation_template,
|
||||
rag_template,
|
||||
title_generation_template,
|
||||
query_generation_template,
|
||||
tags_generation_template,
|
||||
emoji_generation_template,
|
||||
moa_response_generation_template,
|
||||
tools_function_calling_generation_template,
|
||||
)
|
||||
from open_webui.utils.tools import get_tools
|
||||
@@ -380,8 +383,7 @@ async def chat_completion_tools_handler(
|
||||
return body, {}
|
||||
|
||||
skip_files = False
|
||||
contexts = []
|
||||
citations = []
|
||||
sources = []
|
||||
|
||||
task_model_id = get_task_model_id(
|
||||
body["model"],
|
||||
@@ -463,21 +465,39 @@ async def chat_completion_tools_handler(
|
||||
except Exception as e:
|
||||
tool_output = str(e)
|
||||
|
||||
if tools[tool_function_name]["citation"]:
|
||||
citations.append(
|
||||
{
|
||||
"source": {
|
||||
"name": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
},
|
||||
"document": [tool_output],
|
||||
"metadata": [{"source": tool_function_name}],
|
||||
}
|
||||
)
|
||||
if tools[tool_function_name]["file_handler"]:
|
||||
skip_files = True
|
||||
print(tools[tool_function_name]["citation"])
|
||||
|
||||
if isinstance(tool_output, str):
|
||||
contexts.append(tool_output)
|
||||
if tools[tool_function_name]["citation"]:
|
||||
sources.append(
|
||||
{
|
||||
"source": {
|
||||
"name": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
else:
|
||||
sources.append(
|
||||
{
|
||||
"source": {},
|
||||
"document": [tool_output],
|
||||
"metadata": [
|
||||
{
|
||||
"source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}"
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
if tools[tool_function_name]["file_handler"]:
|
||||
skip_files = True
|
||||
|
||||
except Exception as e:
|
||||
log.exception(f"Error: {e}")
|
||||
content = None
|
||||
@@ -485,47 +505,51 @@ async def chat_completion_tools_handler(
|
||||
log.exception(f"Error: {e}")
|
||||
content = None
|
||||
|
||||
log.debug(f"tool_contexts: {contexts}")
|
||||
log.debug(f"tool_contexts: {sources}")
|
||||
|
||||
if skip_files and "files" in body.get("metadata", {}):
|
||||
del body["metadata"]["files"]
|
||||
|
||||
return body, {"contexts": contexts, "citations": citations}
|
||||
return body, {"sources": sources}
|
||||
|
||||
|
||||
async def chat_completion_files_handler(
|
||||
body: dict, user: UserModel
|
||||
) -> tuple[dict, dict[str, list]]:
|
||||
contexts = []
|
||||
citations = []
|
||||
|
||||
try:
|
||||
queries_response = await generate_queries(
|
||||
{
|
||||
"model": body["model"],
|
||||
"messages": body["messages"],
|
||||
"type": "retrieval",
|
||||
},
|
||||
user,
|
||||
)
|
||||
queries_response = queries_response["choices"][0]["message"]["content"]
|
||||
|
||||
try:
|
||||
queries_response = json.loads(queries_response)
|
||||
except Exception as e:
|
||||
queries_response = {"queries": []}
|
||||
|
||||
queries = queries_response.get("queries", [])
|
||||
except Exception as e:
|
||||
queries = []
|
||||
|
||||
if len(queries) == 0:
|
||||
queries = [get_last_user_message(body["messages"])]
|
||||
|
||||
print(f"{queries=}")
|
||||
sources = []
|
||||
|
||||
if files := body.get("metadata", {}).get("files", None):
|
||||
contexts, citations = get_rag_context(
|
||||
try:
|
||||
queries_response = await generate_queries(
|
||||
{
|
||||
"model": body["model"],
|
||||
"messages": body["messages"],
|
||||
"type": "retrieval",
|
||||
},
|
||||
user,
|
||||
)
|
||||
queries_response = queries_response["choices"][0]["message"]["content"]
|
||||
|
||||
try:
|
||||
bracket_start = queries_response.find("{")
|
||||
bracket_end = queries_response.rfind("}") + 1
|
||||
|
||||
if bracket_start == -1 or bracket_end == -1:
|
||||
raise Exception("No JSON object found in the response")
|
||||
|
||||
queries_response = queries_response[bracket_start:bracket_end]
|
||||
queries_response = json.loads(queries_response)
|
||||
except Exception as e:
|
||||
queries_response = {"queries": [queries_response]}
|
||||
|
||||
queries = queries_response.get("queries", [])
|
||||
except Exception as e:
|
||||
queries = []
|
||||
|
||||
if len(queries) == 0:
|
||||
queries = [get_last_user_message(body["messages"])]
|
||||
|
||||
sources = get_sources_from_files(
|
||||
files=files,
|
||||
queries=queries,
|
||||
embedding_function=retrieval_app.state.EMBEDDING_FUNCTION,
|
||||
@@ -535,9 +559,8 @@ async def chat_completion_files_handler(
|
||||
hybrid_search=retrieval_app.state.config.ENABLE_RAG_HYBRID_SEARCH,
|
||||
)
|
||||
|
||||
log.debug(f"rag_contexts: {contexts}, citations: {citations}")
|
||||
|
||||
return body, {"contexts": contexts, "citations": citations}
|
||||
log.debug(f"rag_contexts:sources: {sources}")
|
||||
return body, {"sources": sources}
|
||||
|
||||
|
||||
def is_chat_completion_request(request):
|
||||
@@ -638,8 +661,7 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
|
||||
# Initialize data_items to store additional data to be sent to the client
|
||||
# Initialize contexts and citation
|
||||
data_items = []
|
||||
contexts = []
|
||||
citations = []
|
||||
sources = []
|
||||
|
||||
try:
|
||||
body, flags = await chat_completion_filter_functions_handler(
|
||||
@@ -665,21 +687,37 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
|
||||
body, flags = await chat_completion_tools_handler(
|
||||
body, user, models, extra_params
|
||||
)
|
||||
contexts.extend(flags.get("contexts", []))
|
||||
citations.extend(flags.get("citations", []))
|
||||
sources.extend(flags.get("sources", []))
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
||||
try:
|
||||
body, flags = await chat_completion_files_handler(body, user)
|
||||
contexts.extend(flags.get("contexts", []))
|
||||
citations.extend(flags.get("citations", []))
|
||||
sources.extend(flags.get("sources", []))
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
||||
# If context is not empty, insert it into the messages
|
||||
if len(contexts) > 0:
|
||||
context_string = "/n".join(contexts).strip()
|
||||
if len(sources) > 0:
|
||||
context_string = ""
|
||||
for source_idx, source in enumerate(sources):
|
||||
source_id = source.get("source", {}).get("name", "")
|
||||
|
||||
if "document" in source:
|
||||
for doc_idx, doc_context in enumerate(source["document"]):
|
||||
metadata = source.get("metadata")
|
||||
doc_source_id = None
|
||||
|
||||
if metadata:
|
||||
doc_source_id = metadata[doc_idx].get("source", source_id)
|
||||
|
||||
if source_id:
|
||||
context_string += f"<source><source_id>{doc_source_id if doc_source_id is not None else source_id}</source_id><source_context>{doc_context}</source_context></source>\n"
|
||||
else:
|
||||
# If there is no source_id, then do not include the source_id tag
|
||||
context_string += f"<source><source_context>{doc_context}</source_context></source>\n"
|
||||
|
||||
context_string = context_string.strip()
|
||||
prompt = get_last_user_message(body["messages"])
|
||||
|
||||
if prompt is None:
|
||||
@@ -710,8 +748,11 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
|
||||
)
|
||||
|
||||
# If there are citations, add them to the data_items
|
||||
if len(citations) > 0:
|
||||
data_items.append({"citations": citations})
|
||||
sources = [
|
||||
source for source in sources if source.get("source", {}).get("name", "")
|
||||
]
|
||||
if len(sources) > 0:
|
||||
data_items.append({"sources": sources})
|
||||
|
||||
modified_body_bytes = json.dumps(body).encode("utf-8")
|
||||
# Replace the request body with the modified one
|
||||
@@ -855,6 +896,11 @@ class PipelineMiddleware(BaseHTTPMiddleware):
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
content={"detail": "Not authenticated"},
|
||||
)
|
||||
except HTTPException as e:
|
||||
return JSONResponse(
|
||||
status_code=e.status_code,
|
||||
content={"detail": e.detail},
|
||||
)
|
||||
|
||||
model_list = await get_all_models()
|
||||
models = {model["id"]: model for model in model_list}
|
||||
@@ -932,7 +978,7 @@ app.add_middleware(SecurityHeadersMiddleware)
|
||||
@app.middleware("http")
|
||||
async def commit_session_after_request(request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
log.debug("Commit session after request")
|
||||
# log.debug("Commit session after request")
|
||||
Session.commit()
|
||||
return response
|
||||
|
||||
@@ -1015,7 +1061,7 @@ async def get_all_base_models():
|
||||
return models
|
||||
|
||||
|
||||
@cached(ttl=1)
|
||||
@cached(ttl=3)
|
||||
async def get_all_models():
|
||||
models = await get_all_base_models()
|
||||
|
||||
@@ -1139,6 +1185,8 @@ async def get_all_models():
|
||||
model["actions"].extend(
|
||||
get_action_items_from_module(action_function, function_module)
|
||||
)
|
||||
log.debug(f"get_all_models() returned {len(models)} models")
|
||||
|
||||
return models
|
||||
|
||||
|
||||
@@ -1153,6 +1201,14 @@ async def get_models(user=Depends(get_verified_user)):
|
||||
if "pipeline" not in model or model["pipeline"].get("type", None) != "filter"
|
||||
]
|
||||
|
||||
model_order_list = webui_app.state.config.MODEL_ORDER_LIST
|
||||
if model_order_list:
|
||||
model_order_dict = {model_id: i for i, model_id in enumerate(model_order_list)}
|
||||
# Sort models by order list priority, with fallback for those not in the list
|
||||
models.sort(
|
||||
key=lambda x: (model_order_dict.get(x["id"], float("inf")), x["name"])
|
||||
)
|
||||
|
||||
# Filter out models that the user does not have access to
|
||||
if user.role == "user":
|
||||
filtered_models = []
|
||||
@@ -1176,6 +1232,10 @@ async def get_models(user=Depends(get_verified_user)):
|
||||
filtered_models.append(model)
|
||||
models = filtered_models
|
||||
|
||||
log.debug(
|
||||
f"/api/models returned filtered models accessible to the user: {json.dumps([model['id'] for model in models])}"
|
||||
)
|
||||
|
||||
return {"data": models}
|
||||
|
||||
|
||||
@@ -1308,7 +1368,6 @@ async def generate_chat_completions(
|
||||
|
||||
@app.post("/api/chat/completed")
|
||||
async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
|
||||
|
||||
model_list = await get_all_models()
|
||||
models = {model["id"]: model for model in model_list}
|
||||
|
||||
@@ -1667,7 +1726,6 @@ async def update_task_config(form_data: TaskConfigForm, user=Depends(get_admin_u
|
||||
|
||||
@app.post("/api/task/title/completions")
|
||||
async def generate_title(form_data: dict, user=Depends(get_verified_user)):
|
||||
print("generate_title")
|
||||
|
||||
model_list = await get_all_models()
|
||||
models = {model["id"]: model for model in model_list}
|
||||
@@ -1688,9 +1746,9 @@ async def generate_title(form_data: dict, user=Depends(get_verified_user)):
|
||||
models,
|
||||
)
|
||||
|
||||
print(task_model_id)
|
||||
|
||||
model = models[task_model_id]
|
||||
log.debug(
|
||||
f"generating chat title using model {task_model_id} for user {user.email} "
|
||||
)
|
||||
|
||||
if app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE != "":
|
||||
template = app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE
|
||||
@@ -1729,10 +1787,12 @@ Artificial Intelligence in Healthcare
|
||||
"max_completion_tokens": 50,
|
||||
}
|
||||
),
|
||||
"chat_id": form_data.get("chat_id", None),
|
||||
"metadata": {"task": str(TASKS.TITLE_GENERATION), "task_body": form_data},
|
||||
"metadata": {
|
||||
"task": str(TASKS.TITLE_GENERATION),
|
||||
"task_body": form_data,
|
||||
"chat_id": form_data.get("chat_id", None),
|
||||
},
|
||||
}
|
||||
log.debug(payload)
|
||||
|
||||
# Handle pipeline filters
|
||||
try:
|
||||
@@ -1756,7 +1816,7 @@ Artificial Intelligence in Healthcare
|
||||
|
||||
@app.post("/api/task/tags/completions")
|
||||
async def generate_chat_tags(form_data: dict, user=Depends(get_verified_user)):
|
||||
print("generate_chat_tags")
|
||||
|
||||
if not app.state.config.ENABLE_TAGS_GENERATION:
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
@@ -1781,7 +1841,10 @@ async def generate_chat_tags(form_data: dict, user=Depends(get_verified_user)):
|
||||
app.state.config.TASK_MODEL_EXTERNAL,
|
||||
models,
|
||||
)
|
||||
print(task_model_id)
|
||||
|
||||
log.debug(
|
||||
f"generating chat tags using model {task_model_id} for user {user.email} "
|
||||
)
|
||||
|
||||
if app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE != "":
|
||||
template = app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE
|
||||
@@ -1812,9 +1875,12 @@ JSON format: { "tags": ["tag1", "tag2", "tag3"] }
|
||||
"model": task_model_id,
|
||||
"messages": [{"role": "user", "content": content}],
|
||||
"stream": False,
|
||||
"metadata": {"task": str(TASKS.TAGS_GENERATION), "task_body": form_data},
|
||||
"metadata": {
|
||||
"task": str(TASKS.TAGS_GENERATION),
|
||||
"task_body": form_data,
|
||||
"chat_id": form_data.get("chat_id", None),
|
||||
},
|
||||
}
|
||||
log.debug(payload)
|
||||
|
||||
# Handle pipeline filters
|
||||
try:
|
||||
@@ -1838,7 +1904,7 @@ JSON format: { "tags": ["tag1", "tag2", "tag3"] }
|
||||
|
||||
@app.post("/api/task/queries/completions")
|
||||
async def generate_queries(form_data: dict, user=Depends(get_verified_user)):
|
||||
print("generate_queries")
|
||||
|
||||
type = form_data.get("type")
|
||||
if type == "web_search":
|
||||
if not app.state.config.ENABLE_SEARCH_QUERY_GENERATION:
|
||||
@@ -1871,9 +1937,10 @@ async def generate_queries(form_data: dict, user=Depends(get_verified_user)):
|
||||
app.state.config.TASK_MODEL_EXTERNAL,
|
||||
models,
|
||||
)
|
||||
print(task_model_id)
|
||||
|
||||
model = models[task_model_id]
|
||||
log.debug(
|
||||
f"generating {type} queries using model {task_model_id} for user {user.email}"
|
||||
)
|
||||
|
||||
if app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE != "":
|
||||
template = app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE
|
||||
@@ -1888,9 +1955,12 @@ async def generate_queries(form_data: dict, user=Depends(get_verified_user)):
|
||||
"model": task_model_id,
|
||||
"messages": [{"role": "user", "content": content}],
|
||||
"stream": False,
|
||||
"metadata": {"task": str(TASKS.QUERY_GENERATION), "task_body": form_data},
|
||||
"metadata": {
|
||||
"task": str(TASKS.QUERY_GENERATION),
|
||||
"task_body": form_data,
|
||||
"chat_id": form_data.get("chat_id", None),
|
||||
},
|
||||
}
|
||||
log.debug(payload)
|
||||
|
||||
# Handle pipeline filters
|
||||
try:
|
||||
@@ -1914,7 +1984,6 @@ async def generate_queries(form_data: dict, user=Depends(get_verified_user)):
|
||||
|
||||
@app.post("/api/task/emoji/completions")
|
||||
async def generate_emoji(form_data: dict, user=Depends(get_verified_user)):
|
||||
print("generate_emoji")
|
||||
|
||||
model_list = await get_all_models()
|
||||
models = {model["id"]: model for model in model_list}
|
||||
@@ -1934,9 +2003,8 @@ async def generate_emoji(form_data: dict, user=Depends(get_verified_user)):
|
||||
app.state.config.TASK_MODEL_EXTERNAL,
|
||||
models,
|
||||
)
|
||||
print(task_model_id)
|
||||
|
||||
model = models[task_model_id]
|
||||
log.debug(f"generating emoji using model {task_model_id} for user {user.email} ")
|
||||
|
||||
template = '''
|
||||
Your task is to reflect the speaker's likely facial expression through a fitting emoji. Interpret emotions from the message and reflect their facial expression using fitting, diverse emojis (e.g., 😊, 😢, 😡, 😱).
|
||||
@@ -1966,7 +2034,6 @@ Message: """{{prompt}}"""
|
||||
"chat_id": form_data.get("chat_id", None),
|
||||
"metadata": {"task": str(TASKS.EMOJI_GENERATION), "task_body": form_data},
|
||||
}
|
||||
log.debug(payload)
|
||||
|
||||
# Handle pipeline filters
|
||||
try:
|
||||
@@ -1990,7 +2057,6 @@ Message: """{{prompt}}"""
|
||||
|
||||
@app.post("/api/task/moa/completions")
|
||||
async def generate_moa_response(form_data: dict, user=Depends(get_verified_user)):
|
||||
print("generate_moa_response")
|
||||
|
||||
model_list = await get_all_models()
|
||||
models = {model["id"]: model for model in model_list}
|
||||
@@ -2010,9 +2076,8 @@ async def generate_moa_response(form_data: dict, user=Depends(get_verified_user)
|
||||
app.state.config.TASK_MODEL_EXTERNAL,
|
||||
models,
|
||||
)
|
||||
print(task_model_id)
|
||||
|
||||
model = models[task_model_id]
|
||||
log.debug(f"generating MOA model {task_model_id} for user {user.email} ")
|
||||
|
||||
template = """You have been provided with a set of responses from various models to the latest user query: "{{prompt}}"
|
||||
|
||||
@@ -2036,7 +2101,6 @@ Responses from models: {{responses}}"""
|
||||
"task_body": form_data,
|
||||
},
|
||||
}
|
||||
log.debug(payload)
|
||||
|
||||
try:
|
||||
payload = filter_pipeline(payload, user, models)
|
||||
@@ -2071,7 +2135,7 @@ Responses from models: {{responses}}"""
|
||||
async def get_pipelines_list(user=Depends(get_admin_user)):
|
||||
responses = await get_openai_models_responses()
|
||||
|
||||
print(responses)
|
||||
log.debug(f"get_pipelines_list: get_openai_models_responses returned {responses}")
|
||||
urlIdxs = [
|
||||
idx
|
||||
for idx, response in enumerate(responses)
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
from ast import literal_eval
|
||||
from typing import Any, Literal, Optional, Type
|
||||
|
||||
from pydantic import BaseModel, Field, create_model
|
||||
|
||||
|
||||
def json_schema_to_model(tool_dict: dict[str, Any]) -> Type[BaseModel]:
|
||||
"""
|
||||
Converts a JSON schema to a Pydantic BaseModel class.
|
||||
|
||||
Args:
|
||||
json_schema: The JSON schema to convert.
|
||||
|
||||
Returns:
|
||||
A Pydantic BaseModel class.
|
||||
"""
|
||||
|
||||
# Extract the model name from the schema title.
|
||||
model_name = tool_dict["name"]
|
||||
schema = tool_dict["parameters"]
|
||||
|
||||
# Extract the field definitions from the schema properties.
|
||||
field_definitions = {
|
||||
name: json_schema_to_pydantic_field(name, prop, schema.get("required", []))
|
||||
for name, prop in schema.get("properties", {}).items()
|
||||
}
|
||||
|
||||
# Create the BaseModel class using create_model().
|
||||
return create_model(model_name, **field_definitions)
|
||||
|
||||
|
||||
def json_schema_to_pydantic_field(
|
||||
name: str, json_schema: dict[str, Any], required: list[str]
|
||||
) -> Any:
|
||||
"""
|
||||
Converts a JSON schema property to a Pydantic field definition.
|
||||
|
||||
Args:
|
||||
name: The field name.
|
||||
json_schema: The JSON schema property.
|
||||
|
||||
Returns:
|
||||
A Pydantic field definition.
|
||||
"""
|
||||
|
||||
# Get the field type.
|
||||
type_ = json_schema_to_pydantic_type(json_schema)
|
||||
|
||||
# Get the field description.
|
||||
description = json_schema.get("description")
|
||||
|
||||
# Get the field examples.
|
||||
examples = json_schema.get("examples")
|
||||
|
||||
# Create a Field object with the type, description, and examples.
|
||||
# The 'required' flag will be set later when creating the model.
|
||||
return (
|
||||
type_,
|
||||
Field(
|
||||
description=description,
|
||||
examples=examples,
|
||||
default=... if name in required else None,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def json_schema_to_pydantic_type(json_schema: dict[str, Any]) -> Any:
|
||||
"""
|
||||
Converts a JSON schema type to a Pydantic type.
|
||||
|
||||
Args:
|
||||
json_schema: The JSON schema to convert.
|
||||
|
||||
Returns:
|
||||
A Pydantic type.
|
||||
"""
|
||||
|
||||
type_ = json_schema.get("type")
|
||||
|
||||
if type_ == "string" or type_ == "str":
|
||||
return str
|
||||
elif type_ == "integer" or type_ == "int":
|
||||
return int
|
||||
elif type_ == "number" or type_ == "float":
|
||||
return float
|
||||
elif type_ == "boolean" or type_ == "bool":
|
||||
return bool
|
||||
elif type_ == "array" or type_ == "list":
|
||||
items_schema = json_schema.get("items")
|
||||
if items_schema:
|
||||
item_type = json_schema_to_pydantic_type(items_schema)
|
||||
return list[item_type]
|
||||
else:
|
||||
return list
|
||||
elif type_ == "object":
|
||||
# Handle nested models.
|
||||
properties = json_schema.get("properties")
|
||||
if properties:
|
||||
nested_model = json_schema_to_model(json_schema)
|
||||
return nested_model
|
||||
else:
|
||||
return dict
|
||||
elif type_ == "null":
|
||||
return Optional[Any] # Use Optional[Any] for nullable fields
|
||||
elif type_ == "literal":
|
||||
return Literal[literal_eval(json_schema.get("enum"))]
|
||||
elif type_ == "optional":
|
||||
inner_schema = json_schema.get("items", {"type": "string"})
|
||||
inner_type = json_schema_to_pydantic_type(inner_schema)
|
||||
return Optional[inner_type]
|
||||
else:
|
||||
raise ValueError(f"Unsupported JSON schema type: {type_}")
|
||||
@@ -1,11 +1,20 @@
|
||||
import logging
|
||||
import math
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
import uuid
|
||||
|
||||
|
||||
from open_webui.utils.misc import get_last_user_message, get_messages_content
|
||||
|
||||
from open_webui.env import SRC_LOG_LEVELS
|
||||
from open_webui.config import DEFAULT_RAG_TEMPLATE
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.setLevel(SRC_LOG_LEVELS["RAG"])
|
||||
|
||||
|
||||
def prompt_template(
|
||||
template: str, user_name: Optional[str] = None, user_location: Optional[str] = None
|
||||
@@ -16,12 +25,14 @@ def prompt_template(
|
||||
# Format the date to YYYY-MM-DD
|
||||
formatted_date = current_date.strftime("%Y-%m-%d")
|
||||
formatted_time = current_date.strftime("%I:%M:%S %p")
|
||||
formatted_weekday = current_date.strftime("%A")
|
||||
|
||||
template = template.replace("{{CURRENT_DATE}}", formatted_date)
|
||||
template = template.replace("{{CURRENT_TIME}}", formatted_time)
|
||||
template = template.replace(
|
||||
"{{CURRENT_DATETIME}}", f"{formatted_date} {formatted_time}"
|
||||
)
|
||||
template = template.replace("{{CURRENT_WEEKDAY}}", formatted_weekday)
|
||||
|
||||
if user_name:
|
||||
# Replace {{USER_NAME}} in the template with the user's name
|
||||
@@ -110,6 +121,44 @@ def replace_messages_variable(template: str, messages: list[str]) -> str:
|
||||
# {{prompt:middletruncate:8000}}
|
||||
|
||||
|
||||
def rag_template(template: str, context: str, query: str):
|
||||
if template == "":
|
||||
template = DEFAULT_RAG_TEMPLATE
|
||||
|
||||
if "[context]" not in template and "{{CONTEXT}}" not in template:
|
||||
log.debug(
|
||||
"WARNING: The RAG template does not contain the '[context]' or '{{CONTEXT}}' placeholder."
|
||||
)
|
||||
|
||||
if "<context>" in context and "</context>" in context:
|
||||
log.debug(
|
||||
"WARNING: Potential prompt injection attack: the RAG "
|
||||
"context contains '<context>' and '</context>'. This might be "
|
||||
"nothing, or the user might be trying to hack something."
|
||||
)
|
||||
|
||||
query_placeholders = []
|
||||
if "[query]" in context:
|
||||
query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}"
|
||||
template = template.replace("[query]", query_placeholder)
|
||||
query_placeholders.append(query_placeholder)
|
||||
|
||||
if "{{QUERY}}" in context:
|
||||
query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}"
|
||||
template = template.replace("{{QUERY}}", query_placeholder)
|
||||
query_placeholders.append(query_placeholder)
|
||||
|
||||
template = template.replace("[context]", context)
|
||||
template = template.replace("{{CONTEXT}}", context)
|
||||
template = template.replace("[query]", query)
|
||||
template = template.replace("{{QUERY}}", query)
|
||||
|
||||
for query_placeholder in query_placeholders:
|
||||
template = template.replace(query_placeholder, query)
|
||||
|
||||
return template
|
||||
|
||||
|
||||
def title_generation_template(
|
||||
template: str, messages: list[dict], user: Optional[dict] = None
|
||||
) -> str:
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import inspect
|
||||
import logging
|
||||
from typing import Awaitable, Callable, get_type_hints
|
||||
import re
|
||||
from typing import Any, Awaitable, Callable, get_type_hints
|
||||
from functools import update_wrapper, partial
|
||||
|
||||
from langchain_core.utils.function_calling import convert_to_openai_function
|
||||
from open_webui.apps.webui.models.tools import Tools
|
||||
from open_webui.apps.webui.models.users import UserModel
|
||||
from open_webui.apps.webui.utils import load_tools_module_by_id
|
||||
from open_webui.utils.schemas import json_schema_to_model
|
||||
from pydantic import BaseModel, Field, create_model
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -14,17 +17,16 @@ def apply_extra_params_to_tool_function(
|
||||
function: Callable, extra_params: dict
|
||||
) -> Callable[..., Awaitable]:
|
||||
sig = inspect.signature(function)
|
||||
extra_params = {
|
||||
key: value for key, value in extra_params.items() if key in sig.parameters
|
||||
}
|
||||
is_coroutine = inspect.iscoroutinefunction(function)
|
||||
extra_params = {k: v for k, v in extra_params.items() if k in sig.parameters}
|
||||
partial_func = partial(function, **extra_params)
|
||||
if inspect.iscoroutinefunction(function):
|
||||
update_wrapper(partial_func, function)
|
||||
return partial_func
|
||||
|
||||
async def new_function(**kwargs):
|
||||
extra_kwargs = kwargs | extra_params
|
||||
if is_coroutine:
|
||||
return await function(**extra_kwargs)
|
||||
return function(**extra_kwargs)
|
||||
async def new_function(*args, **kwargs):
|
||||
return partial_func(*args, **kwargs)
|
||||
|
||||
update_wrapper(new_function, function)
|
||||
return new_function
|
||||
|
||||
|
||||
@@ -55,11 +57,6 @@ def get_tools(
|
||||
)
|
||||
|
||||
for spec in tools.specs:
|
||||
# TODO: Fix hack for OpenAI API
|
||||
for val in spec.get("parameters", {}).get("properties", {}).values():
|
||||
if val["type"] == "str":
|
||||
val["type"] = "string"
|
||||
|
||||
# Remove internal parameters
|
||||
spec["parameters"]["properties"] = {
|
||||
key: val
|
||||
@@ -72,15 +69,12 @@ def get_tools(
|
||||
# convert to function that takes only model params and inserts custom params
|
||||
original_func = getattr(module, function_name)
|
||||
callable = apply_extra_params_to_tool_function(original_func, extra_params)
|
||||
if hasattr(original_func, "__doc__"):
|
||||
callable.__doc__ = original_func.__doc__
|
||||
|
||||
# TODO: This needs to be a pydantic model
|
||||
tool_dict = {
|
||||
"toolkit_id": tool_id,
|
||||
"callable": callable,
|
||||
"spec": spec,
|
||||
"pydantic_model": json_schema_to_model(spec),
|
||||
"pydantic_model": function_to_pydantic_model(callable),
|
||||
"file_handler": hasattr(module, "file_handler") and module.file_handler,
|
||||
"citation": hasattr(module, "citation") and module.citation,
|
||||
}
|
||||
@@ -96,78 +90,109 @@ def get_tools(
|
||||
return tools_dict
|
||||
|
||||
|
||||
def doc_to_dict(docstring):
|
||||
lines = docstring.split("\n")
|
||||
description = lines[1].strip()
|
||||
param_dict = {}
|
||||
def parse_description(docstring: str | None) -> str:
|
||||
"""
|
||||
Parse a function's docstring to extract the description.
|
||||
|
||||
Args:
|
||||
docstring (str): The docstring to parse.
|
||||
|
||||
Returns:
|
||||
str: The description.
|
||||
"""
|
||||
|
||||
if not docstring:
|
||||
return ""
|
||||
|
||||
lines = [line.strip() for line in docstring.strip().split("\n")]
|
||||
description_lines: list[str] = []
|
||||
|
||||
for line in lines:
|
||||
if ":param" in line:
|
||||
line = line.replace(":param", "").strip()
|
||||
param, desc = line.split(":", 1)
|
||||
param_dict[param.strip()] = desc.strip()
|
||||
ret_dict = {"description": description, "params": param_dict}
|
||||
return ret_dict
|
||||
if re.match(r":param", line) or re.match(r":return", line):
|
||||
break
|
||||
|
||||
description_lines.append(line)
|
||||
|
||||
return "\n".join(description_lines)
|
||||
|
||||
|
||||
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))
|
||||
def parse_docstring(docstring):
|
||||
"""
|
||||
Parse a function's docstring to extract parameter descriptions in reST format.
|
||||
|
||||
Args:
|
||||
docstring (str): The docstring to parse.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary where keys are parameter names and values are descriptions.
|
||||
"""
|
||||
if not docstring:
|
||||
return {}
|
||||
|
||||
# Regex to match `:param name: description` format
|
||||
param_pattern = re.compile(r":param (\w+):\s*(.+)")
|
||||
param_descriptions = {}
|
||||
|
||||
for line in docstring.splitlines():
|
||||
match = param_pattern.match(line.strip())
|
||||
if not match:
|
||||
continue
|
||||
param_name, param_description = match.groups()
|
||||
if param_name.startswith("__"):
|
||||
continue
|
||||
param_descriptions[param_name] = param_description
|
||||
|
||||
return param_descriptions
|
||||
|
||||
|
||||
def function_to_pydantic_model(func: Callable) -> type[BaseModel]:
|
||||
"""
|
||||
Converts a Python function's type hints and docstring to a Pydantic model,
|
||||
including support for nested types, default values, and descriptions.
|
||||
|
||||
Args:
|
||||
func: The function whose type hints and docstring should be converted.
|
||||
model_name: The name of the generated Pydantic model.
|
||||
|
||||
Returns:
|
||||
A Pydantic model class.
|
||||
"""
|
||||
type_hints = get_type_hints(func)
|
||||
signature = inspect.signature(func)
|
||||
parameters = signature.parameters
|
||||
|
||||
docstring = func.__doc__
|
||||
descriptions = parse_docstring(docstring)
|
||||
|
||||
tool_description = parse_description(docstring)
|
||||
|
||||
field_defs = {}
|
||||
for name, param in parameters.items():
|
||||
type_hint = type_hints.get(name, Any)
|
||||
default_value = param.default if param.default is not param.empty else ...
|
||||
description = descriptions.get(name, None)
|
||||
if not description:
|
||||
field_defs[name] = type_hint, default_value
|
||||
continue
|
||||
field_defs[name] = type_hint, Field(default_value, description=description)
|
||||
|
||||
model = create_model(func.__name__, **field_defs)
|
||||
model.__doc__ = tool_description
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def get_callable_attributes(tool: object) -> list[Callable]:
|
||||
return [
|
||||
getattr(tool, func)
|
||||
for func in dir(tool)
|
||||
if callable(getattr(tool, func))
|
||||
and not func.startswith("__")
|
||||
and not inspect.isclass(getattr(tools, func))
|
||||
and not inspect.isclass(getattr(tool, func))
|
||||
]
|
||||
|
||||
specs = []
|
||||
for function_item in function_list:
|
||||
function_name = function_item["name"]
|
||||
function = function_item["function"]
|
||||
|
||||
function_doc = doc_to_dict(function.__doc__ or function_name)
|
||||
specs.append(
|
||||
{
|
||||
"name": function_name,
|
||||
# TODO: multi-line desc?
|
||||
"description": function_doc.get("description", function_name),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
param_name: {
|
||||
"type": param_annotation.__name__.lower(),
|
||||
**(
|
||||
{
|
||||
"enum": (
|
||||
str(param_annotation.__args__)
|
||||
if hasattr(param_annotation, "__args__")
|
||||
else None
|
||||
)
|
||||
}
|
||||
if hasattr(param_annotation, "__args__")
|
||||
else {}
|
||||
),
|
||||
"description": function_doc.get("params", {}).get(
|
||||
param_name, param_name
|
||||
),
|
||||
}
|
||||
for param_name, param_annotation in get_type_hints(
|
||||
function
|
||||
).items()
|
||||
if param_name != "return"
|
||||
and not (
|
||||
param_name.startswith("__") and param_name.endswith("__")
|
||||
)
|
||||
},
|
||||
"required": [
|
||||
name
|
||||
for name, param in inspect.signature(
|
||||
function
|
||||
).parameters.items()
|
||||
if param.default is param.empty
|
||||
and not (name.startswith("__") and name.endswith("__"))
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return specs
|
||||
def get_tools_specs(tool_class: object) -> list[dict]:
|
||||
function_list = get_callable_attributes(tool_class)
|
||||
models = map(function_to_pydantic_model, function_list)
|
||||
return [convert_to_openai_function(tool) for tool in models]
|
||||
|
||||
@@ -14,6 +14,7 @@ requests==2.32.3
|
||||
aiohttp==3.10.8
|
||||
async-timeout
|
||||
aiocache
|
||||
aiofiles
|
||||
|
||||
sqlalchemy==2.0.32
|
||||
alembic==1.13.2
|
||||
@@ -37,8 +38,8 @@ anthropic
|
||||
google-generativeai==0.7.2
|
||||
tiktoken
|
||||
|
||||
langchain==0.3.5
|
||||
langchain-community==0.3.3
|
||||
langchain==0.3.7
|
||||
langchain-community==0.3.7
|
||||
langchain-chroma==0.1.4
|
||||
|
||||
fake-useragent==1.5.1
|
||||
@@ -82,7 +83,7 @@ authlib==1.3.2
|
||||
|
||||
black==24.8.0
|
||||
langfuse==2.44.0
|
||||
youtube-transcript-api==0.6.2
|
||||
youtube-transcript-api==0.6.3
|
||||
pytube==15.0.0
|
||||
|
||||
extract_msg
|
||||
|
||||
Generated
+942
-15
File diff suppressed because it is too large
Load Diff
+9
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "open-webui",
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run pyodide:fetch && vite dev --host",
|
||||
@@ -37,6 +37,7 @@
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"sass-embedded": "^1.81.0",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.5",
|
||||
"svelte-confetti": "^1.3.2",
|
||||
@@ -56,6 +57,13 @@
|
||||
"@mediapipe/tasks-vision": "^0.10.17",
|
||||
"@pyscript/core": "^0.4.32",
|
||||
"@sveltejs/adapter-node": "^2.0.0",
|
||||
"@tiptap/core": "^2.10.0",
|
||||
"@tiptap/extension-code-block-lowlight": "^2.10.0",
|
||||
"@tiptap/extension-highlight": "^2.10.0",
|
||||
"@tiptap/extension-placeholder": "^2.10.0",
|
||||
"@tiptap/extension-typography": "^2.10.0",
|
||||
"@tiptap/pm": "^2.10.0",
|
||||
"@tiptap/starter-kit": "^2.10.0",
|
||||
"@xyflow/svelte": "^0.1.19",
|
||||
"async": "^3.2.5",
|
||||
"bits-ui": "^0.19.7",
|
||||
|
||||
+4
-3
@@ -22,6 +22,7 @@ dependencies = [
|
||||
"aiohttp==3.10.8",
|
||||
"async-timeout",
|
||||
"aiocache",
|
||||
"aiofiles",
|
||||
|
||||
"sqlalchemy==2.0.32",
|
||||
"alembic==1.13.2",
|
||||
@@ -44,8 +45,8 @@ dependencies = [
|
||||
"google-generativeai==0.7.2",
|
||||
"tiktoken",
|
||||
|
||||
"langchain==0.3.5",
|
||||
"langchain-community==0.3.3",
|
||||
"langchain==0.3.7",
|
||||
"langchain-community==0.3.7",
|
||||
"langchain-chroma==0.1.4",
|
||||
|
||||
"fake-useragent==1.5.1",
|
||||
@@ -88,7 +89,7 @@ dependencies = [
|
||||
|
||||
"black==24.8.0",
|
||||
"langfuse==2.44.0",
|
||||
"youtube-transcript-api==0.6.2",
|
||||
"youtube-transcript-api==0.6.3",
|
||||
"pytube==15.0.0",
|
||||
|
||||
"extract_msg",
|
||||
|
||||
+82
-6
@@ -199,19 +199,95 @@ input[type='number'] {
|
||||
}
|
||||
|
||||
.ProseMirror {
|
||||
@apply h-full min-h-fit max-h-full whitespace-pre-wrap;
|
||||
@apply h-full min-h-fit max-h-full whitespace-pre-wrap;
|
||||
}
|
||||
|
||||
.ProseMirror:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.placeholder::after {
|
||||
.ProseMirror p.is-editor-empty:first-child::before {
|
||||
content: attr(data-placeholder);
|
||||
cursor: text;
|
||||
pointer-events: none;
|
||||
|
||||
float: left;
|
||||
color: #adb5bd;
|
||||
pointer-events: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@apply absolute inset-0 z-0 text-gray-500;
|
||||
.tiptap > pre > code {
|
||||
border-radius: 0.4rem;
|
||||
font-size: 0.85rem;
|
||||
padding: 0.25em 0.3em;
|
||||
|
||||
@apply dark:bg-gray-800 bg-gray-100;
|
||||
}
|
||||
|
||||
.tiptap > pre {
|
||||
border-radius: 0.5rem;
|
||||
font-family: 'JetBrainsMono', monospace;
|
||||
margin: 1.5rem 0;
|
||||
padding: 0.75rem 1rem;
|
||||
|
||||
@apply dark:bg-gray-800 bg-gray-100;
|
||||
}
|
||||
|
||||
.tiptap p code {
|
||||
color: #eb5757;
|
||||
border-width: 0px;
|
||||
padding: 3px 8px;
|
||||
font-size: 0.8em;
|
||||
font-weight: 600;
|
||||
@apply rounded-md dark:bg-gray-800 bg-gray-100 mx-0.5;
|
||||
}
|
||||
|
||||
/* Code styling */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #f98181;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #fbbc88;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #b9f18d;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #faf594;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #70cff8;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -58,17 +58,44 @@ export const exportConfig = async (token: string) => {
|
||||
return res;
|
||||
};
|
||||
|
||||
export const setDefaultModels = async (token: string, models: string) => {
|
||||
export const getModelsConfig = async (token: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/configs/default/models`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/configs/models`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
error = err.detail;
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const setModelsConfig = async (token: string, config: object) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/configs/models`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
models: models
|
||||
...config
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
@@ -91,7 +118,7 @@ export const setDefaultModels = async (token: string, models: string) => {
|
||||
export const setDefaultPromptSuggestions = async (token: string, promptSuggestions: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/configs/default/suggestions`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/configs/suggestions`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
+9
-34
@@ -25,26 +25,6 @@ export const getModels = async (token: string = '', base: boolean = false) => {
|
||||
}
|
||||
|
||||
let models = res?.data ?? [];
|
||||
models = models
|
||||
.filter((models) => models)
|
||||
// Sort the models
|
||||
.sort((a, b) => {
|
||||
// Compare case-insensitively by name for models without position property
|
||||
const lowerA = a.name.toLowerCase();
|
||||
const lowerB = b.name.toLowerCase();
|
||||
|
||||
if (lowerA < lowerB) return -1;
|
||||
if (lowerA > lowerB) return 1;
|
||||
|
||||
// If same case-insensitively, sort by original strings,
|
||||
// lowercase will come before uppercase due to ASCII values
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
|
||||
return 0; // They are equal
|
||||
});
|
||||
|
||||
console.log(models);
|
||||
return models;
|
||||
};
|
||||
|
||||
@@ -387,20 +367,15 @@ export const generateQueries = async (
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Step 1: Safely extract the response string
|
||||
const response = res?.choices[0]?.message?.content ?? '';
|
||||
|
||||
try {
|
||||
// Step 1: Safely extract the response string
|
||||
const response = res?.choices[0]?.message?.content ?? '';
|
||||
const jsonStartIndex = response.indexOf('{');
|
||||
const jsonEndIndex = response.lastIndexOf('}');
|
||||
|
||||
// Step 2: Attempt to fix common JSON format issues like single quotes
|
||||
const sanitizedResponse = response.replace(/['‘’`]/g, '"'); // Convert single quotes to double quotes for valid JSON
|
||||
|
||||
// Step 3: Find the relevant JSON block within the response
|
||||
const jsonStartIndex = sanitizedResponse.indexOf('{');
|
||||
const jsonEndIndex = sanitizedResponse.lastIndexOf('}');
|
||||
|
||||
// Step 4: Check if we found a valid JSON block (with both `{` and `}`)
|
||||
if (jsonStartIndex !== -1 && jsonEndIndex !== -1) {
|
||||
const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1);
|
||||
const jsonResponse = response.substring(jsonStartIndex, jsonEndIndex + 1);
|
||||
|
||||
// Step 5: Parse the JSON block
|
||||
const parsed = JSON.parse(jsonResponse);
|
||||
@@ -413,12 +388,12 @@ export const generateQueries = async (
|
||||
}
|
||||
}
|
||||
|
||||
// If no valid JSON block found, return an empty array
|
||||
return [];
|
||||
// If no valid JSON block found, return response as is
|
||||
return [response];
|
||||
} catch (e) {
|
||||
// Catch and safely return empty array on any parsing errors
|
||||
console.error('Failed to parse response: ', e);
|
||||
return [];
|
||||
return [response];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||
export const getModels = async (token: string = '') => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
@@ -97,7 +97,7 @@ export const getModelById = async (token: string, id: string) => {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('id', id);
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/id/${id}`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/model?${searchParams.toString()}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
@@ -132,7 +132,7 @@ export const toggleModelById = async (token: string, id: string) => {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('id', id);
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/id/${id}/toggle`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/toggle?${searchParams.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
@@ -167,7 +167,7 @@ export const updateModelById = async (token: string, id: string, model: object)
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('id', id);
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/id/${id}/update`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/update?${searchParams.toString()}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
@@ -203,7 +203,7 @@ export const deleteModelById = async (token: string, id: string) => {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append('id', id);
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/id/${id}/delete`, {
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/delete?${searchParams.toString()}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
|
||||
@@ -5,7 +5,7 @@ type TextStreamUpdate = {
|
||||
done: boolean;
|
||||
value: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
citations?: any;
|
||||
sources?: any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
selectedModelId?: any;
|
||||
error?: any;
|
||||
@@ -67,8 +67,8 @@ async function* openAIStreamToIterator(
|
||||
break;
|
||||
}
|
||||
|
||||
if (parsedData.citations) {
|
||||
yield { done: false, value: '', citations: parsedData.citations };
|
||||
if (parsedData.sources) {
|
||||
yield { done: false, value: '', sources: parsedData.sources };
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ async function* streamLargeDeltasAsRandomChunks(
|
||||
yield textStreamUpdate;
|
||||
return;
|
||||
}
|
||||
if (textStreamUpdate.citations) {
|
||||
if (textStreamUpdate.sources) {
|
||||
yield textStreamUpdate;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mb-5">
|
||||
{#each filteredItems as func}
|
||||
{#each filteredItems as func (func.id)}
|
||||
<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"
|
||||
>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
/>
|
||||
|
||||
{#if pipeline}
|
||||
<div class=" absolute top-2.5 right-2.5">
|
||||
<div class=" absolute top-0.5 right-2.5">
|
||||
<Tooltip content="Pipelines">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
import { getModels } from '$lib/apis';
|
||||
import { getConfig, updateConfig } from '$lib/apis/evaluations';
|
||||
|
||||
import Switch from '$lib/components/common/Switch.svelte';
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
@@ -12,7 +13,6 @@
|
||||
import Plus from '$lib/components/icons/Plus.svelte';
|
||||
import Model from './Evaluations/Model.svelte';
|
||||
import ArenaModelModal from './Evaluations/ArenaModelModal.svelte';
|
||||
import { getConfig, updateConfig } from '$lib/apis/evaluations';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
if (config) {
|
||||
toast.success('Settings saved successfully');
|
||||
models.set(await getModels(localStorage.token));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
description = model.meta.description;
|
||||
modelIds = model.meta.model_ids || [];
|
||||
filterMode = model.meta?.filter_mode ?? 'include';
|
||||
accessControl = model.meta?.access_control ?? {};
|
||||
accessControl = 'access_control' in model.meta ? model.meta.access_control : {};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -375,7 +375,7 @@
|
||||
<div class="flex justify-end pt-3 text-sm font-medium gap-1.5">
|
||||
{#if edit}
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium dark:bg-black dark:hover:bg-gray-900 dark:text-white bg-white text-black hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center"
|
||||
class="px-3.5 py-1.5 text-sm font-medium dark:bg-black dark:hover:bg-gray-950 dark:text-white bg-white text-black hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
dispatch('delete', model);
|
||||
@@ -387,7 +387,7 @@
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center {loading
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-950 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center {loading
|
||||
? ' cursor-not-allowed'
|
||||
: ''}"
|
||||
type="submit"
|
||||
|
||||
@@ -55,255 +55,176 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<form
|
||||
class="flex flex-col h-full justify-between space-y-3 text-sm"
|
||||
on:submit|preventDefault={() => {
|
||||
updateInterfaceHandler();
|
||||
dispatch('save');
|
||||
}}
|
||||
>
|
||||
<div class=" overflow-y-scroll scrollbar-hidden h-full pr-1.5">
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium flex items-center">
|
||||
<div class=" mr-1">{$i18n.t('Set Task Model')}</div>
|
||||
<Tooltip
|
||||
content={$i18n.t(
|
||||
'A task model is used when performing tasks such as generating titles for chats and web search queries'
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-3.5"
|
||||
{#if taskConfig}
|
||||
<form
|
||||
class="flex flex-col h-full justify-between space-y-3 text-sm"
|
||||
on:submit|preventDefault={() => {
|
||||
updateInterfaceHandler();
|
||||
dispatch('save');
|
||||
}}
|
||||
>
|
||||
<div class=" overflow-y-scroll scrollbar-hidden h-full pr-1.5">
|
||||
<div>
|
||||
<div class=" mb-2.5 text-sm font-medium flex items-center">
|
||||
<div class=" mr-1">{$i18n.t('Set Task Model')}</div>
|
||||
<Tooltip
|
||||
content={$i18n.t(
|
||||
'A task model is used when performing tasks such as generating titles for chats and web search queries'
|
||||
)}
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-xs mb-1">{$i18n.t('Local Models')}</div>
|
||||
<select
|
||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
bind:value={taskConfig.TASK_MODEL}
|
||||
placeholder={$i18n.t('Select a model')}
|
||||
>
|
||||
<option value="" selected>{$i18n.t('Current Model')}</option>
|
||||
{#each $models.filter((m) => m.owned_by === 'ollama') as model}
|
||||
<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
|
||||
{model.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="size-3.5"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="flex-1">
|
||||
<div class=" text-xs mb-1">{$i18n.t('Local Models')}</div>
|
||||
<select
|
||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
bind:value={taskConfig.TASK_MODEL}
|
||||
placeholder={$i18n.t('Select a model')}
|
||||
>
|
||||
<option value="" selected>{$i18n.t('Current Model')}</option>
|
||||
{#each $models.filter((m) => m.owned_by === 'ollama') as model}
|
||||
<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
|
||||
{model.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-xs mb-1">{$i18n.t('External Models')}</div>
|
||||
<select
|
||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
bind:value={taskConfig.TASK_MODEL_EXTERNAL}
|
||||
placeholder={$i18n.t('Select a model')}
|
||||
>
|
||||
<option value="" selected>{$i18n.t('Current Model')}</option>
|
||||
{#each $models as model}
|
||||
<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
|
||||
{model.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1">
|
||||
<div class=" text-xs mb-1">{$i18n.t('External Models')}</div>
|
||||
<select
|
||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
bind:value={taskConfig.TASK_MODEL_EXTERNAL}
|
||||
placeholder={$i18n.t('Select a model')}
|
||||
>
|
||||
<option value="" selected>{$i18n.t('Current Model')}</option>
|
||||
{#each $models as model}
|
||||
<option value={model.id} class="bg-gray-100 dark:bg-gray-700">
|
||||
{model.name}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Title Generation Prompt')}</div>
|
||||
|
||||
<Tooltip
|
||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
placement="top-start"
|
||||
>
|
||||
<Textarea
|
||||
bind:value={taskConfig.TITLE_GENERATION_PROMPT_TEMPLATE}
|
||||
placeholder={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<hr class=" dark:border-gray-850 my-3" />
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Tags Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_TAGS_GENERATION} />
|
||||
</div>
|
||||
|
||||
{#if taskConfig.ENABLE_TAGS_GENERATION}
|
||||
<div class="mt-3">
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Tags Generation Prompt')}</div>
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Title Generation Prompt')}</div>
|
||||
|
||||
<Tooltip
|
||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
placement="top-start"
|
||||
>
|
||||
<Textarea
|
||||
bind:value={taskConfig.TAGS_GENERATION_PROMPT_TEMPLATE}
|
||||
bind:value={taskConfig.TITLE_GENERATION_PROMPT_TEMPLATE}
|
||||
placeholder={$i18n.t(
|
||||
'Leave empty to use the default prompt, or enter a custom prompt'
|
||||
)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<hr class=" dark:border-gray-850 my-3" />
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Tags Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_TAGS_GENERATION} />
|
||||
</div>
|
||||
|
||||
{#if taskConfig.ENABLE_TAGS_GENERATION}
|
||||
<div class="mt-3">
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Tags Generation Prompt')}</div>
|
||||
|
||||
<Tooltip
|
||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
placement="top-start"
|
||||
>
|
||||
<Textarea
|
||||
bind:value={taskConfig.TAGS_GENERATION_PROMPT_TEMPLATE}
|
||||
placeholder={$i18n.t(
|
||||
'Leave empty to use the default prompt, or enter a custom prompt'
|
||||
)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<hr class=" dark:border-gray-850 my-3" />
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Retrieval Query Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_RETRIEVAL_QUERY_GENERATION} />
|
||||
</div>
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Web Search Query Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_SEARCH_QUERY_GENERATION} />
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Query Generation Prompt')}</div>
|
||||
|
||||
<Tooltip
|
||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
placement="top-start"
|
||||
>
|
||||
<Textarea
|
||||
bind:value={taskConfig.QUERY_GENERATION_PROMPT_TEMPLATE}
|
||||
placeholder={$i18n.t(
|
||||
'Leave empty to use the default prompt, or enter a custom prompt'
|
||||
)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class=" dark:border-gray-850 my-3" />
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Retrieval Query Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_RETRIEVAL_QUERY_GENERATION} />
|
||||
</div>
|
||||
|
||||
<div class="my-3 flex w-full items-center justify-between">
|
||||
<div class=" self-center text-xs font-medium">
|
||||
{$i18n.t('Enable Web Search Query Generation')}
|
||||
</div>
|
||||
|
||||
<Switch bind:state={taskConfig.ENABLE_SEARCH_QUERY_GENERATION} />
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div class=" mb-2.5 text-xs font-medium">{$i18n.t('Query Generation Prompt')}</div>
|
||||
|
||||
<Tooltip
|
||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
placement="top-start"
|
||||
>
|
||||
<Textarea
|
||||
bind:value={taskConfig.QUERY_GENERATION_PROMPT_TEMPLATE}
|
||||
placeholder={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class=" dark:border-gray-850 my-3" />
|
||||
|
||||
<div class=" space-y-3 {banners.length > 0 ? ' mb-3' : ''}">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">
|
||||
{$i18n.t('Banners')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (banners.length === 0 || banners.at(-1).content !== '') {
|
||||
banners = [
|
||||
...banners,
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: '',
|
||||
title: '',
|
||||
content: '',
|
||||
dismissible: true,
|
||||
timestamp: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
];
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-1">
|
||||
{#each banners as banner, bannerIdx}
|
||||
<div class=" flex justify-between">
|
||||
<div class="flex flex-row flex-1 border rounded-xl dark:border-gray-800">
|
||||
<select
|
||||
class="w-fit capitalize rounded-xl py-2 px-4 text-xs bg-transparent outline-none"
|
||||
bind:value={banner.type}
|
||||
required
|
||||
>
|
||||
{#if banner.type == ''}
|
||||
<option value="" selected disabled class="text-gray-900">{$i18n.t('Type')}</option
|
||||
>
|
||||
{/if}
|
||||
<option value="info" class="text-gray-900">{$i18n.t('Info')}</option>
|
||||
<option value="warning" class="text-gray-900">{$i18n.t('Warning')}</option>
|
||||
<option value="error" class="text-gray-900">{$i18n.t('Error')}</option>
|
||||
<option value="success" class="text-gray-900">{$i18n.t('Success')}</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
class="pr-5 py-1.5 text-xs w-full bg-transparent outline-none"
|
||||
placeholder={$i18n.t('Content')}
|
||||
bind:value={banner.content}
|
||||
/>
|
||||
|
||||
<div class="relative top-1.5 -left-2">
|
||||
<Tooltip content={$i18n.t('Dismissible')} className="flex h-fit items-center">
|
||||
<Switch bind:state={banner.dismissible} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="px-2"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
banners.splice(bannerIdx, 1);
|
||||
banners = banners;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<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>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $user.role === 'admin'}
|
||||
<div class=" space-y-3">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" space-y-3 {banners.length > 0 ? ' mb-3' : ''}">
|
||||
<div class="flex w-full justify-between">
|
||||
<div class=" self-center text-sm font-semibold">
|
||||
{$i18n.t('Default Prompt Suggestions')}
|
||||
{$i18n.t('Banners')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (promptSuggestions.length === 0 || promptSuggestions.at(-1).content !== '') {
|
||||
promptSuggestions = [...promptSuggestions, { content: '', title: ['', ''] }];
|
||||
if (banners.length === 0 || banners.at(-1).content !== '') {
|
||||
banners = [
|
||||
...banners,
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: '',
|
||||
title: '',
|
||||
content: '',
|
||||
dismissible: true,
|
||||
timestamp: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
];
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -319,40 +240,45 @@
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid lg:grid-cols-2 flex-col gap-1.5">
|
||||
{#each promptSuggestions as prompt, promptIdx}
|
||||
<div
|
||||
class=" flex border border-gray-100 dark:border-none dark:bg-gray-850 rounded-xl py-1.5"
|
||||
>
|
||||
<div class="flex flex-col flex-1 pl-1">
|
||||
<div class="flex border-b border-gray-100 dark:border-gray-800 w-full">
|
||||
<input
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800"
|
||||
placeholder={$i18n.t('Title (e.g. Tell me a fun fact)')}
|
||||
bind:value={prompt.title[0]}
|
||||
/>
|
||||
<div class="flex flex-col space-y-1">
|
||||
{#each banners as banner, bannerIdx}
|
||||
<div class=" flex justify-between">
|
||||
<div class="flex flex-row flex-1 border rounded-xl dark:border-gray-800">
|
||||
<select
|
||||
class="w-fit capitalize rounded-xl py-2 px-4 text-xs bg-transparent outline-none"
|
||||
bind:value={banner.type}
|
||||
required
|
||||
>
|
||||
{#if banner.type == ''}
|
||||
<option value="" selected disabled class="text-gray-900"
|
||||
>{$i18n.t('Type')}</option
|
||||
>
|
||||
{/if}
|
||||
<option value="info" class="text-gray-900">{$i18n.t('Info')}</option>
|
||||
<option value="warning" class="text-gray-900">{$i18n.t('Warning')}</option>
|
||||
<option value="error" class="text-gray-900">{$i18n.t('Error')}</option>
|
||||
<option value="success" class="text-gray-900">{$i18n.t('Success')}</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800"
|
||||
placeholder={$i18n.t('Subtitle (e.g. about the Roman Empire)')}
|
||||
bind:value={prompt.title[1]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800 resize-none"
|
||||
placeholder={$i18n.t('Prompt (e.g. Tell me a fun fact about the Roman Empire)')}
|
||||
rows="3"
|
||||
bind:value={prompt.content}
|
||||
<input
|
||||
class="pr-5 py-1.5 text-xs w-full bg-transparent outline-none"
|
||||
placeholder={$i18n.t('Content')}
|
||||
bind:value={banner.content}
|
||||
/>
|
||||
|
||||
<div class="relative top-1.5 -left-2">
|
||||
<Tooltip content={$i18n.t('Dismissible')} className="flex h-fit items-center">
|
||||
<Switch bind:state={banner.dismissible} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="px-3"
|
||||
class="px-2"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
promptSuggestions.splice(promptIdx, 1);
|
||||
promptSuggestions = promptSuggestions;
|
||||
banners.splice(bannerIdx, 1);
|
||||
banners = banners;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
@@ -369,22 +295,103 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if promptSuggestions.length > 0}
|
||||
<div class="text-xs text-left w-full mt-2">
|
||||
{$i18n.t('Adjusting these settings will apply changes universally to all users.')}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end text-sm font-medium">
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
|
||||
type="submit"
|
||||
>
|
||||
{$i18n.t('Save')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{#if $user.role === 'admin'}
|
||||
<div class=" space-y-3">
|
||||
<div class="flex w-full justify-between mb-2">
|
||||
<div class=" self-center text-sm font-semibold">
|
||||
{$i18n.t('Default Prompt Suggestions')}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="p-1 px-3 text-xs flex rounded transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (promptSuggestions.length === 0 || promptSuggestions.at(-1).content !== '') {
|
||||
promptSuggestions = [...promptSuggestions, { content: '', title: ['', ''] }];
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<path
|
||||
d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid lg:grid-cols-2 flex-col gap-1.5">
|
||||
{#each promptSuggestions as prompt, promptIdx}
|
||||
<div
|
||||
class=" flex border border-gray-100 dark:border-none dark:bg-gray-850 rounded-xl py-1.5"
|
||||
>
|
||||
<div class="flex flex-col flex-1 pl-1">
|
||||
<div class="flex border-b border-gray-100 dark:border-gray-800 w-full">
|
||||
<input
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800"
|
||||
placeholder={$i18n.t('Title (e.g. Tell me a fun fact)')}
|
||||
bind:value={prompt.title[0]}
|
||||
/>
|
||||
|
||||
<input
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800"
|
||||
placeholder={$i18n.t('Subtitle (e.g. about the Roman Empire)')}
|
||||
bind:value={prompt.title[1]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
class="px-3 py-1.5 text-xs w-full bg-transparent outline-none border-r border-gray-100 dark:border-gray-800 resize-none"
|
||||
placeholder={$i18n.t('Prompt (e.g. Tell me a fun fact about the Roman Empire)')}
|
||||
rows="3"
|
||||
bind:value={prompt.content}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="px-3"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
promptSuggestions.splice(promptIdx, 1);
|
||||
promptSuggestions = promptSuggestions;
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
class="w-4 h-4"
|
||||
>
|
||||
<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>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if promptSuggestions.length > 0}
|
||||
<div class="text-xs text-left w-full mt-2">
|
||||
{$i18n.t('Adjusting these settings will apply changes universally to all users.')}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end text-sm font-medium">
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
|
||||
type="submit"
|
||||
>
|
||||
{$i18n.t('Save')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
import ModelEditor from '$lib/components/workspace/Models/ModelEditor.svelte';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||
import Cog6 from '$lib/components/icons/Cog6.svelte';
|
||||
import ConfigureModelsModal from './Models/ConfigureModelsModal.svelte';
|
||||
|
||||
let importFiles;
|
||||
let modelsImportInputElement: HTMLInputElement;
|
||||
@@ -35,12 +37,20 @@
|
||||
|
||||
let filteredModels = [];
|
||||
let selectedModelId = null;
|
||||
let showResetModal = false;
|
||||
|
||||
let showConfigModal = false;
|
||||
|
||||
$: if (models) {
|
||||
filteredModels = models.filter(
|
||||
(m) => searchValue === '' || m.name.toLowerCase().includes(searchValue.toLowerCase())
|
||||
);
|
||||
filteredModels = models
|
||||
.filter((m) => searchValue === '' || m.name.toLowerCase().includes(searchValue.toLowerCase()))
|
||||
.sort((a, b) => {
|
||||
// Check if either model is inactive and push them to the bottom
|
||||
if ((a.is_active ?? true) !== (b.is_active ?? true)) {
|
||||
return (b.is_active ?? true) - (a.is_active ?? true);
|
||||
}
|
||||
// If both models' active states are the same, sort alphabetically
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
}
|
||||
|
||||
let searchValue = '';
|
||||
@@ -114,12 +124,11 @@
|
||||
}).catch((error) => {
|
||||
return null;
|
||||
});
|
||||
|
||||
await init();
|
||||
} else {
|
||||
await toggleModelById(localStorage.token, model.id);
|
||||
}
|
||||
|
||||
await init();
|
||||
_models.set(await getModels(localStorage.token));
|
||||
};
|
||||
|
||||
@@ -128,18 +137,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<ConfirmDialog
|
||||
title={$i18n.t('Delete All Models')}
|
||||
message={$i18n.t('This will delete all models including custom models and cannot be undone.')}
|
||||
bind:show={showResetModal}
|
||||
onConfirm={async () => {
|
||||
const res = deleteAllModels(localStorage.token);
|
||||
if (res) {
|
||||
toast.success($i18n.t('All models deleted successfully'));
|
||||
init();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ConfigureModelsModal bind:show={showConfigModal} {init} />
|
||||
|
||||
{#if models !== null}
|
||||
{#if selectedModelId === null}
|
||||
@@ -154,17 +152,15 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Tooltip content={$i18n.t('This will delete all models including custom models')}>
|
||||
<Tooltip content={$i18n.t('Configure')}>
|
||||
<button
|
||||
class=" px-2.5 py-1 rounded-full flex gap-1 items-center"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
showResetModal = true;
|
||||
showConfigModal = true;
|
||||
}}
|
||||
>
|
||||
<div class="text-xs flex-shrink-0">
|
||||
{$i18n.t('Reset')}
|
||||
</div>
|
||||
<Cog6 />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@@ -186,7 +182,7 @@
|
||||
|
||||
<div class=" my-2 mb-5" id="model-list">
|
||||
{#if models.length > 0}
|
||||
{#each filteredModels as model (model.id)}
|
||||
{#each filteredModels as model, modelIdx (model.id)}
|
||||
<div
|
||||
class=" flex space-x-4 cursor-pointer w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-lg transition"
|
||||
id="model-item-{model.id}"
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
<script>
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
import { createEventDispatcher, getContext, onMount } from 'svelte';
|
||||
const i18n = getContext('i18n');
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import { models } from '$lib/stores';
|
||||
import { deleteAllModels } from '$lib/apis/models';
|
||||
|
||||
import Modal from '$lib/components/common/Modal.svelte';
|
||||
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import ModelList from './ModelList.svelte';
|
||||
import { getModelsConfig, setModelsConfig } from '$lib/apis/configs';
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
import Minus from '$lib/components/icons/Minus.svelte';
|
||||
import Plus from '$lib/components/icons/Plus.svelte';
|
||||
|
||||
export let show = false;
|
||||
export let init = () => {};
|
||||
|
||||
let config = null;
|
||||
|
||||
let selectedModelId = '';
|
||||
let defaultModelIds = [];
|
||||
let modelIds = [];
|
||||
|
||||
let loading = false;
|
||||
let showResetModal = false;
|
||||
|
||||
const submitHandler = async () => {
|
||||
loading = true;
|
||||
|
||||
const res = await setModelsConfig(localStorage.token, {
|
||||
DEFAULT_MODELS: defaultModelIds.join(','),
|
||||
MODEL_ORDER_LIST: modelIds
|
||||
});
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Models configuration saved successfully'));
|
||||
init();
|
||||
show = false;
|
||||
} else {
|
||||
toast.error($i18n.t('Failed to save models configuration'));
|
||||
}
|
||||
|
||||
loading = false;
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
config = await getModelsConfig(localStorage.token);
|
||||
|
||||
if (config?.DEFAULT_MODELS) {
|
||||
defaultModelIds = (config?.DEFAULT_MODELS).split(',').filter((id) => id);
|
||||
} else {
|
||||
defaultModelIds = [];
|
||||
}
|
||||
const modelOrderList = config.MODEL_ORDER_LIST || [];
|
||||
const allModelIds = $models.map((model) => model.id);
|
||||
|
||||
// Create a Set for quick lookup of ordered IDs
|
||||
const orderedSet = new Set(modelOrderList);
|
||||
|
||||
modelIds = [
|
||||
// Add all IDs from MODEL_ORDER_LIST that exist in allModelIds
|
||||
...modelOrderList.filter((id) => orderedSet.has(id) && allModelIds.includes(id)),
|
||||
// Add remaining IDs not in MODEL_ORDER_LIST, sorted alphabetically
|
||||
...allModelIds.filter((id) => !orderedSet.has(id)).sort((a, b) => a.localeCompare(b))
|
||||
];
|
||||
});
|
||||
</script>
|
||||
|
||||
<ConfirmDialog
|
||||
title={$i18n.t('Reset All Models')}
|
||||
message={$i18n.t('This will delete all models including custom models and cannot be undone.')}
|
||||
bind:show={showResetModal}
|
||||
onConfirm={async () => {
|
||||
const res = deleteAllModels(localStorage.token);
|
||||
if (res) {
|
||||
toast.success($i18n.t('All models deleted successfully'));
|
||||
init();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Modal size="sm" bind:show>
|
||||
<div>
|
||||
<div class=" flex justify-between dark:text-gray-100 px-5 pt-4 pb-2">
|
||||
<div class=" text-lg font-medium self-center font-primary">
|
||||
{$i18n.t('Configure Models')}
|
||||
</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">
|
||||
{#if config}
|
||||
<form
|
||||
class="flex flex-col w-full"
|
||||
on:submit|preventDefault={() => {
|
||||
submitHandler();
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="mb-1 flex justify-between">
|
||||
<div class="text-xs text-gray-500">{$i18n.t('Reorder Models')}</div>
|
||||
</div>
|
||||
|
||||
<ModelList bind:modelIds />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class=" border-gray-100 dark:border-gray-700/10 my-2.5 w-full" />
|
||||
|
||||
<div>
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="mb-1 flex justify-between">
|
||||
<div class="text-xs text-gray-500">{$i18n.t('Default Models')}</div>
|
||||
</div>
|
||||
|
||||
{#if defaultModelIds.length > 0}
|
||||
<div class="flex flex-col">
|
||||
{#each defaultModelIds as modelId, modelIdx}
|
||||
<div class=" flex gap-2 w-full justify-between items-center">
|
||||
<div class=" text-sm flex-1 py-1 rounded-lg">
|
||||
{$models.find((model) => model.id === modelId)?.name}
|
||||
</div>
|
||||
<div class="flex-shrink-0">
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
defaultModelIds = defaultModelIds.filter(
|
||||
(_, idx) => idx !== modelIdx
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Minus strokeWidth="2" className="size-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-gray-500 text-xs text-center py-2">
|
||||
{$i18n.t('No models selected')}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<hr class=" border-gray-100 dark:border-gray-700/10 my-2.5 w-full" />
|
||||
|
||||
<div class="flex items-center">
|
||||
<select
|
||||
class="w-full py-1 text-sm rounded-lg bg-transparent {selectedModelId
|
||||
? ''
|
||||
: 'text-gray-500'} placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-none"
|
||||
bind:value={selectedModelId}
|
||||
>
|
||||
<option value="">{$i18n.t('Select a model')}</option>
|
||||
{#each $models as model}
|
||||
<option value={model.id} class="bg-gray-50 dark:bg-gray-700"
|
||||
>{model.name}</option
|
||||
>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
if (defaultModelIds.includes(selectedModelId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
defaultModelIds = [...defaultModelIds, selectedModelId];
|
||||
selectedModelId = '';
|
||||
}}
|
||||
>
|
||||
<Plus className="size-3.5" strokeWidth="2" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between pt-3 text-sm font-medium gap-1.5">
|
||||
<Tooltip content={$i18n.t('This will delete all models including custom models')}>
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium dark:bg-black dark:hover:bg-gray-950 dark:text-white bg-white text-black hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
showResetModal = true;
|
||||
}}
|
||||
>
|
||||
{$i18n.t('Delete All Models')}
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<button
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full flex flex-row space-x-1 items-center {loading
|
||||
? ' cursor-not-allowed'
|
||||
: ''}"
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
>
|
||||
{$i18n.t('Save')}
|
||||
|
||||
{#if loading}
|
||||
<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>
|
||||
{:else}
|
||||
<div>
|
||||
<Spinner />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
@@ -0,0 +1,58 @@
|
||||
<script lang="ts">
|
||||
import Sortable from 'sortablejs';
|
||||
|
||||
import { createEventDispatcher, getContext, onMount } from 'svelte';
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
import { models } from '$lib/stores';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import EllipsisVertical from '$lib/components/icons/EllipsisVertical.svelte';
|
||||
|
||||
export let modelIds = [];
|
||||
|
||||
let sortable = null;
|
||||
let modelListElement = null;
|
||||
|
||||
const positionChangeHandler = () => {
|
||||
const modelList = Array.from(modelListElement.children).map((child) =>
|
||||
child.id.replace('model-item-', '')
|
||||
);
|
||||
|
||||
modelIds = modelList;
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
sortable = Sortable.create(modelListElement, {
|
||||
animation: 150,
|
||||
onUpdate: async (event) => {
|
||||
positionChangeHandler();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if modelIds.length > 0}
|
||||
<div class="flex flex-col -translate-x-1" bind:this={modelListElement}>
|
||||
{#each modelIds as modelId, modelIdx (modelId)}
|
||||
<div class=" flex gap-2 w-full justify-between items-center" id="model-item-{modelId}">
|
||||
<Tooltip content={modelId} placement="top-start">
|
||||
<div class="flex items-center gap-1">
|
||||
<EllipsisVertical className="size-4 cursor-move" />
|
||||
|
||||
<div class=" text-sm flex-1 py-1 rounded-lg">
|
||||
{#if $models.find((model) => model.id === modelId)}
|
||||
{$models.find((model) => model.id === modelId).name}
|
||||
{:else}
|
||||
{modelId}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-gray-500 text-xs text-center py-2">
|
||||
{$i18n.t('No models found')}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -16,6 +16,7 @@
|
||||
'searxng',
|
||||
'google_pse',
|
||||
'brave',
|
||||
'mojeek',
|
||||
'serpstack',
|
||||
'serper',
|
||||
'serply',
|
||||
@@ -151,6 +152,17 @@
|
||||
bind:value={webConfig.search.brave_search_api_key}
|
||||
/>
|
||||
</div>
|
||||
{:else if webConfig.search.engine === 'mojeek'}
|
||||
<div>
|
||||
<div class=" self-center text-xs font-medium mb-1">
|
||||
{$i18n.t('Mojeek Search API Key')}
|
||||
</div>
|
||||
|
||||
<SensitiveInput
|
||||
placeholder={$i18n.t('Enter Mojeek Search API Key')}
|
||||
bind:value={webConfig.search.mojeek_search_api_key}
|
||||
/>
|
||||
</div>
|
||||
{:else if webConfig.search.engine === 'serpstack'}
|
||||
<div>
|
||||
<div class=" self-center text-xs font-medium mb-1">
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
} else {
|
||||
message.statusHistory = [data];
|
||||
}
|
||||
} else if (type === 'citation') {
|
||||
} else if (type === 'source' || type === 'citation') {
|
||||
if (data?.type === 'code_execution') {
|
||||
// Code execution; update existing code execution by ID, or add new one.
|
||||
if (!message?.code_executions) {
|
||||
@@ -235,11 +235,11 @@
|
||||
|
||||
message.code_executions = message.code_executions;
|
||||
} else {
|
||||
// Regular citation.
|
||||
if (message?.citations) {
|
||||
message.citations.push(data);
|
||||
// Regular source.
|
||||
if (message?.sources) {
|
||||
message.sources.push(data);
|
||||
} else {
|
||||
message.citations = [data];
|
||||
message.sources = [data];
|
||||
}
|
||||
}
|
||||
} else if (type === 'message') {
|
||||
@@ -663,7 +663,8 @@
|
||||
role: m.role,
|
||||
content: m.content,
|
||||
info: m.info ? m.info : undefined,
|
||||
timestamp: m.timestamp
|
||||
timestamp: m.timestamp,
|
||||
...(m.sources ? { sources: m.sources } : {})
|
||||
})),
|
||||
chat_id: chatId,
|
||||
session_id: $socket?.id,
|
||||
@@ -716,7 +717,8 @@
|
||||
role: m.role,
|
||||
content: m.content,
|
||||
info: m.info ? m.info : undefined,
|
||||
timestamp: m.timestamp
|
||||
timestamp: m.timestamp,
|
||||
...(m.sources ? { sources: m.sources } : {})
|
||||
})),
|
||||
...(event ? { event: event } : {}),
|
||||
chat_id: chatId,
|
||||
@@ -886,11 +888,10 @@
|
||||
await tick();
|
||||
|
||||
// Reset chat input textarea
|
||||
const chatInputContainer = document.getElementById('chat-input-container');
|
||||
const chatInputElement = document.getElementById('chat-input');
|
||||
|
||||
if (chatInputContainer) {
|
||||
chatInputContainer.value = '';
|
||||
chatInputContainer.style.height = '';
|
||||
if (chatInputElement) {
|
||||
chatInputElement.style.height = '';
|
||||
}
|
||||
|
||||
const _files = JSON.parse(JSON.stringify(files));
|
||||
@@ -1276,8 +1277,8 @@
|
||||
console.log(line);
|
||||
let data = JSON.parse(line);
|
||||
|
||||
if ('citations' in data) {
|
||||
responseMessage.citations = data.citations;
|
||||
if ('sources' in data) {
|
||||
responseMessage.sources = data.sources;
|
||||
// Only remove status if it was initially set
|
||||
if (model?.info?.meta?.knowledge ?? false) {
|
||||
responseMessage.statusHistory = responseMessage.statusHistory.filter(
|
||||
@@ -1630,7 +1631,7 @@
|
||||
const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
|
||||
|
||||
for await (const update of textStream) {
|
||||
const { value, done, citations, selectedModelId, error, usage } = update;
|
||||
const { value, done, sources, selectedModelId, error, usage } = update;
|
||||
if (error) {
|
||||
await handleOpenAIError(error, null, model, responseMessage);
|
||||
break;
|
||||
@@ -1656,8 +1657,8 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
if (citations) {
|
||||
responseMessage.citations = citations;
|
||||
if (sources) {
|
||||
responseMessage.sources = sources;
|
||||
// Only remove status if it was initially set
|
||||
if (model?.info?.meta?.knowledge ?? false) {
|
||||
responseMessage.statusHistory = responseMessage.statusHistory.filter(
|
||||
@@ -1936,7 +1937,7 @@
|
||||
if (res && res.ok && res.body) {
|
||||
const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
|
||||
for await (const update of textStream) {
|
||||
const { value, done, citations, error, usage } = update;
|
||||
const { value, done, sources, error, usage } = update;
|
||||
if (error || done) {
|
||||
break;
|
||||
}
|
||||
@@ -1975,7 +1976,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
return title;
|
||||
return title ? title : (lastUserMessage?.content ?? 'New Chat');
|
||||
} else {
|
||||
return lastUserMessage?.content ?? 'New Chat';
|
||||
}
|
||||
@@ -2308,7 +2309,11 @@
|
||||
on:submit={async (e) => {
|
||||
if (e.detail) {
|
||||
await tick();
|
||||
submitPrompt(e.detail.replaceAll('\n\n', '\n'));
|
||||
submitPrompt(
|
||||
($settings?.richTextInput ?? true)
|
||||
? e.detail.replaceAll('\n\n', '\n')
|
||||
: e.detail
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -2345,7 +2350,11 @@
|
||||
on:submit={async (e) => {
|
||||
if (e.detail) {
|
||||
await tick();
|
||||
submitPrompt(e.detail.replaceAll('\n\n', '\n'));
|
||||
submitPrompt(
|
||||
($settings?.richTextInput ?? true)
|
||||
? e.detail.replaceAll('\n\n', '\n')
|
||||
: e.detail
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -75,14 +75,6 @@
|
||||
(model) => $models.find((m) => m.id === model)?.info?.meta?.capabilities?.vision ?? true
|
||||
);
|
||||
|
||||
$: if (prompt) {
|
||||
if (chatInputContainerElement) {
|
||||
chatInputContainerElement.style.height = '';
|
||||
chatInputContainerElement.style.height =
|
||||
Math.min(chatInputContainerElement.scrollHeight, 200) + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
const scrollToBottom = () => {
|
||||
const element = document.getElementById('messages-container');
|
||||
element.scrollTo({
|
||||
@@ -321,12 +313,22 @@
|
||||
<span class="relative inline-flex rounded-full size-2 bg-yellow-500" />
|
||||
</span>
|
||||
</div>
|
||||
<div class=" translate-y-[0.5px] line-clamp-1">
|
||||
{selectedToolIds
|
||||
.map((id) => {
|
||||
return $tools ? $tools.find((tool) => tool.id === id)?.name : id;
|
||||
})
|
||||
.join(', ')}
|
||||
<div class=" translate-y-[0.5px] text-ellipsis line-clamp-1 flex">
|
||||
{#each selectedToolIds.map((id) => {
|
||||
return $tools ? $tools.find((t) => t.id === id) : { id: id, name: id };
|
||||
}) as tool, toolIdx (toolIdx)}
|
||||
<Tooltip
|
||||
content={tool?.meta?.description ?? ''}
|
||||
className=" {toolIdx !== 0 ? 'pl-0.5' : ''} flex-shrink-0"
|
||||
placement="top"
|
||||
>
|
||||
{tool.name}
|
||||
</Tooltip>
|
||||
|
||||
{#if toolIdx !== selectedToolIds.length - 1}
|
||||
<span>, </span>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -575,54 +577,24 @@
|
||||
|
||||
{#if $settings?.richTextInput ?? true}
|
||||
<div
|
||||
bind:this={chatInputContainerElement}
|
||||
id="chat-input-container"
|
||||
class="scrollbar-hidden text-left bg-gray-50 dark:bg-gray-850 dark:text-gray-100 outline-none w-full py-2.5 px-1 rounded-xl resize-none h-[48px] overflow-auto"
|
||||
class="scrollbar-hidden text-left bg-gray-50 dark:bg-gray-850 dark:text-gray-100 outline-none w-full py-2.5 px-1 rounded-xl resize-none h-fit max-h-60 overflow-auto"
|
||||
>
|
||||
<RichTextInput
|
||||
bind:this={chatInputElement}
|
||||
id="chat-input"
|
||||
trim={true}
|
||||
placeholder={placeholder ? placeholder : $i18n.t('Send a Message')}
|
||||
largeTextAsFile={$settings?.largeTextAsFile ?? false}
|
||||
bind:value={prompt}
|
||||
messageInput={true}
|
||||
shiftEnter={!$mobile ||
|
||||
!(
|
||||
'ontouchstart' in window ||
|
||||
navigator.maxTouchPoints > 0 ||
|
||||
navigator.msMaxTouchPoints > 0
|
||||
)}
|
||||
on:enter={async (e) => {
|
||||
if (prompt !== '') {
|
||||
dispatch('submit', prompt);
|
||||
}
|
||||
}}
|
||||
on:input={async (e) => {
|
||||
if (chatInputContainerElement) {
|
||||
chatInputContainerElement.style.height = '';
|
||||
chatInputContainerElement.style.height =
|
||||
Math.min(chatInputContainerElement.scrollHeight, 200) + 'px';
|
||||
}
|
||||
}}
|
||||
on:focus={async (e) => {
|
||||
if (chatInputContainerElement) {
|
||||
chatInputContainerElement.style.height = '';
|
||||
chatInputContainerElement.style.height =
|
||||
Math.min(chatInputContainerElement.scrollHeight, 200) + 'px';
|
||||
}
|
||||
}}
|
||||
on:keypress={(e) => {
|
||||
e = e.detail.event;
|
||||
}}
|
||||
placeholder={placeholder ? placeholder : $i18n.t('Send a Message')}
|
||||
largeTextAsFile={$settings?.largeTextAsFile ?? false}
|
||||
bind:value={prompt}
|
||||
on:keydown={async (e) => {
|
||||
e = e.detail.event;
|
||||
|
||||
if (chatInputContainerElement) {
|
||||
chatInputContainerElement.style.height = '';
|
||||
chatInputContainerElement.style.height =
|
||||
Math.min(chatInputContainerElement.scrollHeight, 200) + 'px';
|
||||
}
|
||||
|
||||
const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac
|
||||
const commandsContainerElement =
|
||||
document.getElementById('commands-container');
|
||||
@@ -662,50 +634,70 @@
|
||||
editButton?.click();
|
||||
}
|
||||
|
||||
if (commandsContainerElement && e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
commandsElement.selectUp();
|
||||
if (commandsContainerElement) {
|
||||
if (commandsContainerElement && e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
commandsElement.selectUp();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
||||
if (commandsContainerElement && e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
commandsElement.selectDown();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
||||
if (commandsContainerElement && e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
|
||||
if (e.shiftKey) {
|
||||
prompt = `${prompt}\n`;
|
||||
} else if (commandOptionButton) {
|
||||
commandOptionButton?.click();
|
||||
} else {
|
||||
document.getElementById('send-message-button')?.click();
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
|
||||
if (commandsContainerElement && e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
if (commandsContainerElement && e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
commandsElement.selectDown();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
commandOptionButton.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
||||
commandOptionButton?.click();
|
||||
if (commandsContainerElement && e.key === 'Tab') {
|
||||
e.preventDefault();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
|
||||
commandOptionButton?.click();
|
||||
}
|
||||
|
||||
if (commandsContainerElement && e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
|
||||
const commandOptionButton = [
|
||||
...document.getElementsByClassName('selected-command-option-button')
|
||||
]?.at(-1);
|
||||
|
||||
if (commandOptionButton) {
|
||||
commandOptionButton?.click();
|
||||
} else {
|
||||
document.getElementById('send-message-button')?.click();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
!$mobile ||
|
||||
!(
|
||||
'ontouchstart' in window ||
|
||||
navigator.maxTouchPoints > 0 ||
|
||||
navigator.msMaxTouchPoints > 0
|
||||
)
|
||||
) {
|
||||
// Prevent Enter key from creating a new line
|
||||
// Uses keyCode '13' for Enter key for chinese/japanese keyboards
|
||||
if (e.keyCode === 13 && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Submit the prompt when Enter key is pressed
|
||||
if (prompt !== '' && e.keyCode === 13 && !e.shiftKey) {
|
||||
dispatch('submit', prompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.key === 'Escape') {
|
||||
@@ -902,7 +894,6 @@
|
||||
on:input={async (e) => {
|
||||
e.target.style.height = '';
|
||||
e.target.style.height = Math.min(e.target.scrollHeight, 200) + 'px';
|
||||
user = null;
|
||||
}}
|
||||
on:focus={async (e) => {
|
||||
e.target.style.height = '';
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let citations = [];
|
||||
export let sources = [];
|
||||
|
||||
let _citations = [];
|
||||
let citations = [];
|
||||
let showPercentage = false;
|
||||
let showRelevance = true;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
let selectedCitation: any = null;
|
||||
let isCollapsibleOpen = false;
|
||||
|
||||
function calculateShowRelevance(citations: any[]) {
|
||||
const distances = citations.flatMap((citation) => citation.distances ?? []);
|
||||
function calculateShowRelevance(sources: any[]) {
|
||||
const distances = sources.flatMap((citation) => citation.distances ?? []);
|
||||
const inRange = distances.filter((d) => d !== undefined && d >= -1 && d <= 1).length;
|
||||
const outOfRange = distances.filter((d) => d !== undefined && (d < -1 || d > 1)).length;
|
||||
|
||||
@@ -36,25 +36,31 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
function shouldShowPercentage(citations: any[]) {
|
||||
const distances = citations.flatMap((citation) => citation.distances ?? []);
|
||||
function shouldShowPercentage(sources: any[]) {
|
||||
const distances = sources.flatMap((citation) => citation.distances ?? []);
|
||||
return distances.every((d) => d !== undefined && d >= -1 && d <= 1);
|
||||
}
|
||||
|
||||
$: {
|
||||
_citations = citations.reduce((acc, citation) => {
|
||||
citation.document.forEach((document, index) => {
|
||||
const metadata = citation.metadata?.[index];
|
||||
const distance = citation.distances?.[index];
|
||||
citations = sources.reduce((acc, source) => {
|
||||
if (Object.keys(source).length === 0) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
source.document.forEach((document, index) => {
|
||||
const metadata = source.metadata?.[index];
|
||||
const distance = source.distances?.[index];
|
||||
|
||||
// Within the same citation there could be multiple documents
|
||||
const id = metadata?.source ?? 'N/A';
|
||||
let source = citation?.source;
|
||||
let _source = source?.source;
|
||||
|
||||
if (metadata?.name) {
|
||||
source = { ...source, name: metadata.name };
|
||||
_source = { ..._source, name: metadata.name };
|
||||
}
|
||||
|
||||
if (id.startsWith('http://') || id.startsWith('https://')) {
|
||||
source = { ...source, name: id, url: id };
|
||||
_source = { ..._source, name: id, url: id };
|
||||
}
|
||||
|
||||
const existingSource = acc.find((item) => item.id === id);
|
||||
@@ -66,7 +72,7 @@
|
||||
} else {
|
||||
acc.push({
|
||||
id: id,
|
||||
source: source,
|
||||
source: _source,
|
||||
document: [document],
|
||||
metadata: metadata ? [metadata] : [],
|
||||
distances: distance !== undefined ? [distance] : undefined
|
||||
@@ -76,8 +82,8 @@
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
showRelevance = calculateShowRelevance(_citations);
|
||||
showPercentage = shouldShowPercentage(_citations);
|
||||
showRelevance = calculateShowRelevance(citations);
|
||||
showPercentage = shouldShowPercentage(citations);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -88,24 +94,27 @@
|
||||
{showRelevance}
|
||||
/>
|
||||
|
||||
{#if _citations.length > 0}
|
||||
{#if citations.length > 0}
|
||||
<div class=" py-0.5 -mx-0.5 w-full flex gap-1 items-center flex-wrap">
|
||||
{#if _citations.length <= 3}
|
||||
{#if citations.length <= 3}
|
||||
<div class="flex text-xs font-medium">
|
||||
{#each _citations as citation, idx}
|
||||
{#each citations as citation, idx}
|
||||
<button
|
||||
class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96"
|
||||
id={`source-${citation.source.name}`}
|
||||
class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-white dark:bg-gray-900 rounded-xl max-w-96"
|
||||
on:click={() => {
|
||||
showCitationModal = true;
|
||||
selectedCitation = citation;
|
||||
}}
|
||||
>
|
||||
{#if _citations.every((c) => c.distances !== undefined)}
|
||||
{#if citations.every((c) => c.distances !== undefined)}
|
||||
<div class="bg-gray-50 dark:bg-gray-800 rounded-full size-4">
|
||||
{idx + 1}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex-1 mx-1 line-clamp-1 truncate">
|
||||
<div
|
||||
class="flex-1 mx-1 line-clamp-1 text-black/60 hover:text-black dark:text-white/60 dark:hover:text-white transition"
|
||||
>
|
||||
{citation.source.name}
|
||||
</div>
|
||||
</button>
|
||||
@@ -120,7 +129,7 @@
|
||||
<span class="whitespace-nowrap hidden sm:inline">{$i18n.t('References from')}</span>
|
||||
<div class="flex items-center">
|
||||
<div class="flex text-xs font-medium items-center">
|
||||
{#each _citations.slice(0, 2) as citation, idx}
|
||||
{#each citations.slice(0, 2) as citation, idx}
|
||||
<button
|
||||
class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96"
|
||||
on:click={() => {
|
||||
@@ -131,7 +140,7 @@
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{#if _citations.every((c) => c.distances !== undefined)}
|
||||
{#if citations.every((c) => c.distances !== undefined)}
|
||||
<div class="bg-gray-50 dark:bg-gray-800 rounded-full size-4">
|
||||
{idx + 1}
|
||||
</div>
|
||||
@@ -145,7 +154,7 @@
|
||||
</div>
|
||||
<div class="flex items-center gap-1 whitespace-nowrap">
|
||||
<span class="hidden sm:inline">{$i18n.t('and')}</span>
|
||||
{_citations.length - 2}
|
||||
{citations.length - 2}
|
||||
<span>{$i18n.t('more')}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -159,7 +168,7 @@
|
||||
</div>
|
||||
<div slot="content">
|
||||
<div class="flex text-xs font-medium">
|
||||
{#each _citations as citation, idx}
|
||||
{#each citations as citation, idx}
|
||||
<button
|
||||
class="no-toggle outline-none flex dark:text-gray-300 p-1 bg-gray-50 hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-850 transition rounded-xl max-w-96"
|
||||
on:click={() => {
|
||||
@@ -167,7 +176,7 @@
|
||||
selectedCitation = citation;
|
||||
}}
|
||||
>
|
||||
{#if _citations.every((c) => c.distances !== undefined)}
|
||||
{#if citations.every((c) => c.distances !== undefined)}
|
||||
<div class="bg-gray-50 dark:bg-gray-800 rounded-full size-4">
|
||||
{idx + 1}
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
};
|
||||
});
|
||||
if (mergedDocuments.every((doc) => doc.distance !== undefined)) {
|
||||
mergedDocuments.sort((a, b) => (a.distance ?? Infinity) - (b.distance ?? Infinity));
|
||||
mergedDocuments = mergedDocuments.sort(
|
||||
(a, b) => (b.distance ?? Infinity) - (a.distance ?? Infinity)
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
import LightBlub from '$lib/components/icons/LightBlub.svelte';
|
||||
import { chatId, mobile, showArtifacts, showControls, showOverview } from '$lib/stores';
|
||||
import ChatBubble from '$lib/components/icons/ChatBubble.svelte';
|
||||
import { stringify } from 'postcss';
|
||||
|
||||
export let id;
|
||||
export let content;
|
||||
export let model = null;
|
||||
export let sources = null;
|
||||
|
||||
export let save = false;
|
||||
export let floatingButtons = true;
|
||||
export let onSourceClick = () => {};
|
||||
|
||||
let contentContainerElement;
|
||||
let buttonsContainerElement;
|
||||
@@ -129,6 +132,32 @@
|
||||
{content}
|
||||
{model}
|
||||
{save}
|
||||
sourceIds={(sources ?? []).reduce((acc, s) => {
|
||||
let ids = [];
|
||||
s.document.forEach((document, index) => {
|
||||
const metadata = s.metadata?.[index];
|
||||
const id = metadata?.source ?? 'N/A';
|
||||
|
||||
if (metadata?.name) {
|
||||
ids.push(metadata.name);
|
||||
return ids;
|
||||
}
|
||||
|
||||
if (id.startsWith('http://') || id.startsWith('https://')) {
|
||||
ids.push(id);
|
||||
} else {
|
||||
ids.push(s?.source?.name ?? id);
|
||||
}
|
||||
|
||||
return ids;
|
||||
});
|
||||
|
||||
acc = [...acc, ...ids];
|
||||
|
||||
// remove duplicates
|
||||
return acc.filter((item, index) => acc.indexOf(item) === index);
|
||||
}, [])}
|
||||
{onSourceClick}
|
||||
on:update={(e) => {
|
||||
dispatch('update', e.detail);
|
||||
}}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
export let model = null;
|
||||
export let save = false;
|
||||
|
||||
export let sourceIds = [];
|
||||
export let onSourceClick = () => {};
|
||||
|
||||
let tokens = [];
|
||||
|
||||
const options = {
|
||||
@@ -28,7 +31,7 @@
|
||||
$: (async () => {
|
||||
if (content) {
|
||||
tokens = marked.lexer(
|
||||
replaceTokens(processResponseContent(content), model?.name, $user?.name)
|
||||
replaceTokens(processResponseContent(content), sourceIds, model?.name, $user?.name)
|
||||
);
|
||||
}
|
||||
})();
|
||||
@@ -39,6 +42,7 @@
|
||||
{tokens}
|
||||
{id}
|
||||
{save}
|
||||
{onSourceClick}
|
||||
on:update={(e) => {
|
||||
dispatch('update', e.detail);
|
||||
}}
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
import Image from '$lib/components/common/Image.svelte';
|
||||
import KatexRenderer from './KatexRenderer.svelte';
|
||||
import Source from './Source.svelte';
|
||||
|
||||
export let id: string;
|
||||
export let tokens: Token[];
|
||||
export let onSourceClick: Function = () => {};
|
||||
</script>
|
||||
|
||||
{#each tokens as token}
|
||||
@@ -26,13 +28,15 @@
|
||||
{@html html}
|
||||
{:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
|
||||
{@html `${token.text}`}
|
||||
{:else if token.text.includes(`<source_id`)}
|
||||
<Source {token} onClick={onSourceClick} />
|
||||
{:else}
|
||||
{token.text}
|
||||
{/if}
|
||||
{:else if token.type === 'link'}
|
||||
{#if token.tokens}
|
||||
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>
|
||||
<svelte:self id={`${id}-a`} tokens={token.tokens} />
|
||||
<svelte:self id={`${id}-a`} tokens={token.tokens} {onSourceClick} />
|
||||
</a>
|
||||
{:else}
|
||||
<a href={token.href} target="_blank" rel="nofollow" title={token.title}>{token.text}</a>
|
||||
@@ -41,11 +45,11 @@
|
||||
<Image src={token.href} alt={token.text} />
|
||||
{:else if token.type === 'strong'}
|
||||
<strong>
|
||||
<svelte:self id={`${id}-strong`} tokens={token.tokens} />
|
||||
<svelte:self id={`${id}-strong`} tokens={token.tokens} {onSourceClick} />
|
||||
</strong>
|
||||
{:else if token.type === 'em'}
|
||||
<em>
|
||||
<svelte:self id={`${id}-em`} tokens={token.tokens} />
|
||||
<svelte:self id={`${id}-em`} tokens={token.tokens} {onSourceClick} />
|
||||
</em>
|
||||
{:else if token.type === 'codespan'}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
@@ -61,7 +65,7 @@
|
||||
<br />
|
||||
{:else if token.type === 'del'}
|
||||
<del>
|
||||
<svelte:self id={`${id}-del`} tokens={token.tokens} />
|
||||
<svelte:self id={`${id}-del`} tokens={token.tokens} {onSourceClick} />
|
||||
</del>
|
||||
{:else if token.type === 'inlineKatex'}
|
||||
{#if token.text}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
export let top = true;
|
||||
|
||||
export let save = false;
|
||||
export let onSourceClick: Function = () => {};
|
||||
|
||||
const headerComponent = (depth: number) => {
|
||||
return 'h' + depth;
|
||||
@@ -62,7 +63,7 @@
|
||||
<hr />
|
||||
{:else if token.type === 'heading'}
|
||||
<svelte:element this={headerComponent(token.depth)}>
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} />
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} {onSourceClick} />
|
||||
</svelte:element>
|
||||
{:else if token.type === 'code'}
|
||||
{#if token.raw.includes('```')}
|
||||
@@ -108,6 +109,7 @@
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-header-${headerIdx}`}
|
||||
tokens={header.tokens}
|
||||
{onSourceClick}
|
||||
/>
|
||||
</div>
|
||||
</th>
|
||||
@@ -126,6 +128,7 @@
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-row-${rowIdx}-${cellIdx}`}
|
||||
tokens={cell.tokens}
|
||||
{onSourceClick}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@@ -205,19 +208,27 @@
|
||||
></iframe>
|
||||
{:else if token.type === 'paragraph'}
|
||||
<p>
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-p`}
|
||||
tokens={token.tokens ?? []}
|
||||
{onSourceClick}
|
||||
/>
|
||||
</p>
|
||||
{:else if token.type === 'text'}
|
||||
{#if top}
|
||||
<p>
|
||||
{#if token.tokens}
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} />
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} {onSourceClick} />
|
||||
{:else}
|
||||
{unescapeHtml(token.text)}
|
||||
{/if}
|
||||
</p>
|
||||
{:else if token.tokens}
|
||||
<MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-p`}
|
||||
tokens={token.tokens ?? []}
|
||||
{onSourceClick}
|
||||
/>
|
||||
{:else}
|
||||
{unescapeHtml(token.text)}
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
export let token;
|
||||
export let onClick: Function = () => {};
|
||||
|
||||
let id = '';
|
||||
function extractDataAttribute(input) {
|
||||
// Use a regular expression to extract the value of the `data` attribute
|
||||
const match = input.match(/data="([^"]*)"/);
|
||||
// Check if a match was found and return the first captured group
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
$: id = extractDataAttribute(token.text);
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="text-xs font-medium w-fit translate-y-[2px] px-2 py-0.5 dark:bg-white/5 dark:text-white/60 dark:hover:text-white bg-gray-50 text-black/60 hover:text-black transition rounded-lg"
|
||||
on:click={() => {
|
||||
onClick(id);
|
||||
}}
|
||||
>
|
||||
<span class="line-clamp-1">
|
||||
{id}
|
||||
</span>
|
||||
</button>
|
||||
@@ -38,6 +38,7 @@
|
||||
let selectedReason = null;
|
||||
let comment = '';
|
||||
|
||||
let detailedRating = null;
|
||||
let selectedModel = null;
|
||||
|
||||
$: if (message?.annotation?.rating === 1) {
|
||||
@@ -56,6 +57,7 @@
|
||||
tags = (message?.annotation?.tags ?? []).map((tag) => ({
|
||||
name: tag
|
||||
}));
|
||||
detailedRating = message?.annotation?.details?.rating ?? null;
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
@@ -79,7 +81,10 @@
|
||||
dispatch('save', {
|
||||
reason: selectedReason,
|
||||
comment: comment,
|
||||
tags: tags.map((tag) => tag.name)
|
||||
tags: tags.map((tag) => tag.name),
|
||||
details: {
|
||||
rating: detailedRating
|
||||
}
|
||||
});
|
||||
|
||||
toast.success($i18n.t('Thanks for your feedback!'));
|
||||
@@ -100,7 +105,9 @@
|
||||
id="message-feedback-{message.id}"
|
||||
>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class=" text-sm">{$i18n.t('Tell us more:')}</div>
|
||||
<div class="text-sm font-medium">{$i18n.t('How would you rate this response?')}</div>
|
||||
|
||||
<!-- <div class=" text-sm">{$i18n.t('Tell us more:')}</div> -->
|
||||
|
||||
<button
|
||||
on:click={() => {
|
||||
@@ -120,53 +127,89 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if reasons.length > 0}
|
||||
<div class="flex flex-wrap gap-1.5 text-sm mt-2.5">
|
||||
{#each reasons as reason}
|
||||
<button
|
||||
class="px-3 py-0.5 border border-gray-50 dark:border-gray-850 hover:bg-gray-100 dark:hover:bg-gray-850 {selectedReason ===
|
||||
reason
|
||||
? 'bg-gray-200 dark:bg-gray-800'
|
||||
: ''} transition rounded-lg"
|
||||
on:click={() => {
|
||||
selectedReason = reason;
|
||||
}}
|
||||
>
|
||||
{#if reason === 'accurate_information'}
|
||||
{$i18n.t('Accurate information')}
|
||||
{:else if reason === 'followed_instructions_perfectly'}
|
||||
{$i18n.t('Followed instructions perfectly')}
|
||||
{:else if reason === 'showcased_creativity'}
|
||||
{$i18n.t('Showcased creativity')}
|
||||
{:else if reason === 'positive_attitude'}
|
||||
{$i18n.t('Positive attitude')}
|
||||
{:else if reason === 'attention_to_detail'}
|
||||
{$i18n.t('Attention to detail')}
|
||||
{:else if reason === 'thorough_explanation'}
|
||||
{$i18n.t('Thorough explanation')}
|
||||
{:else if reason === 'dont_like_the_style'}
|
||||
{$i18n.t("Don't like the style")}
|
||||
{:else if reason === 'too_verbose'}
|
||||
{$i18n.t('Too verbose')}
|
||||
{:else if reason === 'not_helpful'}
|
||||
{$i18n.t('Not helpful')}
|
||||
{:else if reason === 'not_factually_correct'}
|
||||
{$i18n.t('Not factually correct')}
|
||||
{:else if reason === 'didnt_fully_follow_instructions'}
|
||||
{$i18n.t("Didn't fully follow instructions")}
|
||||
{:else if reason === 'refused_when_it_shouldnt_have'}
|
||||
{$i18n.t("Refused when it shouldn't have")}
|
||||
{:else if reason === 'being_lazy'}
|
||||
{$i18n.t('Being lazy')}
|
||||
{:else if reason === 'other'}
|
||||
{$i18n.t('Other')}
|
||||
{:else}
|
||||
{reason}
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
<div class="w-full flex justify-center">
|
||||
<div class=" relative w-fit">
|
||||
<div class="mt-1.5 w-fit flex gap-1 pb-5">
|
||||
<!-- 1-10 scale -->
|
||||
{#each Array.from({ length: 10 }).map((_, i) => i + 1) as rating}
|
||||
<button
|
||||
class="size-7 text-sm border border-gray-50 dark:border-gray-850 hover:bg-gray-50 dark:hover:bg-gray-850 {detailedRating ===
|
||||
rating
|
||||
? 'bg-gray-100 dark:bg-gray-800'
|
||||
: ''} transition rounded-full disabled:cursor-not-allowed disabled:text-gray-500 disabled:bg-white disabled:dark:bg-gray-900"
|
||||
on:click={() => {
|
||||
detailedRating = rating;
|
||||
}}
|
||||
disabled={message?.annotation?.rating === -1 ? rating > 5 : rating < 6}
|
||||
>
|
||||
{rating}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-0 left-0 right-0 flex justify-between text-xs">
|
||||
<div>
|
||||
1 - {$i18n.t('Awful')}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
10 - {$i18n.t('Amazing')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{#if reasons.length > 0}
|
||||
<div class="text-sm mt-1.5 font-medium">{$i18n.t('Why?')}</div>
|
||||
|
||||
<div class="flex flex-wrap gap-1.5 text-sm mt-1.5">
|
||||
{#each reasons as reason}
|
||||
<button
|
||||
class="px-3 py-0.5 border border-gray-50 dark:border-gray-850 hover:bg-gray-50 dark:hover:bg-gray-850 {selectedReason ===
|
||||
reason
|
||||
? 'bg-gray-100 dark:bg-gray-800'
|
||||
: ''} transition rounded-xl"
|
||||
on:click={() => {
|
||||
selectedReason = reason;
|
||||
}}
|
||||
>
|
||||
{#if reason === 'accurate_information'}
|
||||
{$i18n.t('Accurate information')}
|
||||
{:else if reason === 'followed_instructions_perfectly'}
|
||||
{$i18n.t('Followed instructions perfectly')}
|
||||
{:else if reason === 'showcased_creativity'}
|
||||
{$i18n.t('Showcased creativity')}
|
||||
{:else if reason === 'positive_attitude'}
|
||||
{$i18n.t('Positive attitude')}
|
||||
{:else if reason === 'attention_to_detail'}
|
||||
{$i18n.t('Attention to detail')}
|
||||
{:else if reason === 'thorough_explanation'}
|
||||
{$i18n.t('Thorough explanation')}
|
||||
{:else if reason === 'dont_like_the_style'}
|
||||
{$i18n.t("Don't like the style")}
|
||||
{:else if reason === 'too_verbose'}
|
||||
{$i18n.t('Too verbose')}
|
||||
{:else if reason === 'not_helpful'}
|
||||
{$i18n.t('Not helpful')}
|
||||
{:else if reason === 'not_factually_correct'}
|
||||
{$i18n.t('Not factually correct')}
|
||||
{:else if reason === 'didnt_fully_follow_instructions'}
|
||||
{$i18n.t("Didn't fully follow instructions")}
|
||||
{:else if reason === 'refused_when_it_shouldnt_have'}
|
||||
{$i18n.t("Refused when it shouldn't have")}
|
||||
{:else if reason === 'being_lazy'}
|
||||
{$i18n.t('Being lazy')}
|
||||
{:else if reason === 'other'}
|
||||
{$i18n.t('Other')}
|
||||
{:else}
|
||||
{reason}
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<textarea
|
||||
@@ -195,7 +238,7 @@
|
||||
</div>
|
||||
|
||||
<button
|
||||
class=" bg-emerald-700 hover:bg-emerald-800 transition text-white text-sm font-medium rounded-xl px-3.5 py-1.5"
|
||||
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
|
||||
on:click={() => {
|
||||
saveHandler();
|
||||
}}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
};
|
||||
done: boolean;
|
||||
error?: boolean | { content: string };
|
||||
citations?: string[];
|
||||
sources?: string[];
|
||||
code_executions?: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
@@ -340,19 +340,16 @@
|
||||
|
||||
let feedbackLoading = false;
|
||||
|
||||
const feedbackHandler = async (
|
||||
rating: number | null = null,
|
||||
annotation: object | null = null
|
||||
) => {
|
||||
const feedbackHandler = async (rating: number | null = null, details: object | null = null) => {
|
||||
feedbackLoading = true;
|
||||
console.log('Feedback', rating, annotation);
|
||||
console.log('Feedback', rating, details);
|
||||
|
||||
const updatedMessage = {
|
||||
...message,
|
||||
annotation: {
|
||||
...(message?.annotation ?? {}),
|
||||
...(rating !== null ? { rating: rating } : {}),
|
||||
...(annotation ? annotation : {})
|
||||
...(details ? details : {})
|
||||
}
|
||||
};
|
||||
|
||||
@@ -429,7 +426,7 @@
|
||||
|
||||
await tick();
|
||||
|
||||
if (!annotation) {
|
||||
if (!details) {
|
||||
showRateComment = true;
|
||||
|
||||
if (!updatedMessage.annotation?.tags) {
|
||||
@@ -624,9 +621,18 @@
|
||||
<ContentRenderer
|
||||
id={message.id}
|
||||
content={message.content}
|
||||
sources={message.sources}
|
||||
floatingButtons={message?.done}
|
||||
save={!readOnly}
|
||||
{model}
|
||||
onSourceClick={(e) => {
|
||||
console.log(e);
|
||||
const sourceButton = document.getElementById(`source-${e}`);
|
||||
|
||||
if (sourceButton) {
|
||||
sourceButton.click();
|
||||
}
|
||||
}}
|
||||
on:update={(e) => {
|
||||
const { raw, oldContent, newContent } = e.detail;
|
||||
|
||||
@@ -656,8 +662,8 @@
|
||||
<Error content={message?.error?.content ?? message.content} />
|
||||
{/if}
|
||||
|
||||
{#if message.citations && (model?.info?.meta?.capabilities?.citations ?? true)}
|
||||
<Citations citations={message.citations} />
|
||||
{#if (message?.sources || message?.citations) && (model?.info?.meta?.capabilities?.citations ?? true)}
|
||||
<Citations sources={message?.sources ?? message?.citations} />
|
||||
{/if}
|
||||
|
||||
{#if message.code_executions}
|
||||
@@ -1194,9 +1200,7 @@
|
||||
bind:show={showRateComment}
|
||||
on:save={async (e) => {
|
||||
await feedbackHandler(null, {
|
||||
tags: e.detail.tags,
|
||||
comment: e.detail.comment,
|
||||
reason: e.detail.reason
|
||||
...e.detail
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
|
||||
import { models, settings } from '$lib/stores';
|
||||
import { user as _user } from '$lib/stores';
|
||||
import {
|
||||
copyToClipboard as _copyToClipboard,
|
||||
processResponseContent,
|
||||
replaceTokens
|
||||
} from '$lib/utils';
|
||||
import { copyToClipboard as _copyToClipboard } from '$lib/utils';
|
||||
|
||||
import Name from './Name.svelte';
|
||||
import ProfileImage from './ProfileImage.svelte';
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
import Selector from './ModelSelector/Selector.svelte';
|
||||
import Tooltip from '../common/Tooltip.svelte';
|
||||
|
||||
import { setDefaultModels } from '$lib/apis/configs';
|
||||
import { updateUserSettings } from '$lib/apis/users';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
export let selectedModels = [''];
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
mirostat_tau: null,
|
||||
top_k: null,
|
||||
top_p: null,
|
||||
min_p: null,
|
||||
stop: null,
|
||||
tfs_z: null,
|
||||
num_ctx: null,
|
||||
@@ -340,6 +341,7 @@
|
||||
mirostat_tau: params.mirostat_tau !== null ? params.mirostat_tau : undefined,
|
||||
top_k: params.top_k !== null ? params.top_k : undefined,
|
||||
top_p: params.top_p !== null ? params.top_p : undefined,
|
||||
min_p: params.min_p !== null ? params.min_p : undefined,
|
||||
tfs_z: params.tfs_z !== null ? params.tfs_z : undefined,
|
||||
num_ctx: params.num_ctx !== null ? params.num_ctx : undefined,
|
||||
num_batch: params.num_batch !== null ? params.num_batch : undefined,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
export let show = true;
|
||||
export let size = 'md';
|
||||
export let className = 'bg-gray-50 dark:bg-gray-900 rounded-2xl';
|
||||
export let className = 'bg-gray-50 dark:bg-gray-900 rounded-2xl';
|
||||
|
||||
let modalElement = null;
|
||||
let mounted = false;
|
||||
@@ -65,7 +65,7 @@
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
bind:this={modalElement}
|
||||
class="modal fixed top-0 right-0 left-0 bottom-0 bg-black/60 w-full h-screen max-h-[100dvh] flex justify-center z-[9999] overflow-hidden overscroll-contain"
|
||||
class="modal fixed top-0 right-0 left-0 bottom-0 bg-black/60 w-full h-screen max-h-[100dvh] p-3 flex justify-center z-[9999] overflow-y-auto overscroll-contain"
|
||||
in:fade={{ duration: 10 }}
|
||||
on:mousedown={() => {
|
||||
show = false;
|
||||
@@ -74,7 +74,7 @@
|
||||
<div
|
||||
class=" m-auto max-w-full {sizeToWidth(size)} {size !== 'full'
|
||||
? 'mx-2'
|
||||
: ''} shadow-3xl max-h-[100dvh] overflow-y-auto scrollbar-hidden {className}"
|
||||
: ''} shadow-3xl min-h-fit scrollbar-hidden {className}"
|
||||
in:flyAndScale
|
||||
on:mousedown={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -1,241 +1,49 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { marked } from 'marked';
|
||||
import TurndownService from 'turndown';
|
||||
const turndownService = new TurndownService({
|
||||
codeBlockStyle: 'fenced'
|
||||
});
|
||||
turndownService.escape = (string) => string;
|
||||
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
const eventDispatch = createEventDispatcher();
|
||||
|
||||
import { EditorState, Plugin, TextSelection } from 'prosemirror-state';
|
||||
import { EditorView, Decoration, DecorationSet } from 'prosemirror-view';
|
||||
import { undo, redo, history } from 'prosemirror-history';
|
||||
import {
|
||||
schema,
|
||||
defaultMarkdownParser,
|
||||
MarkdownParser,
|
||||
defaultMarkdownSerializer
|
||||
} from 'prosemirror-markdown';
|
||||
|
||||
import {
|
||||
inputRules,
|
||||
wrappingInputRule,
|
||||
textblockTypeInputRule,
|
||||
InputRule
|
||||
} from 'prosemirror-inputrules'; // Import input rules
|
||||
import { splitListItem, liftListItem, sinkListItem } from 'prosemirror-schema-list'; // Import from prosemirror-schema-list
|
||||
import { keymap } from 'prosemirror-keymap';
|
||||
import { baseKeymap, chainCommands } from 'prosemirror-commands';
|
||||
import { DOMParser, DOMSerializer, Schema, Fragment } from 'prosemirror-model';
|
||||
import { Editor } from '@tiptap/core';
|
||||
|
||||
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
||||
import Placeholder from '@tiptap/extension-placeholder';
|
||||
import Highlight from '@tiptap/extension-highlight';
|
||||
import Typography from '@tiptap/extension-typography';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
|
||||
import { all, createLowlight } from 'lowlight';
|
||||
|
||||
import { PASTED_TEXT_CHARACTER_LIMIT } from '$lib/constants';
|
||||
|
||||
// create a lowlight instance with all languages loaded
|
||||
const lowlight = createLowlight(all);
|
||||
|
||||
export let className = 'input-prose';
|
||||
export let placeholder = 'Type here...';
|
||||
export let value = '';
|
||||
export let id = '';
|
||||
|
||||
export let messageInput = false;
|
||||
export let shiftEnter = false;
|
||||
export let largeTextAsFile = false;
|
||||
|
||||
export let id = '';
|
||||
export let value = '';
|
||||
export let placeholder = 'Type here...';
|
||||
export let trim = false;
|
||||
let element;
|
||||
let editor;
|
||||
|
||||
let element: HTMLElement; // Element where ProseMirror will attach
|
||||
let state;
|
||||
let view;
|
||||
|
||||
// Plugin to add placeholder when the content is empty
|
||||
function placeholderPlugin(placeholder: string) {
|
||||
return new Plugin({
|
||||
props: {
|
||||
decorations(state) {
|
||||
const doc = state.doc;
|
||||
if (
|
||||
doc.childCount === 1 &&
|
||||
doc.firstChild.isTextblock &&
|
||||
doc.firstChild?.textContent === ''
|
||||
) {
|
||||
// If there's nothing in the editor, show the placeholder decoration
|
||||
const decoration = Decoration.node(0, doc.content.size, {
|
||||
'data-placeholder': placeholder,
|
||||
class: 'placeholder'
|
||||
});
|
||||
return DecorationSet.create(doc, [decoration]);
|
||||
}
|
||||
return DecorationSet.empty;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unescapeMarkdown(text: string): string {
|
||||
return text
|
||||
.replace(/\\([\\`*{}[\]()#+\-.!_>])/g, '$1') // unescape backslashed characters
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// Custom parsing rule that creates proper paragraphs for newlines and empty lines
|
||||
function markdownToProseMirrorDoc(markdown: string) {
|
||||
// Split the markdown into lines
|
||||
const lines = markdown.split('\n\n');
|
||||
|
||||
// Create an array to hold our paragraph nodes
|
||||
const paragraphs = [];
|
||||
|
||||
// Process each line
|
||||
lines.forEach((line) => {
|
||||
if (line.trim() === '') {
|
||||
// For empty lines, create an empty paragraph
|
||||
paragraphs.push(schema.nodes.paragraph.create());
|
||||
} else {
|
||||
// For non-empty lines, parse as usual
|
||||
const doc = defaultMarkdownParser.parse(line);
|
||||
// Extract the content of the parsed document
|
||||
doc.content.forEach((node) => {
|
||||
paragraphs.push(node);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Create a new document with these paragraphs
|
||||
return schema.node('doc', null, paragraphs);
|
||||
}
|
||||
|
||||
// Create a custom serializer for paragraphs
|
||||
// Custom paragraph serializer to preserve newlines for empty paragraphs (empty block).
|
||||
function serializeParagraph(state, node: Node) {
|
||||
const content = node.textContent.trim();
|
||||
|
||||
// If the paragraph is empty, just add an empty line.
|
||||
if (content === '') {
|
||||
state.write('\n\n');
|
||||
} else {
|
||||
state.renderInline(node);
|
||||
state.closeBlock(node);
|
||||
}
|
||||
}
|
||||
|
||||
const customMarkdownSerializer = new defaultMarkdownSerializer.constructor(
|
||||
{
|
||||
...defaultMarkdownSerializer.nodes,
|
||||
|
||||
paragraph: (state, node) => {
|
||||
serializeParagraph(state, node); // Use custom paragraph serialization
|
||||
}
|
||||
|
||||
// Customize other block formats if needed
|
||||
},
|
||||
|
||||
// Copy marks directly from the original serializer (or customize them if necessary)
|
||||
defaultMarkdownSerializer.marks
|
||||
);
|
||||
|
||||
// Utility function to convert ProseMirror content back to markdown text
|
||||
function serializeEditorContent(doc) {
|
||||
const markdown = customMarkdownSerializer.serialize(doc);
|
||||
if (trim) {
|
||||
return unescapeMarkdown(markdown).trim();
|
||||
} else {
|
||||
return unescapeMarkdown(markdown);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Input Rules ----
|
||||
// Input rule for heading (e.g., # Headings)
|
||||
function headingRule(schema) {
|
||||
return textblockTypeInputRule(/^(#{1,6})\s$/, schema.nodes.heading, (match) => ({
|
||||
level: match[1].length
|
||||
}));
|
||||
}
|
||||
|
||||
// Input rule for bullet list (e.g., `- item`)
|
||||
function bulletListRule(schema) {
|
||||
return wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list);
|
||||
}
|
||||
|
||||
// Input rule for ordered list (e.g., `1. item`)
|
||||
function orderedListRule(schema) {
|
||||
return wrappingInputRule(/^(\d+)\.\s$/, schema.nodes.ordered_list, (match) => ({
|
||||
order: +match[1]
|
||||
}));
|
||||
}
|
||||
|
||||
// Custom input rules for Bold/Italic (using * or _)
|
||||
function markInputRule(regexp: RegExp, markType: any) {
|
||||
return new InputRule(regexp, (state, match, start, end) => {
|
||||
const { tr } = state;
|
||||
if (match) {
|
||||
tr.replaceWith(start, end, schema.text(match[1], [markType.create()]));
|
||||
}
|
||||
return tr;
|
||||
});
|
||||
}
|
||||
|
||||
function boldRule(schema) {
|
||||
return markInputRule(/(?<=^|\s)\*([^*]+)\*(?=\s|$)/, schema.marks.strong);
|
||||
}
|
||||
|
||||
function italicRule(schema) {
|
||||
// Using lookbehind and lookahead to prevent the space from being consumed
|
||||
return markInputRule(/(?<=^|\s)_([^*_]+)_(?=\s|$)/, schema.marks.em);
|
||||
}
|
||||
|
||||
// Initialize Editor State and View
|
||||
function afterSpacePress(state, dispatch) {
|
||||
// Get the position right after the space was naturally inserted by the browser.
|
||||
let { from, to, empty } = state.selection;
|
||||
|
||||
if (dispatch && empty) {
|
||||
let tr = state.tr;
|
||||
|
||||
// Check for any active marks at `from - 1` (the space we just inserted)
|
||||
const storedMarks = state.storedMarks || state.selection.$from.marks();
|
||||
|
||||
const hasBold = storedMarks.some((mark) => mark.type === state.schema.marks.strong);
|
||||
const hasItalic = storedMarks.some((mark) => mark.type === state.schema.marks.em);
|
||||
|
||||
// Remove marks from the space character (marks applied to the space character will be marked as false)
|
||||
if (hasBold) {
|
||||
tr = tr.removeMark(from - 1, from, state.schema.marks.strong);
|
||||
}
|
||||
if (hasItalic) {
|
||||
tr = tr.removeMark(from - 1, from, state.schema.marks.em);
|
||||
}
|
||||
|
||||
// Dispatch the resulting transaction to update the editor state
|
||||
dispatch(tr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function toggleMark(markType) {
|
||||
return (state, dispatch) => {
|
||||
const { from, to } = state.selection;
|
||||
if (state.doc.rangeHasMark(from, to, markType)) {
|
||||
if (dispatch) dispatch(state.tr.removeMark(from, to, markType));
|
||||
return true;
|
||||
} else {
|
||||
if (dispatch) dispatch(state.tr.addMark(from, to, markType.create()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isInList(state) {
|
||||
const { $from } = state.selection;
|
||||
return (
|
||||
$from.parent.type === schema.nodes.paragraph && $from.node(-1).type === schema.nodes.list_item
|
||||
);
|
||||
}
|
||||
|
||||
function isEmptyListItem(state) {
|
||||
const { $from } = state.selection;
|
||||
return isInList(state) && $from.parent.content.size === 0 && $from.node(-1).childCount === 1;
|
||||
}
|
||||
|
||||
function exitList(state, dispatch) {
|
||||
return liftListItem(schema.nodes.list_item)(state, dispatch);
|
||||
}
|
||||
const options = {
|
||||
throwOnError: false
|
||||
};
|
||||
|
||||
// Function to find the next template in the document
|
||||
function findNextTemplate(doc, from = 0) {
|
||||
const patterns = [
|
||||
{ start: '[', end: ']' },
|
||||
@@ -270,6 +78,7 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
// Function to select the next template in the document
|
||||
function selectNextTemplate(state, dispatch) {
|
||||
const { doc, selection } = state;
|
||||
const from = selection.to;
|
||||
@@ -290,220 +99,196 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
// Replace tabs with four spaces
|
||||
function handleTabIndentation(text: string): string {
|
||||
// Replace each tab character with four spaces
|
||||
return text.replace(/\t/g, ' ');
|
||||
}
|
||||
export const setContent = (content) => {
|
||||
editor.commands.setContent(content);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
const initialDoc = markdownToProseMirrorDoc(value || ''); // Convert the initial content
|
||||
const selectTemplate = () => {
|
||||
if (value !== '') {
|
||||
// After updating the state, try to find and select the next template
|
||||
setTimeout(() => {
|
||||
const templateFound = selectNextTemplate(editor.view.state, editor.view.dispatch);
|
||||
if (!templateFound) {
|
||||
// If no template found, set cursor at the end
|
||||
const endPos = editor.view.state.doc.content.size;
|
||||
editor.view.dispatch(
|
||||
editor.view.state.tr.setSelection(TextSelection.create(editor.view.state.doc, endPos))
|
||||
);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
state = EditorState.create({
|
||||
doc: initialDoc,
|
||||
schema,
|
||||
plugins: [
|
||||
history(),
|
||||
placeholderPlugin(placeholder),
|
||||
inputRules({
|
||||
rules: [
|
||||
headingRule(schema), // Handle markdown-style headings (# H1, ## H2, etc.)
|
||||
bulletListRule(schema), // Handle `-` or `*` input to start bullet list
|
||||
orderedListRule(schema), // Handle `1.` input to start ordered list
|
||||
boldRule(schema), // Bold input rule
|
||||
italicRule(schema) // Italic input rule
|
||||
]
|
||||
onMount(async () => {
|
||||
async function tryParse(value, attempts = 3, interval = 100) {
|
||||
try {
|
||||
// Try parsing the value
|
||||
return marked.parse(value);
|
||||
} catch (error) {
|
||||
// If no attempts remain, fallback to plain text
|
||||
if (attempts <= 1) {
|
||||
return value;
|
||||
}
|
||||
// Wait for the interval, then retry
|
||||
await new Promise((resolve) => setTimeout(resolve, interval));
|
||||
return tryParse(value, attempts - 1, interval); // Recursive call
|
||||
}
|
||||
}
|
||||
|
||||
// Usage example
|
||||
let content = await tryParse(value);
|
||||
|
||||
editor = new Editor({
|
||||
element: element,
|
||||
extensions: [
|
||||
StarterKit,
|
||||
CodeBlockLowlight.configure({
|
||||
lowlight
|
||||
}),
|
||||
keymap({
|
||||
...baseKeymap,
|
||||
'Mod-z': undo,
|
||||
'Mod-y': redo,
|
||||
Enter: (state, dispatch, view) => {
|
||||
if (shiftEnter) {
|
||||
eventDispatch('enter');
|
||||
return true;
|
||||
}
|
||||
return chainCommands(
|
||||
(state, dispatch, view) => {
|
||||
if (isEmptyListItem(state)) {
|
||||
return exitList(state, dispatch);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
(state, dispatch, view) => {
|
||||
if (isInList(state)) {
|
||||
return splitListItem(schema.nodes.list_item)(state, dispatch);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
baseKeymap.Enter
|
||||
)(state, dispatch, view);
|
||||
},
|
||||
Highlight,
|
||||
Typography,
|
||||
Placeholder.configure({ placeholder })
|
||||
],
|
||||
content: content,
|
||||
autofocus: true,
|
||||
onTransaction: () => {
|
||||
// force re-render so `editor.isActive` works as expected
|
||||
editor = editor;
|
||||
|
||||
'Shift-Enter': (state, dispatch, view) => {
|
||||
if (shiftEnter) {
|
||||
return chainCommands(
|
||||
(state, dispatch, view) => {
|
||||
if (isEmptyListItem(state)) {
|
||||
return exitList(state, dispatch);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
(state, dispatch, view) => {
|
||||
if (isInList(state)) {
|
||||
return splitListItem(schema.nodes.list_item)(state, dispatch);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
baseKeymap.Enter
|
||||
)(state, dispatch, view);
|
||||
} else {
|
||||
return baseKeymap.Enter(state, dispatch, view);
|
||||
}
|
||||
const newValue = turndownService.turndown(editor.getHTML());
|
||||
if (value !== newValue) {
|
||||
value = newValue;
|
||||
|
||||
if (value === '') {
|
||||
editor.commands.clearContent();
|
||||
}
|
||||
}
|
||||
},
|
||||
editorProps: {
|
||||
attributes: { id },
|
||||
handleDOMEvents: {
|
||||
focus: (view, event) => {
|
||||
eventDispatch('focus', { event });
|
||||
return false;
|
||||
},
|
||||
|
||||
// Prevent default tab navigation and provide indent/outdent behavior inside lists:
|
||||
Tab: chainCommands((state, dispatch, view) => {
|
||||
const { $from } = state.selection;
|
||||
if (isInList(state)) {
|
||||
return sinkListItem(schema.nodes.list_item)(state, dispatch);
|
||||
} else {
|
||||
return selectNextTemplate(state, dispatch);
|
||||
}
|
||||
return true; // Prevent Tab from moving the focus
|
||||
}),
|
||||
'Shift-Tab': (state, dispatch, view) => {
|
||||
const { $from } = state.selection;
|
||||
if (isInList(state)) {
|
||||
return liftListItem(schema.nodes.list_item)(state, dispatch);
|
||||
}
|
||||
return true; // Prevent Shift-Tab from moving the focus
|
||||
keyup: (view, event) => {
|
||||
eventDispatch('keyup', { event });
|
||||
return false;
|
||||
},
|
||||
'Mod-b': toggleMark(schema.marks.strong),
|
||||
'Mod-i': toggleMark(schema.marks.em)
|
||||
})
|
||||
]
|
||||
});
|
||||
keydown: (view, event) => {
|
||||
// Handle Tab Key
|
||||
if (event.key === 'Tab') {
|
||||
const handled = selectNextTemplate(view.state, view.dispatch);
|
||||
if (handled) {
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
view = new EditorView(element, {
|
||||
state,
|
||||
dispatchTransaction(transaction) {
|
||||
// Update editor state
|
||||
let newState = view.state.apply(transaction);
|
||||
view.updateState(newState);
|
||||
if (messageInput) {
|
||||
if (event.key === 'Enter') {
|
||||
// Check if the current selection is inside a structured block (like codeBlock or list)
|
||||
const { state } = view;
|
||||
const { $head } = state.selection;
|
||||
|
||||
value = serializeEditorContent(newState.doc); // Convert ProseMirror content to markdown text
|
||||
eventDispatch('input', { value });
|
||||
},
|
||||
handleDOMEvents: {
|
||||
focus: (view, event) => {
|
||||
eventDispatch('focus', { event });
|
||||
return false;
|
||||
},
|
||||
keypress: (view, event) => {
|
||||
eventDispatch('keypress', { event });
|
||||
return false;
|
||||
},
|
||||
keydown: (view, event) => {
|
||||
eventDispatch('keydown', { event });
|
||||
return false;
|
||||
},
|
||||
paste: (view, event) => {
|
||||
if (event.clipboardData) {
|
||||
// Extract plain text from clipboard and paste it without formatting
|
||||
const plainText = event.clipboardData.getData('text/plain');
|
||||
if (plainText) {
|
||||
if (largeTextAsFile) {
|
||||
if (plainText.length > PASTED_TEXT_CHARACTER_LIMIT) {
|
||||
// Dispatch paste event to parent component
|
||||
eventDispatch('paste', { event });
|
||||
// Recursive function to check ancestors for specific node types
|
||||
function isInside(nodeTypes: string[]): boolean {
|
||||
let currentNode = $head;
|
||||
while (currentNode) {
|
||||
if (nodeTypes.includes(currentNode.parent.type.name)) {
|
||||
return true;
|
||||
}
|
||||
if (!currentNode.depth) break; // Stop if we reach the top
|
||||
currentNode = state.doc.resolve(currentNode.before()); // Move to the parent node
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const isInCodeBlock = isInside(['codeBlock']);
|
||||
const isInList = isInside(['listItem', 'bulletList', 'orderedList']);
|
||||
const isInHeading = isInside(['heading']);
|
||||
|
||||
if (isInCodeBlock || isInList || isInHeading) {
|
||||
// Let ProseMirror handle the normal Enter behavior
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle shift + Enter for a line break
|
||||
if (shiftEnter) {
|
||||
if (event.key === 'Enter' && event.shiftKey && !event.ctrlKey && !event.metaKey) {
|
||||
editor.commands.setHardBreak(); // Insert a hard break
|
||||
view.dispatch(view.state.tr.scrollIntoView()); // Move viewport to the cursor
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
eventDispatch('keydown', { event });
|
||||
return false;
|
||||
},
|
||||
paste: (view, event) => {
|
||||
if (event.clipboardData) {
|
||||
// Extract plain text from clipboard and paste it without formatting
|
||||
const plainText = event.clipboardData.getData('text/plain');
|
||||
if (plainText) {
|
||||
if (largeTextAsFile) {
|
||||
if (plainText.length > PASTED_TEXT_CHARACTER_LIMIT) {
|
||||
// Dispatch paste event to parent component
|
||||
eventDispatch('paste', { event });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const modifiedText = handleTabIndentation(plainText);
|
||||
console.log(modifiedText);
|
||||
|
||||
// Replace the current selection with the plain text content
|
||||
const tr = view.state.tr.replaceSelectionWith(
|
||||
view.state.schema.text(modifiedText),
|
||||
false
|
||||
// Check if the pasted content contains image files
|
||||
const hasImageFile = Array.from(event.clipboardData.files).some((file) =>
|
||||
file.type.startsWith('image/')
|
||||
);
|
||||
view.dispatch(tr.scrollIntoView());
|
||||
event.preventDefault(); // Prevent the default paste behavior
|
||||
return true;
|
||||
|
||||
// Check for image in dataTransfer items (for cases where files are not available)
|
||||
const hasImageItem = Array.from(event.clipboardData.items).some((item) =>
|
||||
item.type.startsWith('image/')
|
||||
);
|
||||
if (hasImageFile) {
|
||||
// If there's an image, dispatch the event to the parent
|
||||
eventDispatch('paste', { event });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasImageItem) {
|
||||
// If there's an image item, dispatch the event to the parent
|
||||
eventDispatch('paste', { event });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the pasted content contains image files
|
||||
const hasImageFile = Array.from(event.clipboardData.files).some((file) =>
|
||||
file.type.startsWith('image/')
|
||||
);
|
||||
|
||||
// Check for image in dataTransfer items (for cases where files are not available)
|
||||
const hasImageItem = Array.from(event.clipboardData.items).some((item) =>
|
||||
item.type.startsWith('image/')
|
||||
);
|
||||
if (hasImageFile) {
|
||||
// If there's an image, dispatch the event to the parent
|
||||
eventDispatch('paste', { event });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasImageItem) {
|
||||
// If there's an image item, dispatch the event to the parent
|
||||
eventDispatch('paste', { event });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
// For all other cases (text, formatted text, etc.), let ProseMirror handle it
|
||||
view.dispatch(view.state.tr.scrollIntoView()); // Move viewport to the cursor after pasting
|
||||
return false;
|
||||
}
|
||||
|
||||
// For all other cases (text, formatted text, etc.), let ProseMirror handle it
|
||||
return false;
|
||||
},
|
||||
// Handle space input after browser has completed it
|
||||
keyup: (view, event) => {
|
||||
if (event.key === ' ' && event.code === 'Space') {
|
||||
afterSpacePress(view.state, view.dispatch);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
attributes: { id }
|
||||
}
|
||||
});
|
||||
|
||||
selectTemplate();
|
||||
});
|
||||
|
||||
// Reinitialize the editor if the value is externally changed (i.e. when `value` is updated)
|
||||
$: if (view && value !== serializeEditorContent(view.state.doc)) {
|
||||
const newDoc = markdownToProseMirrorDoc(value || '');
|
||||
|
||||
const newState = EditorState.create({
|
||||
doc: newDoc,
|
||||
schema,
|
||||
plugins: view.state.plugins,
|
||||
selection: TextSelection.atEnd(newDoc) // This sets the cursor at the end
|
||||
});
|
||||
view.updateState(newState);
|
||||
|
||||
if (value !== '') {
|
||||
// After updating the state, try to find and select the next template
|
||||
setTimeout(() => {
|
||||
const templateFound = selectNextTemplate(view.state, view.dispatch);
|
||||
if (!templateFound) {
|
||||
// If no template found, set cursor at the end
|
||||
const endPos = view.state.doc.content.size;
|
||||
view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, endPos)));
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy ProseMirror instance on unmount
|
||||
onDestroy(() => {
|
||||
view?.destroy();
|
||||
if (editor) {
|
||||
editor.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
// Update the editor content if the external `value` changes
|
||||
$: if (editor && value !== turndownService.turndown(editor.getHTML())) {
|
||||
editor.commands.setContent(marked.parse(value)); // Update editor content
|
||||
selectTemplate();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div bind:this={element} class="relative w-full min-w-full h-full min-h-fit {className}"></div>
|
||||
<div bind:this={element} class="relative w-full min-w-full h-full min-h-fit {className}" />
|
||||
|
||||
@@ -3,42 +3,25 @@
|
||||
|
||||
export let value = '';
|
||||
export let placeholder = '';
|
||||
|
||||
export let rows = 1;
|
||||
export let required = false;
|
||||
|
||||
export let className =
|
||||
'w-full rounded-lg px-3 py-2 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none resize-none h-full';
|
||||
|
||||
let textareaElement;
|
||||
|
||||
// Adjust height on mount and after setting the element.
|
||||
onMount(async () => {
|
||||
await tick();
|
||||
if (textareaElement) {
|
||||
await tick();
|
||||
setTimeout(adjustHeight, 0);
|
||||
}
|
||||
});
|
||||
|
||||
$: if (value) {
|
||||
setTimeout(adjustHeight, 0);
|
||||
}
|
||||
|
||||
const adjustHeight = () => {
|
||||
if (textareaElement) {
|
||||
textareaElement.style.height = '';
|
||||
textareaElement.style.height = `${textareaElement.scrollHeight}px`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<textarea
|
||||
bind:this={textareaElement}
|
||||
bind:value
|
||||
{placeholder}
|
||||
on:input={adjustHeight}
|
||||
on:focus={adjustHeight}
|
||||
class={className}
|
||||
style="field-sizing: content;"
|
||||
{rows}
|
||||
{required}
|
||||
/>
|
||||
|
||||
@@ -115,6 +115,20 @@
|
||||
</div>
|
||||
</button>
|
||||
</Menu>
|
||||
{:else if $mobile}
|
||||
<Tooltip content={$i18n.t('Controls')}>
|
||||
<button
|
||||
class=" flex cursor-pointer px-2 py-2 rounded-xl hover:bg-gray-50 dark:hover:bg-gray-850 transition"
|
||||
on:click={async () => {
|
||||
await showControls.set(!$showControls);
|
||||
}}
|
||||
aria-label="Controls"
|
||||
>
|
||||
<div class=" m-auto self-center">
|
||||
<AdjustmentsHorizontal className=" size-5" strokeWidth="0.5" />
|
||||
</div>
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
{#if !$mobile}
|
||||
|
||||
@@ -165,12 +165,14 @@
|
||||
<div class="mt-3 flex justify-between">
|
||||
<div class="text-xs text-gray-500">
|
||||
<Tooltip
|
||||
content={item?.user?.email}
|
||||
content={item?.user?.email ?? $i18n.t('Deleted User')}
|
||||
className="flex shrink-0"
|
||||
placement="top-start"
|
||||
>
|
||||
{$i18n.t('By {{name}}', {
|
||||
name: capitalizeFirstLetter(item?.user?.name ?? item?.user?.email)
|
||||
name: capitalizeFirstLetter(
|
||||
item?.user?.name ?? item?.user?.email ?? $i18n.t('Deleted User')
|
||||
)
|
||||
})}
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
let inputFiles = null;
|
||||
|
||||
let filteredItems = [];
|
||||
$: if (knowledge) {
|
||||
$: if (knowledge && knowledge.files) {
|
||||
fuse = new Fuse(knowledge.files, {
|
||||
keys: ['meta.name', 'meta.description']
|
||||
});
|
||||
|
||||
@@ -279,10 +279,16 @@
|
||||
|
||||
<div class="flex justify-between items-center -mb-0.5 px-0.5">
|
||||
<div class=" text-xs mt-0.5">
|
||||
<Tooltip content={model?.user?.email} className="flex shrink-0" placement="top-start">
|
||||
<Tooltip
|
||||
content={model?.user?.email ?? $i18n.t('Deleted User')}
|
||||
className="flex shrink-0"
|
||||
placement="top-start"
|
||||
>
|
||||
<div class="shrink-0 text-gray-500">
|
||||
{$i18n.t('By {{name}}', {
|
||||
name: capitalizeFirstLetter(model?.user?.name ?? model?.user?.email)
|
||||
name: capitalizeFirstLetter(
|
||||
model?.user?.name ?? model?.user?.email ?? $i18n.t('Deleted User')
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@@ -210,9 +210,6 @@
|
||||
}
|
||||
});
|
||||
capabilities = { ...capabilities, ...(model?.meta?.capabilities ?? {}) };
|
||||
if (model?.owned_by === 'openai') {
|
||||
capabilities.usage = false;
|
||||
}
|
||||
|
||||
if ('access_control' in model) {
|
||||
accessControl = model.access_control;
|
||||
@@ -320,6 +317,7 @@
|
||||
info.meta.profile_image_url = compressedSrc;
|
||||
|
||||
inputFiles = null;
|
||||
filesInputElement.value = '';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -348,7 +346,7 @@
|
||||
<div class="self-center md:self-start flex justify-center my-2 flex-shrink-0">
|
||||
<div class="self-center">
|
||||
<button
|
||||
class="rounded-2xl flex flex-shrink-0 items-center {info.meta.profile_image_url !==
|
||||
class="rounded-xl flex flex-shrink-0 items-center {info.meta.profile_image_url !==
|
||||
'/static/favicon.png'
|
||||
? 'bg-transparent'
|
||||
: 'bg-white'} shadow-xl group relative"
|
||||
@@ -361,13 +359,13 @@
|
||||
<img
|
||||
src={info.meta.profile_image_url}
|
||||
alt="model profile"
|
||||
class="rounded-lg size-72 md:size-60 object-cover shrink-0"
|
||||
class="rounded-xl size-72 md:size-60 object-cover shrink-0"
|
||||
/>
|
||||
{:else}
|
||||
<img
|
||||
src="/static/favicon.png"
|
||||
alt="model profile"
|
||||
class=" rounded-lg size-72 md:size-60 object-cover shrink-0"
|
||||
class=" rounded-xl size-72 md:size-60 object-cover shrink-0"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -396,6 +394,18 @@
|
||||
class="absolute top-0 bottom-0 left-0 right-0 bg-white dark:bg-black rounded-lg opacity-0 group-hover:opacity-20 transition"
|
||||
></div>
|
||||
</button>
|
||||
|
||||
<div class="flex w-full mt-1 justify-end">
|
||||
<button
|
||||
class="px-2 py-1 text-gray-500 rounded-lg text-xs"
|
||||
on:click={() => {
|
||||
info.meta.profile_image_url = '/static/favicon.png';
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
Reset Image</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -155,13 +155,15 @@
|
||||
|
||||
<div class=" text-xs px-0.5">
|
||||
<Tooltip
|
||||
content={prompt?.user?.email}
|
||||
content={prompt?.user?.email ?? $i18n.t('Deleted User')}
|
||||
className="flex shrink-0"
|
||||
placement="top-start"
|
||||
>
|
||||
<div class="shrink-0 text-gray-500">
|
||||
{$i18n.t('By {{name}}', {
|
||||
name: capitalizeFirstLetter(prompt?.user?.name ?? prompt?.user?.email)
|
||||
name: capitalizeFirstLetter(
|
||||
prompt?.user?.name ?? prompt?.user?.email ?? $i18n.t('Deleted User')
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
@@ -251,12 +251,14 @@
|
||||
|
||||
<div class="text-xs text-gray-500 shrink-0">
|
||||
<Tooltip
|
||||
content={tool?.user?.email}
|
||||
content={tool?.user?.email ?? $i18n.t('Deleted User')}
|
||||
className="flex shrink-0"
|
||||
placement="top-start"
|
||||
>
|
||||
{$i18n.t('By {{name}}', {
|
||||
name: capitalizeFirstLetter(tool?.user?.name ?? tool?.user?.email)
|
||||
name: capitalizeFirstLetter(
|
||||
tool?.user?.name ?? tool?.user?.email ?? $i18n.t('Deleted User')
|
||||
)
|
||||
})}
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "هل تملك حساب ؟",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "مساعد",
|
||||
"and": "و",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 الرابط مطلوب",
|
||||
"Available list": "",
|
||||
"available!": "متاح",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "خلف",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "الطلبات المتزامنة",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "تأكيد كلمة المرور",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "(SentenceTransformers) الإفتراضي",
|
||||
"Default Model": "النموذج الافتراضي",
|
||||
"Default model updated": "الإفتراضي تحديث الموديل",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "الإفتراضي Prompt الاقتراحات",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "حذف المستخدم",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} حذف",
|
||||
"Deleted {{name}}": "حذف {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "وصف",
|
||||
"Didn't fully follow instructions": "لم أتبع التعليمات بشكل كامل",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "أدخل كود اللغة",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "(e.g. {{modelTag}}) أدخل الموديل تاق",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "(e.g. 50) أدخل عدد الخطوات",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "فشل في إنشاء مفتاح API.",
|
||||
"Failed to read clipboard contents": "فشل في قراءة محتويات الحافظة",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "فبراير",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "أخفاء",
|
||||
"Host": "",
|
||||
"How can I help you today?": "كيف استطيع مساعدتك اليوم؟",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "البحث الهجين",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "محتوى الملف النموذجي",
|
||||
"Models": "الموديلات",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "المزيد",
|
||||
"Name": "الأسم",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "لا توجد نتايج",
|
||||
"No search query generated": "لم يتم إنشاء استعلام بحث",
|
||||
"No source available": "لا يوجد مصدر متاح",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "إزالة",
|
||||
"Remove Model": "حذف الموديل",
|
||||
"Rename": "إعادة تسمية",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "N كرر آخر",
|
||||
"Request Mode": "وضع الطلب",
|
||||
"Reranking Model": "إعادة تقييم النموذج",
|
||||
"Reranking model disabled": "تم تعطيل نموذج إعادة الترتيب",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "تم ضبط نموذج إعادة الترتيب على \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -981,6 +994,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Вече имате акаунт? ",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "асистент",
|
||||
"and": "и",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Базов URL е задължителен.",
|
||||
"Available list": "",
|
||||
"available!": "наличен!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Назад",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Едновременни искания",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Потвърди Парола",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "По подразбиране (SentenceTransformers)",
|
||||
"Default Model": "Модел по подразбиране",
|
||||
"Default model updated": "Моделът по подразбиране е обновен",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Промпт Предложения по подразбиране",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Изтриване на потребител",
|
||||
"Deleted {{deleteModelTag}}": "Изтрито {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Изтрито {{име}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Описание",
|
||||
"Didn't fully follow instructions": "Не следва инструкциите",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Въведете кодове на езика",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Въведете таг на модел (напр. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Въведете брой стъпки (напр. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Неуспешно създаване на API ключ.",
|
||||
"Failed to read clipboard contents": "Грешка при четене на съдържанието от клипборда",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "Февруари",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Скрий",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Как мога да ви помогна днес?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hybrid Search",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Съдържание на модфайл",
|
||||
"Models": "Модели",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Повече",
|
||||
"Name": "Име",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Няма намерени резултати",
|
||||
"No search query generated": "Не е генерирана заявка за търсене",
|
||||
"No source available": "Няма наличен източник",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Изтриване",
|
||||
"Remove Model": "Изтриване на модела",
|
||||
"Rename": "Преименуване",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Repeat Last N",
|
||||
"Request Mode": "Request Mode",
|
||||
"Reranking Model": "Reranking Model",
|
||||
"Reranking model disabled": "Reranking model disabled",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Reranking model set to \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "আগে থেকেই একাউন্ট আছে?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "একটা এসিস্ট্যান্ট",
|
||||
"and": "এবং",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 বেজ ইউআরএল আবশ্যক",
|
||||
"Available list": "",
|
||||
"available!": "উপলব্ধ!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "পেছনে",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "সমকালীন অনুরোধ",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "পাসওয়ার্ড নিশ্চিত করুন",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "ডিফল্ট (SentenceTransformers)",
|
||||
"Default Model": "ডিফল্ট মডেল",
|
||||
"Default model updated": "ডিফল্ট মডেল আপডেট হয়েছে",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "ডিফল্ট প্রম্পট সাজেশন",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "ইউজার মুছে ফেলুন",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} মুছে ফেলা হয়েছে",
|
||||
"Deleted {{name}}": "{{name}} মোছা হয়েছে",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "বিবরণ",
|
||||
"Didn't fully follow instructions": "ইনস্ট্রাকশন সম্পূর্ণ অনুসরণ করা হয়নি",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "ল্যাঙ্গুয়েজ কোড লিখুন",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "মডেল ট্যাগ লিখুন (e.g. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "ধাপের সংখ্যা দিন (যেমন: 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "API Key তৈরি করা যায়নি।",
|
||||
"Failed to read clipboard contents": "ক্লিপবোর্ডের বিষয়বস্তু পড়া সম্ভব হয়নি",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "ফেব্রুয়ারি",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "লুকান",
|
||||
"Host": "",
|
||||
"How can I help you today?": "আপনাকে আজ কিভাবে সাহায্য করতে পারি?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "হাইব্রিড অনুসন্ধান",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "মডেলফাইল কনটেন্ট",
|
||||
"Models": "মডেলসমূহ",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "আরো",
|
||||
"Name": "নাম",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "কোন ফলাফল পাওয়া যায়নি",
|
||||
"No search query generated": "কোনও অনুসন্ধান ক্যোয়ারী উত্পন্ন হয়নি",
|
||||
"No source available": "কোন উৎস পাওয়া যায়নি",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "রিমুভ করুন",
|
||||
"Remove Model": "মডেল রিমুভ করুন",
|
||||
"Rename": "রেনেম",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "রিপিট Last N",
|
||||
"Request Mode": "রিকোয়েস্ট মোড",
|
||||
"Reranking Model": "রির্যাক্টিং মডেল",
|
||||
"Reranking model disabled": "রির্যাক্টিং মডেল নিষ্ক্রিয় করা",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "রির ্যাঙ্কিং মডেল \"{{reranking_model}}\" -এ সেট করা আছে",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
"A task model is used when performing tasks such as generating titles for chats and web search queries": "Un model de tasca s'utilitza quan es realitzen tasques com ara generar títols per a xats i consultes de cerca per a la web",
|
||||
"a user": "un usuari",
|
||||
"About": "Sobre",
|
||||
"Access": "",
|
||||
"Access Control": "",
|
||||
"Accessible to all users": "",
|
||||
"Access": "Accés",
|
||||
"Access Control": "Control d'accés",
|
||||
"Accessible to all users": "Accessible a tots els usuaris",
|
||||
"Account": "Compte",
|
||||
"Account Activation Pending": "Activació del compte pendent",
|
||||
"Accurate information": "Informació precisa",
|
||||
@@ -30,14 +30,14 @@
|
||||
"Add content here": "Afegir contingut aquí",
|
||||
"Add custom prompt": "Afegir una indicació personalitzada",
|
||||
"Add Files": "Afegir arxius",
|
||||
"Add Group": "",
|
||||
"Add Group": "Afegir grup",
|
||||
"Add Memory": "Afegir memòria",
|
||||
"Add Model": "Afegir un model",
|
||||
"Add Tag": "Afegir etiqueta",
|
||||
"Add Tags": "Afegir etiquetes",
|
||||
"Add text content": "Afegir contingut de text",
|
||||
"Add User": "Afegir un usuari",
|
||||
"Add User Group": "",
|
||||
"Add User Group": "Afegir grup d'usuaris",
|
||||
"Adjusting these settings will apply changes universally to all users.": "Si ajustes aquesta preferència, els canvis s'aplicaran de manera universal a tots els usuaris.",
|
||||
"admin": "administrador",
|
||||
"Admin": "Administrador",
|
||||
@@ -48,17 +48,18 @@
|
||||
"Advanced Params": "Paràmetres avançats",
|
||||
"All chats": "Tots els xats",
|
||||
"All Documents": "Tots els documents",
|
||||
"All models deleted successfully": "",
|
||||
"Allow Chat Delete": "",
|
||||
"All models deleted successfully": "Tots els models s'han eliminat correctament",
|
||||
"Allow Chat Delete": "Permetre eliminar el xat",
|
||||
"Allow Chat Deletion": "Permetre la supressió del xat",
|
||||
"Allow Chat Edit": "",
|
||||
"Allow File Upload": "",
|
||||
"Allow Chat Edit": "Permetre editar el xat",
|
||||
"Allow File Upload": "Permetre la pujada d'arxius",
|
||||
"Allow non-local voices": "Permetre veus no locals",
|
||||
"Allow Temporary Chat": "Permetre el xat temporal",
|
||||
"Allow User Location": "Permetre la ubicació de l'usuari",
|
||||
"Allow Voice Interruption in Call": "Permetre la interrupció de la veu en una trucada",
|
||||
"Already have an account?": "Ja tens un compte?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternativa al top_p, i pretén garantir un equilibri de qualitat i varietat. El paràmetre p representa la probabilitat mínima que es consideri un token, en relació amb la probabilitat del token més probable. Per exemple, amb p=0,05 i el token més probable amb una probabilitat de 0,9, es filtren els logits amb un valor inferior a 0,045. (Per defecte: 0.0)",
|
||||
"Amazing": "Al·lucinant",
|
||||
"an assistant": "un assistent",
|
||||
"and": "i",
|
||||
"and {{COUNT}} more": "i {{COUNT}} més",
|
||||
@@ -69,7 +70,7 @@
|
||||
"API keys": "Claus de l'API",
|
||||
"Application DN": "DN d'aplicació",
|
||||
"Application DN Password": "Contrasenya del DN d'aplicació",
|
||||
"applies to all users with the \"user\" role": "",
|
||||
"applies to all users with the \"user\" role": "s'aplica a tots els usuaris amb el rol \"usuari\"",
|
||||
"April": "Abril",
|
||||
"Archive": "Arxiu",
|
||||
"Archive All Chats": "Arxiva tots els xats",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "Es requereix l'URL Base d'AUTOMATIC1111.",
|
||||
"Available list": "Llista de disponibles",
|
||||
"available!": "disponible!",
|
||||
"Awful": "Terrible",
|
||||
"Azure AI Speech": "Azure AI Speech",
|
||||
"Azure Region": "Regió d'Azure",
|
||||
"Back": "Enrere",
|
||||
@@ -107,7 +109,7 @@
|
||||
"Bing Search V7 Endpoint": "Punt de connexió a Bing Search V7",
|
||||
"Bing Search V7 Subscription Key": "Clau de subscripció a Bing Search V7",
|
||||
"Brave Search API Key": "Clau API de Brave Search",
|
||||
"By {{name}}": "",
|
||||
"By {{name}}": "Per {{name}}",
|
||||
"Bypass SSL verification for Websites": "Desactivar la verificació SSL per a l'accés a Internet",
|
||||
"Call": "Trucada",
|
||||
"Call feature is not supported when using Web STT engine": "La funció de trucada no s'admet quan s'utilitza el motor Web STT",
|
||||
@@ -124,7 +126,7 @@
|
||||
"Chat Controls": "Controls de xat",
|
||||
"Chat direction": "Direcció del xat",
|
||||
"Chat Overview": "Vista general del xat",
|
||||
"Chat Permissions": "",
|
||||
"Chat Permissions": "Permisos del xat",
|
||||
"Chat Tags Auto-Generation": "Generació automàtica d'etiquetes del xat",
|
||||
"Chats": "Xats",
|
||||
"Check Again": "Comprovar-ho de nou",
|
||||
@@ -155,7 +157,7 @@
|
||||
"Code execution": "Execució de codi",
|
||||
"Code formatted successfully": "Codi formatat correctament",
|
||||
"Collection": "Col·lecció",
|
||||
"Color": "",
|
||||
"Color": "Color",
|
||||
"ComfyUI": "ComfyUI",
|
||||
"ComfyUI Base URL": "URL base de ComfyUI",
|
||||
"ComfyUI Base URL is required.": "L'URL base de ComfyUI és obligatòria.",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "Completaments",
|
||||
"Concurrent Requests": "Peticions simultànies",
|
||||
"Configure": "Configurar",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Confirmar",
|
||||
"Confirm Password": "Confirmar la contrasenya",
|
||||
"Confirm your action": "Confirma la teva acció",
|
||||
@@ -189,12 +192,12 @@
|
||||
"Copy Link": "Copiar l'enllaç",
|
||||
"Copy to clipboard": "Copiar al porta-retalls",
|
||||
"Copying to clipboard was successful!": "La còpia al porta-retalls s'ha realitzat correctament",
|
||||
"Create": "",
|
||||
"Create": "Crear",
|
||||
"Create a knowledge base": "Crear una base de coneixement",
|
||||
"Create a model": "Crear un model",
|
||||
"Create Account": "Crear un compte",
|
||||
"Create Admin Account": "Crear un compte d'Administrador",
|
||||
"Create Group": "",
|
||||
"Create Group": "Crear grup",
|
||||
"Create Knowledge": "Crear Coneixement",
|
||||
"Create new key": "Crear una nova clau",
|
||||
"Create new secret key": "Crear una nova clau secreta",
|
||||
@@ -213,8 +216,9 @@
|
||||
"Default (SentenceTransformers)": "Per defecte (SentenceTransformers)",
|
||||
"Default Model": "Model per defecte",
|
||||
"Default model updated": "Model per defecte actualitzat",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Models": "",
|
||||
"Default permissions": "Permisos per defecte",
|
||||
"Default permissions updated successfully": "Permisos per defecte actualitzats correctament",
|
||||
"Default Prompt Suggestions": "Suggeriments d'indicació per defecte",
|
||||
"Default to 389 or 636 if TLS is enabled": "Per defecte 389 o 636 si TLS està habilitat",
|
||||
"Default to ALL": "Per defecte TOTS",
|
||||
@@ -222,7 +226,7 @@
|
||||
"Delete": "Eliminar",
|
||||
"Delete a model": "Eliminar un model",
|
||||
"Delete All Chats": "Eliminar tots els xats",
|
||||
"Delete All Models": "",
|
||||
"Delete All Models": "Eliminar tots els models",
|
||||
"Delete chat": "Eliminar xat",
|
||||
"Delete Chat": "Eliminar xat",
|
||||
"Delete chat?": "Eliminar el xat?",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Eliminar usuari",
|
||||
"Deleted {{deleteModelTag}}": "S'ha eliminat {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "S'ha eliminat {{name}}",
|
||||
"Deleted User": "Usuari eliminat",
|
||||
"Describe your knowledge base and objectives": "Descriu la teva base de coneixement i objectius",
|
||||
"Description": "Descripció",
|
||||
"Didn't fully follow instructions": "No s'han seguit les instruccions completament",
|
||||
@@ -248,10 +253,10 @@
|
||||
"Discover, download, and explore custom tools": "Descobrir, descarregar i explorar eines personalitzades",
|
||||
"Discover, download, and explore model presets": "Descobrir, descarregar i explorar models preconfigurats",
|
||||
"Dismissible": "Descartable",
|
||||
"Display": "",
|
||||
"Display": "Mostrar",
|
||||
"Display Emoji in Call": "Mostrar emojis a la trucada",
|
||||
"Display the username instead of You in the Chat": "Mostrar el nom d'usuari en lloc de 'Tu' al xat",
|
||||
"Displays citations in the response": "",
|
||||
"Displays citations in the response": "Mostra les referències a la resposta",
|
||||
"Dive into knowledge": "Aprofundir en el coneixement",
|
||||
"Do not install functions from sources you do not fully trust.": "No instal·lis funcions de fonts en què no confiïs plenament.",
|
||||
"Do not install tools from sources you do not fully trust.": "No instal·lis eines de fonts en què no confiïs plenament.",
|
||||
@@ -267,23 +272,23 @@
|
||||
"Download": "Descarregar",
|
||||
"Download canceled": "Descàrrega cancel·lada",
|
||||
"Download Database": "Descarregar la base de dades",
|
||||
"Drag and drop a file to upload or select a file to view": "",
|
||||
"Drag and drop a file to upload or select a file to view": "Arrossegar un arxiu per pujar o escull un arxiu a veure",
|
||||
"Draw": "Dibuixar",
|
||||
"Drop any files here to add to the conversation": "Deixa qualsevol arxiu aquí per afegir-lo a la conversa",
|
||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "p. ex. '30s','10m'. Les unitats de temps vàlides són 's', 'm', 'h'.",
|
||||
"e.g. A filter to remove profanity from text": "p. ex. Un filtre per eliminar paraules malsonants del text",
|
||||
"e.g. My Filter": "p. ex. El meu filtre",
|
||||
"e.g. My Tools": "",
|
||||
"e.g. My Tools": "p. ex. Les meves eines",
|
||||
"e.g. my_filter": "p. ex. els_meus_filtres",
|
||||
"e.g. my_tools": "",
|
||||
"e.g. Tools for performing various operations": "",
|
||||
"e.g. my_tools": "p. ex. les_meves_eines",
|
||||
"e.g. Tools for performing various operations": "p. ex. Eines per dur a terme operacions",
|
||||
"Edit": "Editar",
|
||||
"Edit Arena Model": "Editar model de l'Arena",
|
||||
"Edit Connection": "Editar la connexió",
|
||||
"Edit Default Permissions": "",
|
||||
"Edit Default Permissions": "Editar el permisos per defecte",
|
||||
"Edit Memory": "Editar la memòria",
|
||||
"Edit User": "Editar l'usuari",
|
||||
"Edit User Group": "",
|
||||
"Edit User Group": "Editar el grup d'usuaris",
|
||||
"ElevenLabs": "ElevenLabs",
|
||||
"Email": "Correu electrònic",
|
||||
"Embark on adventures": "Embarcar en aventures",
|
||||
@@ -291,14 +296,14 @@
|
||||
"Embedding Model": "Model d'incrustació",
|
||||
"Embedding Model Engine": "Motor de model d'incrustació",
|
||||
"Embedding model set to \"{{embedding_model}}\"": "Model d'incrustació configurat a \"{{embedding_model}}\"",
|
||||
"Enable API Key Auth": "",
|
||||
"Enable API Key Auth": "Activar l'autenticació amb clau API",
|
||||
"Enable Community Sharing": "Activar l'ús compartit amb la comunitat",
|
||||
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Activar el bloqueig de memòria (mlock) per evitar que les dades del model s'intercanviïn fora de la memòria RAM. Aquesta opció bloqueja el conjunt de pàgines de treball del model a la memòria RAM, assegurant-se que no s'intercanviaran al disc. Això pot ajudar a mantenir el rendiment evitant errors de pàgina i garantint un accés ràpid a les dades.",
|
||||
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Activar l'assignació de memòria (mmap) per carregar les dades del model. Aquesta opció permet que el sistema utilitzi l'emmagatzematge en disc com a extensió de la memòria RAM tractant els fitxers de disc com si estiguessin a la memòria RAM. Això pot millorar el rendiment del model permetent un accés més ràpid a les dades. Tanmateix, és possible que no funcioni correctament amb tots els sistemes i pot consumir una quantitat important d'espai en disc.",
|
||||
"Enable Message Rating": "Permetre la qualificació de missatges",
|
||||
"Enable Mirostat sampling for controlling perplexity. (Default: 0, 0 = Disabled, 1 = Mirostat, 2 = Mirostat 2.0)": "Activar el mostreig de Mirostat per controlar la perplexitat. (Per defecte: 0, 0 = Inhabilitat, 1 = Mirostat, 2 = Mirostat 2.0)",
|
||||
"Enable New Sign Ups": "Permetre nous registres",
|
||||
"Enable Retrieval Query Generation": "",
|
||||
"Enable Retrieval Query Generation": "Activar la Retrieval Query Generation",
|
||||
"Enable Tags Generation": "Activar la generació d'etiquetes",
|
||||
"Enable Web Search": "Activar la cerca web",
|
||||
"Enable Web Search Query Generation": "Activa la generació de consultes de cerca web",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Introdueix els codis de llenguatge",
|
||||
"Enter Model ID": "Introdueix l'identificador del model",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Introdueix l'etiqueta del model (p. ex. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "Introdueix la clau API de Mojeek Search",
|
||||
"Enter Number of Steps (e.g. 50)": "Introdueix el nombre de passos (p. ex. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Introdueix el mostrejador (p.ex. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Entra el programador (p.ex. Karras)",
|
||||
@@ -371,7 +377,7 @@
|
||||
"Export Config to JSON File": "Exportar la configuració a un arxiu JSON",
|
||||
"Export Functions": "Exportar funcions",
|
||||
"Export Models": "Exportar els models",
|
||||
"Export Presets": "",
|
||||
"Export Presets": "Exportar les configuracions",
|
||||
"Export Prompts": "Exportar les indicacions",
|
||||
"Export to CSV": "Exportar a CSV",
|
||||
"Export Tools": "Exportar les eines",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "No s'ha pogut afegir l'arxiu.",
|
||||
"Failed to create API Key.": "No s'ha pogut crear la clau API.",
|
||||
"Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "No s'han pogut actualitzar les preferències",
|
||||
"Failed to upload file.": "No s'ha pogut pujar l'arxiu.",
|
||||
"February": "Febrer",
|
||||
@@ -432,11 +439,11 @@
|
||||
"Good Response": "Bona resposta",
|
||||
"Google PSE API Key": "Clau API PSE de Google",
|
||||
"Google PSE Engine Id": "Identificador del motor PSE de Google",
|
||||
"Group created successfully": "",
|
||||
"Group deleted successfully": "",
|
||||
"Group Description": "",
|
||||
"Group Name": "",
|
||||
"Group updated successfully": "",
|
||||
"Group created successfully": "El grup s'ha creat correctament",
|
||||
"Group deleted successfully": "El grup s'ha eliminat correctament",
|
||||
"Group Description": "Descripció del grup",
|
||||
"Group Name": "Nom del grup",
|
||||
"Group updated successfully": "Grup actualitzat correctament",
|
||||
"Groups": "Grups",
|
||||
"h:mm a": "h:mm a",
|
||||
"Haptic Feedback": "Retorn hàptic",
|
||||
@@ -444,11 +451,12 @@
|
||||
"Hello, {{name}}": "Hola, {{name}}",
|
||||
"Help": "Ajuda",
|
||||
"Help us create the best community leaderboard by sharing your feedback history!": "Ajuda'ns a crear la millor taula de classificació de la comunitat compartint el teu historial de comentaris!",
|
||||
"Hex Color": "",
|
||||
"Hex Color - Leave empty for default color": "",
|
||||
"Hex Color": "Color hexadecimal",
|
||||
"Hex Color - Leave empty for default color": "Color hexadecimal - Deixar buit per a color per defecte",
|
||||
"Hide": "Amaga",
|
||||
"Host": "Servidor",
|
||||
"How can I help you today?": "Com et puc ajudar avui?",
|
||||
"How would you rate this response?": "Com avaluaries aquesta resposta?",
|
||||
"Hybrid Search": "Cerca híbrida",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Afirmo que he llegit i entenc les implicacions de la meva acció. Soc conscient dels riscos associats a l'execució de codi arbitrari i he verificat la fiabilitat de la font.",
|
||||
"ID": "ID",
|
||||
@@ -461,7 +469,7 @@
|
||||
"Import Config from JSON File": "Importar la configuració des d'un arxiu JSON",
|
||||
"Import Functions": "Importar funcions",
|
||||
"Import Models": "Importar models",
|
||||
"Import Presets": "",
|
||||
"Import Presets": "Importar configuracions",
|
||||
"Import Prompts": "Importar indicacions",
|
||||
"Import Tools": "Importar eines",
|
||||
"Include": "Incloure",
|
||||
@@ -488,7 +496,7 @@
|
||||
"Key": "Clau",
|
||||
"Keyboard shortcuts": "Dreceres de teclat",
|
||||
"Knowledge": "Coneixement",
|
||||
"Knowledge Access": "",
|
||||
"Knowledge Access": "Accés al coneixement",
|
||||
"Knowledge created successfully.": "Coneixement creat correctament.",
|
||||
"Knowledge deleted successfully.": "Coneixement eliminat correctament.",
|
||||
"Knowledge reset successfully.": "Coneixement restablert correctament.",
|
||||
@@ -518,7 +526,7 @@
|
||||
"Make sure to export a workflow.json file as API format from ComfyUI.": "Assegura't d'exportar un fitxer workflow.json com a format API des de ComfyUI.",
|
||||
"Manage": "Gestionar",
|
||||
"Manage Arena Models": "Gestionar els models de l'Arena",
|
||||
"Manage Ollama": "",
|
||||
"Manage Ollama": "Gestionar Ollama",
|
||||
"Manage Ollama API Connections": "Gestionar les connexions a l'API d'Ollama",
|
||||
"Manage OpenAI API Connections": "Gestionar les connexions a l'API d'OpenAI",
|
||||
"Manage Pipelines": "Gestionar les Pipelines",
|
||||
@@ -554,17 +562,19 @@
|
||||
"Model accepts image inputs": "El model accepta entrades d'imatge",
|
||||
"Model created successfully!": "Model creat correctament",
|
||||
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "S'ha detectat el camí del sistema de fitxers del model. És necessari un nom curt del model per actualitzar, no es pot continuar.",
|
||||
"Model Filtering": "",
|
||||
"Model Filtering": "Filtrat de models",
|
||||
"Model ID": "Identificador del model",
|
||||
"Model IDs": "Identificadors del model",
|
||||
"Model Name": "Nom del model",
|
||||
"Model not selected": "Model no seleccionat",
|
||||
"Model Params": "Paràmetres del model",
|
||||
"Model Permissions": "",
|
||||
"Model Permissions": "Permisos dels models",
|
||||
"Model updated successfully": "Model actualitzat correctament",
|
||||
"Modelfile Content": "Contingut del Modelfile",
|
||||
"Models": "Models",
|
||||
"Models Access": "",
|
||||
"Models Access": "Accés als models",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "Clau API de Mojeek Search",
|
||||
"more": "més",
|
||||
"More": "Més",
|
||||
"Name": "Nom",
|
||||
@@ -578,15 +588,16 @@
|
||||
"No feedbacks found": "No s'han trobat comentaris",
|
||||
"No file selected": "No s'ha escollit cap fitxer",
|
||||
"No files found.": "No s'han trobat arxius.",
|
||||
"No groups with access, add a group to grant access": "",
|
||||
"No groups with access, add a group to grant access": "No hi ha cap grup amb accés, afegeix un grup per concedir accés",
|
||||
"No HTML, CSS, or JavaScript content found.": "No s'ha trobat contingut HTML, CSS o JavaScript.",
|
||||
"No knowledge found": "No s'ha trobat Coneixement",
|
||||
"No model IDs": "",
|
||||
"No model IDs": "No hi ha IDs de model",
|
||||
"No models found": "No s'han trobat models",
|
||||
"No models selected": "",
|
||||
"No results found": "No s'han trobat resultats",
|
||||
"No search query generated": "No s'ha generat cap consulta",
|
||||
"No source available": "Sense font disponible",
|
||||
"No users were found.": "",
|
||||
"No users were found.": "No s'han trobat usuaris",
|
||||
"No valves to update": "No hi ha cap Valve per actualitzar",
|
||||
"None": "Cap",
|
||||
"Not factually correct": "No és clarament correcte",
|
||||
@@ -611,7 +622,7 @@
|
||||
"Only alphanumeric characters and hyphens are allowed": "Només es permeten caràcters alfanumèrics i guions",
|
||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Només es permeten caràcters alfanumèrics i guions en la comanda.",
|
||||
"Only collections can be edited, create a new knowledge base to edit/add documents.": "Només es poden editar col·leccions, crea una nova base de coneixement per editar/afegir documents.",
|
||||
"Only select users and groups with permission can access": "",
|
||||
"Only select users and groups with permission can access": "Només hi poden accedir usuaris i grups seleccionats amb permís",
|
||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ui! Sembla que l'URL no és vàlida. Si us plau, revisa-la i torna-ho a provar.",
|
||||
"Oops! There are files still uploading. Please wait for the upload to complete.": "Ui! Encara hi ha fitxers pujant-se. Si us plau, espera que finalitzi la càrrega.",
|
||||
"Oops! There was an error in the previous response.": "Ui! Hi ha hagut un error a la resposta anterior.",
|
||||
@@ -629,21 +640,21 @@
|
||||
"OpenAI API settings updated": "Configuració de l'API d'OpenAI actualitzada",
|
||||
"OpenAI URL/Key required.": "URL/Clau d'OpenAI requerides.",
|
||||
"or": "o",
|
||||
"Organize your users": "",
|
||||
"Organize your users": "Organitza els teus usuaris",
|
||||
"Other": "Altres",
|
||||
"OUTPUT": "SORTIDA",
|
||||
"Output format": "Format de sortida",
|
||||
"Overview": "Vista general",
|
||||
"page": "pàgina",
|
||||
"Password": "Contrasenya",
|
||||
"Paste Large Text as File": "",
|
||||
"Paste Large Text as File": "Enganxa un text llarg com a fitxer",
|
||||
"PDF document (.pdf)": "Document PDF (.pdf)",
|
||||
"PDF Extract Images (OCR)": "Extreu imatges del PDF (OCR)",
|
||||
"pending": "pendent",
|
||||
"Permission denied when accessing media devices": "Permís denegat en accedir a dispositius multimèdia",
|
||||
"Permission denied when accessing microphone": "Permís denegat en accedir al micròfon",
|
||||
"Permission denied when accessing microphone: {{error}}": "Permís denegat en accedir al micròfon: {{error}}",
|
||||
"Permissions": "",
|
||||
"Permissions": "Permisos",
|
||||
"Personalization": "Personalització",
|
||||
"Pin": "Fixar",
|
||||
"Pinned": "Fixat",
|
||||
@@ -668,14 +679,14 @@
|
||||
"Profile Image": "Imatge de perfil",
|
||||
"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Indicació (p.ex. Digues-me quelcom divertit sobre l'Imperi Romà)",
|
||||
"Prompt Content": "Contingut de la indicació",
|
||||
"Prompt created successfully": "",
|
||||
"Prompt created successfully": "Indicació creada correctament",
|
||||
"Prompt suggestions": "Suggeriments d'indicacions",
|
||||
"Prompt updated successfully": "",
|
||||
"Prompt updated successfully": "Indicació actualitzada correctament",
|
||||
"Prompts": "Indicacions",
|
||||
"Prompts Access": "",
|
||||
"Prompts Access": "Accés a les indicacions",
|
||||
"Pull \"{{searchValue}}\" from Ollama.com": "Obtenir \"{{searchValue}}\" de Ollama.com",
|
||||
"Pull a model from Ollama.com": "Obtenir un model d'Ollama.com",
|
||||
"Query Generation Prompt": "",
|
||||
"Query Generation Prompt": "Indicació per a generació de consulta",
|
||||
"Query Params": "Paràmetres de consulta",
|
||||
"RAG Template": "Plantilla RAG",
|
||||
"Rating": "Valoració",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Eliminar",
|
||||
"Remove Model": "Eliminar el model",
|
||||
"Rename": "Canviar el nom",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Repeteix els darrers N",
|
||||
"Request Mode": "Mode de sol·licitud",
|
||||
"Reranking Model": "Model de reavaluació",
|
||||
"Reranking model disabled": "Model de reavaluació desactivat",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Model de reavaluació establert a \"{{reranking_model}}\"",
|
||||
"Reset": "Restableix",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Restableix el directori de pujades",
|
||||
"Reset Vector Storage/Knowledge": "Restableix el Repositori de vectors/Coneixement",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de resposta no es poden activar perquè els permisos del lloc web han estat rebutjats. Comprova les preferències del navegador per donar l'accés necessari.",
|
||||
@@ -749,7 +762,7 @@
|
||||
"Select a base model": "Seleccionar un model base",
|
||||
"Select a engine": "Seleccionar un motor",
|
||||
"Select a function": "Seleccionar una funció",
|
||||
"Select a group": "",
|
||||
"Select a group": "Seleccionar un grup",
|
||||
"Select a model": "Seleccionar un model",
|
||||
"Select a pipeline": "Seleccionar una Pipeline",
|
||||
"Select a pipeline url": "Seleccionar l'URL d'una Pipeline",
|
||||
@@ -772,7 +785,7 @@
|
||||
"Set as default": "Establir com a predeterminat",
|
||||
"Set CFG Scale": "Establir l'escala CFG",
|
||||
"Set Default Model": "Establir el model predeterminat",
|
||||
"Set embedding model": "",
|
||||
"Set embedding model": "Establir el model d'incrustació",
|
||||
"Set embedding model (e.g. {{model}})": "Establir el model d'incrustació (p.ex. {{model}})",
|
||||
"Set Image Size": "Establir la mida de la image",
|
||||
"Set reranking model (e.g. {{model}})": "Establir el model de reavaluació (p.ex. {{model}})",
|
||||
@@ -860,8 +873,8 @@
|
||||
"This response was generated by \"{{model}}\"": "Aquesta resposta l'ha generat el model \"{{model}}\"",
|
||||
"This will delete": "Això eliminarà",
|
||||
"This will delete <strong>{{NAME}}</strong> and <strong>all its contents</strong>.": "Això eliminarà <strong>{{NAME}}</strong> i <strong>tots els continguts</strong>.",
|
||||
"This will delete all models including custom models": "",
|
||||
"This will delete all models including custom models and cannot be undone.": "",
|
||||
"This will delete all models including custom models": "Això eliminarà tots els models incloent els personalitzats",
|
||||
"This will delete all models including custom models and cannot be undone.": "Això eliminarà tots els models incloent els personalitzats i no es pot desfer",
|
||||
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Això restablirà la base de coneixement i sincronitzarà tots els fitxers. Vols continuar?",
|
||||
"Thorough explanation": "Explicació en detall",
|
||||
"Tika": "Tika",
|
||||
@@ -891,13 +904,13 @@
|
||||
"Too verbose": "Massa explicit",
|
||||
"Tool created successfully": "Eina creada correctament",
|
||||
"Tool deleted successfully": "Eina eliminada correctament",
|
||||
"Tool Description": "",
|
||||
"Tool ID": "",
|
||||
"Tool Description": "Descripció de l'eina",
|
||||
"Tool ID": "ID de l'eina",
|
||||
"Tool imported successfully": "Eina importada correctament",
|
||||
"Tool Name": "",
|
||||
"Tool Name": "Nom de l'eina",
|
||||
"Tool updated successfully": "Eina actualitzada correctament",
|
||||
"Tools": "Eines",
|
||||
"Tools Access": "",
|
||||
"Tools Access": "Accés a les eines",
|
||||
"Tools are a function calling system with arbitrary code execution": "Les eines són un sistema de crida a funcions amb execució de codi arbitrari",
|
||||
"Tools have a function calling system that allows arbitrary code execution": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari",
|
||||
"Tools have a function calling system that allows arbitrary code execution.": "Les eines disposen d'un sistema de crida a funcions que permet execució de codi arbitrari.",
|
||||
@@ -937,7 +950,7 @@
|
||||
"URL Mode": "Mode URL",
|
||||
"Use '#' in the prompt input to load and include your knowledge.": "Utilitza '#' a l'entrada de la indicació per carregar i incloure els teus coneixements.",
|
||||
"Use Gravatar": "Utilitzar Gravatar",
|
||||
"Use groups to group your users and assign permissions.": "",
|
||||
"Use groups to group your users and assign permissions.": "Utilitza grups per agrupar els usuaris i assignar permisos.",
|
||||
"Use Initials": "Utilitzar inicials",
|
||||
"use_mlock (Ollama)": "use_mlock (Ollama)",
|
||||
"use_mmap (Ollama)": "use_mmap (Ollama)",
|
||||
@@ -956,12 +969,12 @@
|
||||
"variable to have them replaced with clipboard content.": "variable per tenir-les reemplaçades amb el contingut del porta-retalls.",
|
||||
"Version": "Versió",
|
||||
"Version {{selectedVersion}} of {{totalVersions}}": "Versió {{selectedVersion}} de {{totalVersions}}",
|
||||
"Visibility": "",
|
||||
"Visibility": "Visibilitat",
|
||||
"Voice": "Veu",
|
||||
"Voice Input": "Entrada de veu",
|
||||
"Warning": "Avís",
|
||||
"Warning:": "Avís:",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "Avís: Habilitar això permetrà als usuaris penjar codi arbitrari al servidor.",
|
||||
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Avís: Si s'actualitza o es canvia el model d'incrustació, s'hauran de tornar a importar tots els documents.",
|
||||
"Web": "Web",
|
||||
"Web API": "Web API",
|
||||
@@ -978,11 +991,12 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Quan està activat, el model respondrà a cada missatge de xat en temps real, generant una resposta tan bon punt l'usuari envia un missatge. Aquest mode és útil per a aplicacions de xat en directe, però pot afectar el rendiment en maquinari més lent.",
|
||||
"wherever you are": "allà on estiguis",
|
||||
"Whisper (Local)": "Whisper (local)",
|
||||
"Why?": "Per què?",
|
||||
"Widescreen Mode": "Mode de pantalla ampla",
|
||||
"Won": "Ha guanyat",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "Funciona juntament amb top-k. Un valor més alt (p. ex., 0,95) donarà lloc a un text més divers, mentre que un valor més baix (p. ex., 0,5) generarà un text més concentrat i conservador. (Per defecte: 0,9)",
|
||||
"Workspace": "Espai de treball",
|
||||
"Workspace Permissions": "",
|
||||
"Workspace Permissions": "Permisos de l'espai de treball",
|
||||
"Write a prompt suggestion (e.g. Who are you?)": "Escriu una suggerència d'indicació (p. ex. Qui ets?)",
|
||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Escriu un resum en 50 paraules que resumeixi [tema o paraula clau].",
|
||||
"Write something...": "Escriu quelcom...",
|
||||
@@ -992,7 +1006,7 @@
|
||||
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Només pots xatejar amb un màxim de {{maxCount}} fitxers alhora.",
|
||||
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Pots personalitzar les teves interaccions amb els models de llenguatge afegint memòries mitjançant el botó 'Gestiona' que hi ha a continuació, fent-les més útils i adaptades a tu.",
|
||||
"You cannot upload an empty file.": "No es pot pujar un ariux buit.",
|
||||
"You do not have permission to upload files.": "",
|
||||
"You do not have permission to upload files.": "No tens permisos per pujar arxius.",
|
||||
"You have no archived conversations.": "No tens converses arxivades.",
|
||||
"You have shared this chat": "Has compartit aquest xat",
|
||||
"You're a helpful assistant.": "Ets un assistent útil.",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Naa na kay account ?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "usa ka katabang",
|
||||
"and": "Ug",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "Ang AUTOMATIC1111 base URL gikinahanglan.",
|
||||
"Available list": "",
|
||||
"available!": "magamit!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Balik",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Kumpirma ang password",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "",
|
||||
"Default Model": "",
|
||||
"Default model updated": "Gi-update nga default template",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Default nga prompt nga mga sugyot",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} gipapas",
|
||||
"Deleted {{name}}": "",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Deskripsyon",
|
||||
"Didn't fully follow instructions": "",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Pagsulod sa template tag (e.g. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Pagsulod sa gidaghanon sa mga lakang (e.g. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "",
|
||||
"Failed to read clipboard contents": "Napakyas sa pagbasa sa sulod sa clipboard",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Tagoa",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Unsaon nako pagtabang kanimo karon?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Mga sulod sa template file",
|
||||
"Models": "Mga modelo",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "",
|
||||
"Name": "Ngalan",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "",
|
||||
"No search query generated": "",
|
||||
"No source available": "Walay tinubdan nga anaa",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "",
|
||||
"Remove Model": "",
|
||||
"Rename": "",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Balika ang katapusang N",
|
||||
"Request Mode": "Query mode",
|
||||
"Reranking Model": "",
|
||||
"Reranking model disabled": "",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Povolit přerušení hlasu při hovoru",
|
||||
"Already have an account?": "Už máte účet?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "asistent",
|
||||
"and": "a",
|
||||
"and {{COUNT}} more": "a {{COUNT}} dalších",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "Vyžaduje se základní URL pro AUTOMATIC1111.",
|
||||
"Available list": "Dostupný seznam",
|
||||
"available!": "k dispozici!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "Azure AI syntéza řeči",
|
||||
"Azure Region": "Azure oblast",
|
||||
"Back": "Zpět",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "Doplnění",
|
||||
"Concurrent Requests": "Současné požadavky",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Potvrdit",
|
||||
"Confirm Password": "Potvrzení hesla",
|
||||
"Confirm your action": "Potvrďte svoji akci",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Výchozí (SentenceTransformers)",
|
||||
"Default Model": "Výchozí model",
|
||||
"Default model updated": "Výchozí model aktualizován.",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Výchozí návrhy promptů",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Smazat uživatele",
|
||||
"Deleted {{deleteModelTag}}": "Smazáno {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Smazáno {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Popis",
|
||||
"Didn't fully follow instructions": "Nenásledovali jste přesně všechny instrukce.",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Zadejte kódy jazyků",
|
||||
"Enter Model ID": "Zadejte ID modelu",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Zadejte označení modelu (např. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Zadejte počet kroků (např. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Zadejte vzorkovač (např. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Zadejte plánovač (např. Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "Nepodařilo se přidat soubor.",
|
||||
"Failed to create API Key.": "Nepodařilo se vytvořit API klíč.",
|
||||
"Failed to read clipboard contents": "Nepodařilo se přečíst obsah schránky",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Nepodařilo se aktualizovat nastavení",
|
||||
"Failed to upload file.": "Nepodařilo se nahrát soubor.",
|
||||
"February": "Únor",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Schovej",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Jak vám mohu dnes pomoci?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hybridní vyhledávání",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Beru na vědomí, že jsem si přečetl a chápu důsledky svých činů. Jsem si vědom rizik spojených s vykonáváním libovolného kódu a ověřil jsem důvěryhodnost zdroje.",
|
||||
"ID": "ID",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Obsah souboru modelfile",
|
||||
"Models": "Modely",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "více",
|
||||
"More": "Více",
|
||||
"Name": "Jméno",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "Nebyly nalezeny žádné znalosti",
|
||||
"No model IDs": "",
|
||||
"No models found": "Nebyly nalezeny žádné modely",
|
||||
"No models selected": "",
|
||||
"No results found": "Nebyly nalezeny žádné výsledky",
|
||||
"No search query generated": "Nebyl vygenerován žádný vyhledávací dotaz.",
|
||||
"No source available": "Není k dispozici žádný zdroj.",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Odebrat",
|
||||
"Remove Model": "Odebrat model",
|
||||
"Rename": "Přejmenovat",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Opakovat posledních N",
|
||||
"Request Mode": "Režim žádosti",
|
||||
"Reranking Model": "Model pro přehodnocení pořadí",
|
||||
"Reranking model disabled": "Přeřazovací model je deaktivován",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Model pro přeřazení nastaven na \"{{reranking_model}}\"",
|
||||
"Reset": "režim Reset",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Resetovat adresář nahrávání",
|
||||
"Reset Vector Storage/Knowledge": "Resetování úložiště vektorů/znalostí",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Oznámení o odpovědích nelze aktivovat, protože oprávnění webu byla zamítnuta. Navštivte nastavení svého prohlížeče a udělte potřebný přístup.",
|
||||
@@ -979,6 +992,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (Lokálně)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Režim širokoúhlého zobrazení",
|
||||
"Won": "Vyhrál",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Tillad afbrydelser i stemme i opkald",
|
||||
"Already have an account?": "Har du allerede en profil?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "en assistent",
|
||||
"and": "og",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Base URL er påkrævet.",
|
||||
"Available list": "Tilgængelige lister",
|
||||
"available!": "tilgængelig!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "Azure AI Speech",
|
||||
"Azure Region": "Azure Region",
|
||||
"Back": "Tilbage",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Concurrent requests",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Bekræft",
|
||||
"Confirm Password": "Bekræft password",
|
||||
"Confirm your action": "Bekræft din handling",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Standard (SentenceTransformers)",
|
||||
"Default Model": "Standard model",
|
||||
"Default model updated": "Standard model opdateret",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Standardforslag til prompt",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Slet bruger",
|
||||
"Deleted {{deleteModelTag}}": "Slettede {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Slettede {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Beskrivelse",
|
||||
"Didn't fully follow instructions": "Fulgte ikke instruktioner",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Indtast sprogkoder",
|
||||
"Enter Model ID": "Indtast model-ID",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Indtast modelmærke (f.eks. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Indtast antal trin (f.eks. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Indtast sampler (f.eks. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Indtast scheduler (f.eks. Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Kunne ikke oprette API-nøgle.",
|
||||
"Failed to read clipboard contents": "Kunne ikke læse indholdet af udklipsholderen",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Kunne ikke opdatere indstillinger",
|
||||
"Failed to upload file.": "Kunne ikke uploade fil.",
|
||||
"February": "Februar",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Skjul",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Hvordan kan jeg hjælpe dig i dag?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hybrid søgning",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Jeg anerkender, at jeg har læst og forstået konsekvenserne af min handling. Jeg er opmærksom på de risici, der er forbundet med at udføre vilkårlig kode, og jeg har verificeret kildens troværdighed.",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Modelfilindhold",
|
||||
"Models": "Modeller",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Mere",
|
||||
"Name": "Navn",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "Ingen viden fundet",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Ingen resultater fundet",
|
||||
"No search query generated": "Ingen søgeforespørgsel genereret",
|
||||
"No source available": "Ingen kilde tilgængelig",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Fjern",
|
||||
"Remove Model": "Fjern model",
|
||||
"Rename": "Omdøb",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Gentag sidste N",
|
||||
"Request Mode": "Forespørgselstilstand",
|
||||
"Reranking Model": "Omarrangeringsmodel",
|
||||
"Reranking model disabled": "Omarrangeringsmodel deaktiveret",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Omarrangeringsmodel sat til \"{{reranking_model}}\"",
|
||||
"Reset": "Nulstil",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Nulstil uploadmappe",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Svarnotifikationer kan ikke aktiveres, da webstedets tilladelser er blevet nægtet. Besøg dine browserindstillinger for at give den nødvendige adgang.",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (lokal)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Widescreen-tilstand",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -11,33 +11,33 @@
|
||||
"A task model is used when performing tasks such as generating titles for chats and web search queries": "Aufgabenmodelle können Unterhaltungstitel oder Websuchanfragen generieren.",
|
||||
"a user": "ein Benutzer",
|
||||
"About": "Über",
|
||||
"Access": "",
|
||||
"Access Control": "",
|
||||
"Accessible to all users": "",
|
||||
"Access": "Zugang",
|
||||
"Access Control": "Zugangskontrolle",
|
||||
"Accessible to all users": "Für alle Benutzer zugänglich",
|
||||
"Account": "Konto",
|
||||
"Account Activation Pending": "Kontoaktivierung ausstehend",
|
||||
"Accurate information": "Präzise Information(en)",
|
||||
"Actions": "Aktionen",
|
||||
"Activate this command by typing \"/{{COMMAND}}\" to chat input.": "",
|
||||
"Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Aktivieren Sie diesen Befehl, indem Sie \"/{{COMMAND}}\" in die Chat-Eingabe eingeben.",
|
||||
"Active Users": "Aktive Benutzer",
|
||||
"Add": "Hinzufügen",
|
||||
"Add a model ID": "",
|
||||
"Add a model ID": "Modell-ID hinzufügen",
|
||||
"Add a short description about what this model does": "Fügen Sie eine kurze Beschreibung über dieses Modell hinzu",
|
||||
"Add a tag": "Tag hinzufügen",
|
||||
"Add Arena Model": "Arena-Modell hinzufügen",
|
||||
"Add Connection": "",
|
||||
"Add Connection": "Verbindung hinzufügen",
|
||||
"Add Content": "Inhalt hinzufügen",
|
||||
"Add content here": "Inhalt hier hinzufügen",
|
||||
"Add custom prompt": "Benutzerdefinierten Prompt hinzufügen",
|
||||
"Add Files": "Dateien hinzufügen",
|
||||
"Add Group": "",
|
||||
"Add Group": "Gruppe hinzufügen",
|
||||
"Add Memory": "Erinnerung hinzufügen",
|
||||
"Add Model": "Modell hinzufügen",
|
||||
"Add Tag": "Tag hinzufügen",
|
||||
"Add Tags": "Tags hinzufügen",
|
||||
"Add text content": "Textinhalt hinzufügen",
|
||||
"Add User": "Benutzer hinzufügen",
|
||||
"Add User Group": "",
|
||||
"Add User Group": "Benutzergruppe hinzufügen",
|
||||
"Adjusting these settings will apply changes universally to all users.": "Das Anpassen dieser Einstellungen wird Änderungen universell auf alle Benutzer anwenden.",
|
||||
"admin": "Administrator",
|
||||
"Admin": "Administrator",
|
||||
@@ -48,17 +48,18 @@
|
||||
"Advanced Params": "Erweiterte Parameter",
|
||||
"All chats": "Alle Unterhaltungen",
|
||||
"All Documents": "Alle Dokumente",
|
||||
"All models deleted successfully": "",
|
||||
"Allow Chat Delete": "",
|
||||
"All models deleted successfully": "Alle Modelle erfolgreich gelöscht",
|
||||
"Allow Chat Delete": "Löschen von Unterhaltungen erlauben",
|
||||
"Allow Chat Deletion": "Löschen von Unterhaltungen erlauben",
|
||||
"Allow Chat Edit": "",
|
||||
"Allow File Upload": "",
|
||||
"Allow Chat Edit": "Bearbeiten von Unterhaltungen erlauben",
|
||||
"Allow File Upload": "Hochladen von Dateien erlauben",
|
||||
"Allow non-local voices": "Nicht-lokale Stimmen erlauben",
|
||||
"Allow Temporary Chat": "Temporäre Unterhaltungen erlauben",
|
||||
"Allow User Location": "Standort freigeben",
|
||||
"Allow Voice Interruption in Call": "Unterbrechung durch Stimme im Anruf zulassen",
|
||||
"Already have an account?": "Haben Sie bereits einen Account?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternative zu top_p und zielt darauf ab, ein Gleichgewicht zwischen Qualität und Vielfalt zu gewährleisten. Der Parameter p repräsentiert die Mindestwahrscheinlichkeit für ein Token, um berücksichtigt zu werden, relativ zur Wahrscheinlichkeit des wahrscheinlichsten Tokens. Zum Beispiel, bei p=0.05 und das wahrscheinlichste Token hat eine Wahrscheinlichkeit von 0.9, werden Logits mit einem Wert von weniger als 0.045 herausgefiltert. (Standard: 0.0)",
|
||||
"Amazing": "Fantastisch",
|
||||
"an assistant": "ein Assistent",
|
||||
"and": "und",
|
||||
"and {{COUNT}} more": "und {{COUNT}} mehr",
|
||||
@@ -67,15 +68,15 @@
|
||||
"API Key": "API-Schlüssel",
|
||||
"API Key created.": "API-Schlüssel erstellt.",
|
||||
"API keys": "API-Schlüssel",
|
||||
"Application DN": "",
|
||||
"Application DN Password": "",
|
||||
"applies to all users with the \"user\" role": "",
|
||||
"Application DN": "Anwendungs-DN",
|
||||
"Application DN Password": "Anwendungs-DN-Passwort",
|
||||
"applies to all users with the \"user\" role": "gilt für alle Benutzer mit der Rolle \"Benutzer\"",
|
||||
"April": "April",
|
||||
"Archive": "Archivieren",
|
||||
"Archive All Chats": "Alle Unterhaltungen archivieren",
|
||||
"Archived Chats": "Archivierte Unterhaltungen",
|
||||
"archived-chat-export": "",
|
||||
"Are you sure you want to unarchive all archived chats?": "",
|
||||
"archived-chat-export": "archivierter-chat-export",
|
||||
"Are you sure you want to unarchive all archived chats?": "Sind Sie sicher, dass Sie alle archivierten Unterhaltungen wiederherstellen möchten?",
|
||||
"Are you sure?": "Sind Sie sicher?",
|
||||
"Arena Models": "Arena-Modelle",
|
||||
"Artifacts": "Artefakte",
|
||||
@@ -83,10 +84,10 @@
|
||||
"Assistant": "Assistent",
|
||||
"Attach file": "Datei anhängen",
|
||||
"Attention to detail": "Aufmerksamkeit für Details",
|
||||
"Attribute for Username": "",
|
||||
"Attribute for Username": "Attribut für Benutzername",
|
||||
"Audio": "Audio",
|
||||
"August": "August",
|
||||
"Authenticate": "",
|
||||
"Authenticate": "Authentifizieren",
|
||||
"Auto-Copy Response to Clipboard": "Antwort automatisch in die Zwischenablage kopieren",
|
||||
"Auto-playback response": "Antwort automatisch abspielen",
|
||||
"Automatic1111": "Automatic1111",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111-Basis-URL ist erforderlich.",
|
||||
"Available list": "Verfügbare Liste",
|
||||
"available!": "Verfügbar!",
|
||||
"Awful": "Schrecklich",
|
||||
"Azure AI Speech": "Azure AI Speech",
|
||||
"Azure Region": "Azure-Region",
|
||||
"Back": "Zurück",
|
||||
@@ -104,27 +106,27 @@
|
||||
"Batch Size (num_batch)": "Stapelgröße (num_batch)",
|
||||
"before": "bereits geteilt",
|
||||
"Being lazy": "Faulheit",
|
||||
"Bing Search V7 Endpoint": "",
|
||||
"Bing Search V7 Subscription Key": "",
|
||||
"Bing Search V7 Endpoint": "Bing Search V7-Endpunkt",
|
||||
"Bing Search V7 Subscription Key": "Bing Search V7-Abonnement-Schlüssel",
|
||||
"Brave Search API Key": "Brave Search API-Schlüssel",
|
||||
"By {{name}}": "",
|
||||
"By {{name}}": "Von {{name}}",
|
||||
"Bypass SSL verification for Websites": "SSL-Überprüfung für Webseiten umgehen",
|
||||
"Call": "Anrufen",
|
||||
"Call feature is not supported when using Web STT engine": "Die Anruffunktion wird nicht unterstützt, wenn die Web-STT-Engine verwendet wird.",
|
||||
"Camera": "Kamera",
|
||||
"Cancel": "Abbrechen",
|
||||
"Capabilities": "Fähigkeiten",
|
||||
"Certificate Path": "",
|
||||
"Certificate Path": "Zertifikatpfad",
|
||||
"Change Password": "Passwort ändern",
|
||||
"Character": "Zeichen",
|
||||
"Chart new frontiers": "",
|
||||
"Chart new frontiers": "Neue Wege beschreiten",
|
||||
"Chat": "Gespräch",
|
||||
"Chat Background Image": "Hintergrundbild des Unterhaltungsfensters",
|
||||
"Chat Bubble UI": "Chat Bubble UI",
|
||||
"Chat Controls": "Chat-Steuerung",
|
||||
"Chat direction": "Textrichtung",
|
||||
"Chat Overview": "Unterhaltungsübersicht",
|
||||
"Chat Permissions": "",
|
||||
"Chat Permissions": "Unterhaltungsberechtigungen",
|
||||
"Chat Tags Auto-Generation": "Automatische Generierung von Unterhaltungstags",
|
||||
"Chats": "Unterhaltungen",
|
||||
"Check Again": "Erneut überprüfen",
|
||||
@@ -134,11 +136,11 @@
|
||||
"Chunk Overlap": "Blocküberlappung",
|
||||
"Chunk Params": "Blockparameter",
|
||||
"Chunk Size": "Blockgröße",
|
||||
"Ciphers": "",
|
||||
"Ciphers": "Verschlüsselungen",
|
||||
"Citation": "Zitate",
|
||||
"Clear memory": "Alle Erinnerungen entfernen",
|
||||
"click here": "",
|
||||
"Click here for filter guides.": "",
|
||||
"click here": "hier klicken",
|
||||
"Click here for filter guides.": "Klicken Sie hier für Filteranleitungen.",
|
||||
"Click here for help.": "Klicken Sie hier für Hilfe.",
|
||||
"Click here to": "Klicken Sie hier, um",
|
||||
"Click here to download user import template file.": "Klicken Sie hier, um die Vorlage für den Benutzerimport herunterzuladen.",
|
||||
@@ -155,7 +157,7 @@
|
||||
"Code execution": "Codeausführung",
|
||||
"Code formatted successfully": "Code erfolgreich formatiert",
|
||||
"Collection": "Kollektion",
|
||||
"Color": "",
|
||||
"Color": "Farbe",
|
||||
"ComfyUI": "ComfyUI",
|
||||
"ComfyUI Base URL": "ComfyUI-Basis-URL",
|
||||
"ComfyUI Base URL is required.": "ComfyUI-Basis-URL wird benötigt.",
|
||||
@@ -164,7 +166,8 @@
|
||||
"Command": "Befehl",
|
||||
"Completions": "Vervollständigungen",
|
||||
"Concurrent Requests": "Anzahl gleichzeitiger Anfragen",
|
||||
"Configure": "",
|
||||
"Configure": "Konfigurieren",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Bestätigen",
|
||||
"Confirm Password": "Passwort bestätigen",
|
||||
"Confirm your action": "Bestätigen Sie Ihre Aktion.",
|
||||
@@ -175,11 +178,11 @@
|
||||
"Context Length": "Kontextlänge",
|
||||
"Continue Response": "Antwort fortsetzen",
|
||||
"Continue with {{provider}}": "Mit {{provider}} fortfahren",
|
||||
"Continue with Email": "",
|
||||
"Continue with LDAP": "",
|
||||
"Continue with Email": "Mit Email fortfahren",
|
||||
"Continue with LDAP": "Mit LDAP fortfahren",
|
||||
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "Kontrollieren Sie, wie Nachrichtentext für TTS-Anfragen aufgeteilt wird. 'Punctuation' teilt in Sätze auf, 'paragraphs' teilt in Absätze auf und 'none' behält die Nachricht als einzelnen String.",
|
||||
"Controls": "Steuerung",
|
||||
"Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text. (Default: 5.0)": "",
|
||||
"Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text. (Default: 5.0)": "Kontrolliert das Gleichgewicht zwischen Kohärenz und Vielfalt des Ausgabetextes. Ein niedrigerer Wert führt zu fokussierterem und kohärenterem Text. (Standard: 5.0)",
|
||||
"Copied": "Kopiert",
|
||||
"Copied shared chat URL to clipboard!": "Freigabelink in die Zwischenablage kopiert!",
|
||||
"Copied to clipboard": "In die Zwischenablage kopiert",
|
||||
@@ -189,12 +192,12 @@
|
||||
"Copy Link": "Link kopieren",
|
||||
"Copy to clipboard": "In die Zwischenablage kopieren",
|
||||
"Copying to clipboard was successful!": "Das Kopieren in die Zwischenablage war erfolgreich!",
|
||||
"Create": "",
|
||||
"Create a knowledge base": "",
|
||||
"Create a model": "Ein Modell erstellen",
|
||||
"Create": "Erstellen",
|
||||
"Create a knowledge base": "Wissensspeicher erstellen",
|
||||
"Create a model": "Modell erstellen",
|
||||
"Create Account": "Konto erstellen",
|
||||
"Create Admin Account": "",
|
||||
"Create Group": "",
|
||||
"Create Admin Account": "Administrator-Account erstellen",
|
||||
"Create Group": "Gruppe erstellen",
|
||||
"Create Knowledge": "Wissen erstellen",
|
||||
"Create new key": "Neuen Schlüssel erstellen",
|
||||
"Create new secret key": "Neuen API-Schlüssel erstellen",
|
||||
@@ -213,16 +216,17 @@
|
||||
"Default (SentenceTransformers)": "Standard (SentenceTransformers)",
|
||||
"Default Model": "Standardmodell",
|
||||
"Default model updated": "Standardmodell aktualisiert",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Models": "",
|
||||
"Default permissions": "Standardberechtigungen",
|
||||
"Default permissions updated successfully": "Standardberechtigungen erfolgreich aktualisiert",
|
||||
"Default Prompt Suggestions": "Prompt-Vorschläge",
|
||||
"Default to 389 or 636 if TLS is enabled": "",
|
||||
"Default to ALL": "",
|
||||
"Default to 389 or 636 if TLS is enabled": "Standardmäßig auf 389 oder 636 setzen, wenn TLS aktiviert ist",
|
||||
"Default to ALL": "Standardmäßig auf ALLE setzen",
|
||||
"Default User Role": "Standardbenutzerrolle",
|
||||
"Delete": "Löschen",
|
||||
"Delete a model": "Ein Modell löschen",
|
||||
"Delete All Chats": "Alle Unterhaltungen löschen",
|
||||
"Delete All Models": "",
|
||||
"Delete All Models": "Alle Modelle löschen",
|
||||
"Delete chat": "Unterhaltung löschen",
|
||||
"Delete Chat": "Unterhaltung löschen",
|
||||
"Delete chat?": "Unterhaltung löschen?",
|
||||
@@ -234,7 +238,8 @@
|
||||
"Delete User": "Benutzer löschen",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} gelöscht",
|
||||
"Deleted {{name}}": "{{name}} gelöscht",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Deleted User": "Benutzer gelöscht",
|
||||
"Describe your knowledge base and objectives": "Beschreibe deinen Wissensspeicher und deine Ziele",
|
||||
"Description": "Beschreibung",
|
||||
"Didn't fully follow instructions": "Nicht genau den Answeisungen gefolgt",
|
||||
"Disabled": "Deaktiviert",
|
||||
@@ -242,17 +247,17 @@
|
||||
"Discover a model": "Entdecken Sie weitere Modelle",
|
||||
"Discover a prompt": "Entdecken Sie weitere Prompts",
|
||||
"Discover a tool": "Entdecken Sie weitere Werkzeuge",
|
||||
"Discover wonders": "",
|
||||
"Discover wonders": "Entdecken Sie Wunder",
|
||||
"Discover, download, and explore custom functions": "Entdecken und beziehen Sie benutzerdefinierte Funktionen",
|
||||
"Discover, download, and explore custom prompts": "Entdecken und beziehen Sie benutzerdefinierte Prompts",
|
||||
"Discover, download, and explore custom tools": "Entdecken und beziehen Sie benutzerdefinierte Werkzeuge",
|
||||
"Discover, download, and explore model presets": "Entdecken und beziehen Sie benutzerdefinierte Modellvorlagen",
|
||||
"Dismissible": "ausblendbar",
|
||||
"Display": "",
|
||||
"Display": "Anzeigen",
|
||||
"Display Emoji in Call": "Emojis im Anruf anzeigen",
|
||||
"Display the username instead of You in the Chat": "Soll \"Sie\" durch Ihren Benutzernamen ersetzt werden?",
|
||||
"Displays citations in the response": "",
|
||||
"Dive into knowledge": "",
|
||||
"Displays citations in the response": "Zeigt Zitate in der Antwort an",
|
||||
"Dive into knowledge": "Tauchen Sie in das Wissen ein",
|
||||
"Do not install functions from sources you do not fully trust.": "Installieren Sie keine Funktionen aus Quellen, denen Sie nicht vollständig vertrauen.",
|
||||
"Do not install tools from sources you do not fully trust.": "Installieren Sie keine Werkzeuge aus Quellen, denen Sie nicht vollständig vertrauen.",
|
||||
"Document": "Dokument",
|
||||
@@ -267,39 +272,39 @@
|
||||
"Download": "Exportieren",
|
||||
"Download canceled": "Exportierung abgebrochen",
|
||||
"Download Database": "Datenbank exportieren",
|
||||
"Drag and drop a file to upload or select a file to view": "",
|
||||
"Drag and drop a file to upload or select a file to view": "Ziehen Sie eine Datei zum Hochladen oder wählen Sie eine Datei zum Anzeigen aus",
|
||||
"Draw": "Zeichnen",
|
||||
"Drop any files here to add to the conversation": "Ziehen Sie beliebige Dateien hierher, um sie der Unterhaltung hinzuzufügen",
|
||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "z. B. '30s','10m'. Gültige Zeiteinheiten sind 's', 'm', 'h'.",
|
||||
"e.g. A filter to remove profanity from text": "",
|
||||
"e.g. My Filter": "",
|
||||
"e.g. My Tools": "",
|
||||
"e.g. my_filter": "",
|
||||
"e.g. my_tools": "",
|
||||
"e.g. Tools for performing various operations": "",
|
||||
"e.g. A filter to remove profanity from text": "z. B. Ein Filter, um Schimpfwörter aus Text zu entfernen",
|
||||
"e.g. My Filter": "z. B. Mein Filter",
|
||||
"e.g. My Tools": "z. B. Meine Werkzeuge",
|
||||
"e.g. my_filter": "z. B. mein_filter",
|
||||
"e.g. my_tools": "z. B. meine_werkzeuge",
|
||||
"e.g. Tools for performing various operations": "z. B. Werkzeuge für verschiedene Operationen",
|
||||
"Edit": "Bearbeiten",
|
||||
"Edit Arena Model": "Arena-Modell bearbeiten",
|
||||
"Edit Connection": "",
|
||||
"Edit Default Permissions": "",
|
||||
"Edit Connection": "Verbindung bearbeiten",
|
||||
"Edit Default Permissions": "Standardberechtigungen bearbeiten",
|
||||
"Edit Memory": "Erinnerungen bearbeiten",
|
||||
"Edit User": "Benutzer bearbeiten",
|
||||
"Edit User Group": "",
|
||||
"Edit User Group": "Benutzergruppe bearbeiten",
|
||||
"ElevenLabs": "ElevenLabs",
|
||||
"Email": "E-Mail",
|
||||
"Embark on adventures": "",
|
||||
"Embark on adventures": "Abenteuer erleben",
|
||||
"Embedding Batch Size": "Embedding-Stapelgröße",
|
||||
"Embedding Model": "Embedding-Modell",
|
||||
"Embedding Model Engine": "Embedding-Modell-Engine",
|
||||
"Embedding model set to \"{{embedding_model}}\"": "Embedding-Modell auf \"{{embedding_model}}\" gesetzt",
|
||||
"Enable API Key Auth": "",
|
||||
"Enable API Key Auth": "API-Schlüssel-Authentifizierung aktivieren",
|
||||
"Enable Community Sharing": "Community-Freigabe aktivieren",
|
||||
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "",
|
||||
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "",
|
||||
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Aktiviere Memory Locking (mlock), um zu verhindern, dass Modelldaten aus dem RAM ausgelagert werden. Diese Option sperrt die Arbeitsseiten des Modells im RAM, um sicherzustellen, dass sie nicht auf die Festplatte ausgelagert werden. Dies kann die Leistung verbessern, indem Page Faults vermieden und ein schneller Datenzugriff sichergestellt werden.",
|
||||
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Aktiviere Memory Mapping (mmap), um Modelldaten zu laden. Diese Option ermöglicht es dem System, den Festplattenspeicher als Erweiterung des RAM zu verwenden, indem Festplattendateien so behandelt werden, als ob sie im RAM wären. Dies kann die Modellleistung verbessern, indem ein schnellerer Datenzugriff ermöglicht wird. Es kann jedoch nicht auf allen Systemen korrekt funktionieren und einen erheblichen Teil des Festplattenspeichers beanspruchen.",
|
||||
"Enable Message Rating": "Nachrichtenbewertung aktivieren",
|
||||
"Enable Mirostat sampling for controlling perplexity. (Default: 0, 0 = Disabled, 1 = Mirostat, 2 = Mirostat 2.0)": "",
|
||||
"Enable Mirostat sampling for controlling perplexity. (Default: 0, 0 = Disabled, 1 = Mirostat, 2 = Mirostat 2.0)": "Mirostat Sampling zur Steuerung der Perplexität aktivieren. (Standard: 0, 0 = Deaktiviert, 1 = Mirostat, 2 = Mirostat 2.0)",
|
||||
"Enable New Sign Ups": "Registrierung erlauben",
|
||||
"Enable Retrieval Query Generation": "",
|
||||
"Enable Tags Generation": "",
|
||||
"Enable Retrieval Query Generation": "Abfragegenerierung aktivieren",
|
||||
"Enable Tags Generation": "Tag-Generierung aktivieren",
|
||||
"Enable Web Search": "Websuche aktivieren",
|
||||
"Enable Web Search Query Generation": "Websuchanfragen-Generierung aktivieren",
|
||||
"Enabled": "Aktiviert",
|
||||
@@ -308,12 +313,12 @@
|
||||
"Enter {{role}} message here": "Geben Sie die {{role}}-Nachricht hier ein",
|
||||
"Enter a detail about yourself for your LLMs to recall": "Geben Sie ein Detail über sich selbst ein, das Ihre Sprachmodelle (LLMs) sich merken sollen",
|
||||
"Enter api auth string (e.g. username:password)": "Geben Sie die API-Authentifizierungszeichenfolge ein (z. B. Benutzername:Passwort)",
|
||||
"Enter Application DN": "",
|
||||
"Enter Application DN Password": "",
|
||||
"Enter Bing Search V7 Endpoint": "",
|
||||
"Enter Bing Search V7 Subscription Key": "",
|
||||
"Enter Application DN": "Geben Sie die Anwendungs-DN ein",
|
||||
"Enter Application DN Password": "Geben Sie das Anwendungs-DN-Passwort ein",
|
||||
"Enter Bing Search V7 Endpoint": "Geben Sie den Bing Search V7-Endpunkt ein",
|
||||
"Enter Bing Search V7 Subscription Key": "Geben Sie den Bing Search V7-Abonnement-Schlüssel ein",
|
||||
"Enter Brave Search API Key": "Geben Sie den Brave Search API-Schlüssel ein",
|
||||
"Enter certificate path": "",
|
||||
"Enter certificate path": "Geben Sie den Zertifikatpfad ein",
|
||||
"Enter CFG Scale (e.g. 7.0)": "Geben Sie die CFG-Skala ein (z. B. 7.0)",
|
||||
"Enter Chunk Overlap": "Geben Sie die Blocküberlappung ein",
|
||||
"Enter Chunk Size": "Geben Sie die Blockgröße ein",
|
||||
@@ -322,10 +327,11 @@
|
||||
"Enter Google PSE API Key": "Geben Sie den Google PSE-API-Schlüssel ein",
|
||||
"Enter Google PSE Engine Id": "Geben Sie die Google PSE-Engine-ID ein",
|
||||
"Enter Image Size (e.g. 512x512)": "Geben Sie die Bildgröße ein (z. B. 512x512)",
|
||||
"Enter Jina API Key": "",
|
||||
"Enter Jina API Key": "Geben Sie den Jina-API-Schlüssel ein",
|
||||
"Enter language codes": "Geben Sie die Sprachcodes ein",
|
||||
"Enter Model ID": "Geben Sie die Modell-ID ein",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Gebn Sie den Model-Tag ein",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Geben Sie den Model-Tag ein",
|
||||
"Enter Mojeek Search API Key": "Geben Sie den Mojeek Search API-Schlüssel ein",
|
||||
"Enter Number of Steps (e.g. 50)": "Geben Sie die Anzahl an Schritten ein (z. B. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Geben Sie den Sampler ein (z. B. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Geben Sie den Scheduler ein (z. B. Karras)",
|
||||
@@ -333,13 +339,13 @@
|
||||
"Enter SearchApi API Key": "Geben Sie den SearchApi-API-Schlüssel ein",
|
||||
"Enter SearchApi Engine": "Geben Sie die SearchApi-Engine ein",
|
||||
"Enter Searxng Query URL": "Geben Sie die Searxng-Abfrage-URL ein",
|
||||
"Enter Seed": "",
|
||||
"Enter Seed": "Geben Sie den Seed ein",
|
||||
"Enter Serper API Key": "Geben Sie den Serper-API-Schlüssel ein",
|
||||
"Enter Serply API Key": "Geben Sie den",
|
||||
"Enter Serpstack API Key": "Geben Sie den Serpstack-API-Schlüssel ein",
|
||||
"Enter server host": "",
|
||||
"Enter server label": "",
|
||||
"Enter server port": "",
|
||||
"Enter server host": "Geben Sie den Server-Host ein",
|
||||
"Enter server label": "Geben Sie das Server-Label ein",
|
||||
"Enter server port": "Geben Sie den Server-Port ein",
|
||||
"Enter stop sequence": "Stop-Sequenz eingeben",
|
||||
"Enter system prompt": "Systemprompt eingeben",
|
||||
"Enter Tavily API Key": "Geben Sie den Tavily-API-Schlüssel ein",
|
||||
@@ -352,38 +358,39 @@
|
||||
"Enter your message": "Geben Sie Ihre Nachricht ein",
|
||||
"Enter Your Password": "Geben Sie Ihr Passwort ein",
|
||||
"Enter Your Role": "Geben Sie Ihre Rolle ein",
|
||||
"Enter Your Username": "",
|
||||
"Enter Your Username": "Geben Sie Ihren Benutzernamen ein",
|
||||
"Error": "Fehler",
|
||||
"ERROR": "FEHLER",
|
||||
"Evaluations": "Evaluationen",
|
||||
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "",
|
||||
"Example: ALL": "",
|
||||
"Example: ou=users,dc=foo,dc=example": "",
|
||||
"Example: sAMAccountName or uid or userPrincipalName": "",
|
||||
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Beispiel: (&(objectClass=inetOrgPerson)(uid=%s))",
|
||||
"Example: ALL": "Beispiel: ALL",
|
||||
"Example: ou=users,dc=foo,dc=example": "Beispiel: ou=users,dc=foo,dc=example",
|
||||
"Example: sAMAccountName or uid or userPrincipalName": "Beispiel: sAMAccountName or uid or userPrincipalName",
|
||||
"Exclude": "Ausschließen",
|
||||
"Experimental": "Experimentell",
|
||||
"Explore the cosmos": "",
|
||||
"Explore the cosmos": "Erforschen Sie das Universum",
|
||||
"Export": "Exportieren",
|
||||
"Export All Archived Chats": "",
|
||||
"Export All Archived Chats": "Alle archivierten Unterhaltungen exportieren",
|
||||
"Export All Chats (All Users)": "Alle Unterhaltungen exportieren (alle Benutzer)",
|
||||
"Export chat (.json)": "Unterhaltung exportieren (.json)",
|
||||
"Export Chats": "Unterhaltungen exportieren",
|
||||
"Export Config to JSON File": "Exportiere Konfiguration als JSON-Datei",
|
||||
"Export Functions": "Funktionen exportieren",
|
||||
"Export Models": "Modelle exportieren",
|
||||
"Export Presets": "",
|
||||
"Export Presets": "Voreinstellungen exportieren",
|
||||
"Export Prompts": "Prompts exportieren",
|
||||
"Export to CSV": "",
|
||||
"Export to CSV": "Als CSV exportieren",
|
||||
"Export Tools": "Werkzeuge exportieren",
|
||||
"External Models": "Externe Modelle",
|
||||
"Failed to add file.": "Fehler beim Hinzufügen der Datei.",
|
||||
"Failed to create API Key.": "Fehler beim Erstellen des API-Schlüssels.",
|
||||
"Failed to read clipboard contents": "Fehler beim Abruf der Zwischenablage",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Fehler beim Aktualisieren der Einstellungen",
|
||||
"Failed to upload file.": "Fehler beim Hochladen der Datei.",
|
||||
"February": "Februar",
|
||||
"Feedback History": "Feedback-Verlauf",
|
||||
"Feedbacks": "",
|
||||
"Feedbacks": "Feedbacks",
|
||||
"Feel free to add specific details": "Fühlen Sie sich frei, spezifische Details hinzuzufügen",
|
||||
"File": "Datei",
|
||||
"File added successfully.": "Datei erfolgreich hinzugefügt.",
|
||||
@@ -404,18 +411,18 @@
|
||||
"Folder name cannot be empty.": "Ordnername darf nicht leer sein.",
|
||||
"Folder name updated successfully": "Ordnername erfolgreich aktualisiert",
|
||||
"Followed instructions perfectly": "Anweisungen perfekt befolgt",
|
||||
"Forge new paths": "",
|
||||
"Forge new paths": "Neue Wege beschreiten",
|
||||
"Form": "Formular",
|
||||
"Format your variables using brackets like this:": "Formatieren Sie Ihre Variablen mit Klammern, wie hier:",
|
||||
"Frequency Penalty": "Frequenzstrafe",
|
||||
"Function": "Funktion",
|
||||
"Function created successfully": "Funktion erfolgreich erstellt",
|
||||
"Function deleted successfully": "Funktion erfolgreich gelöscht",
|
||||
"Function Description": "",
|
||||
"Function ID": "",
|
||||
"Function Description": "Funktionsbeschreibung",
|
||||
"Function ID": "Funktions-ID",
|
||||
"Function is now globally disabled": "Die Funktion ist jetzt global deaktiviert",
|
||||
"Function is now globally enabled": "Die Funktion ist jetzt global aktiviert",
|
||||
"Function Name": "",
|
||||
"Function Name": "Funktionsname",
|
||||
"Function updated successfully": "Funktion erfolgreich aktualisiert",
|
||||
"Functions": "Funktionen",
|
||||
"Functions allow arbitrary code execution": "Funktionen ermöglichen die Ausführung beliebigen Codes",
|
||||
@@ -426,33 +433,34 @@
|
||||
"Generate Image": "Bild erzeugen",
|
||||
"Generating search query": "Suchanfrage wird erstellt",
|
||||
"Generation Info": "Generierungsinformationen",
|
||||
"Get started": "",
|
||||
"Get started with {{WEBUI_NAME}}": "",
|
||||
"Get started": "Loslegen",
|
||||
"Get started with {{WEBUI_NAME}}": "Loslegen mit {{WEBUI_NAME}}",
|
||||
"Global": "Global",
|
||||
"Good Response": "Gute Antwort",
|
||||
"Google PSE API Key": "Google PSE-API-Schlüssel",
|
||||
"Google PSE Engine Id": "Google PSE-Engine-ID",
|
||||
"Group created successfully": "",
|
||||
"Group deleted successfully": "",
|
||||
"Group Description": "",
|
||||
"Group Name": "",
|
||||
"Group updated successfully": "",
|
||||
"Groups": "",
|
||||
"Group created successfully": "Gruppe erfolgreich erstellt",
|
||||
"Group deleted successfully": "Gruppe erfolgreich gelöscht",
|
||||
"Group Description": "Gruppenbeschreibung",
|
||||
"Group Name": "Gruppenname",
|
||||
"Group updated successfully": "Gruppe erfolgreich aktualisiert",
|
||||
"Groups": "Gruppen",
|
||||
"h:mm a": "h:mm a",
|
||||
"Haptic Feedback": "Haptisches Feedback",
|
||||
"has no conversations.": "hat keine Unterhaltungen.",
|
||||
"Hello, {{name}}": "Hallo, {{name}}",
|
||||
"Help": "Hilfe",
|
||||
"Help us create the best community leaderboard by sharing your feedback history!": "Helfen Sie uns, die beste Community-Bestenliste zu erstellen, indem Sie Ihren Feedback-Verlauf teilen!",
|
||||
"Hex Color": "",
|
||||
"Hex Color - Leave empty for default color": "",
|
||||
"Hex Color": "Hex-Farbe",
|
||||
"Hex Color - Leave empty for default color": "Hex-Farbe - Leer lassen für Standardfarbe",
|
||||
"Hide": "Verbergen",
|
||||
"Host": "",
|
||||
"Host": "Host",
|
||||
"How can I help you today?": "Wie kann ich Ihnen heute helfen?",
|
||||
"How would you rate this response?": "Wie würden Sie diese Antwort bewerten?",
|
||||
"Hybrid Search": "Hybride Suche",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Ich bestätige, dass ich gelesen habe und die Auswirkungen meiner Aktion verstehe. Mir sind die Risiken bewusst, die mit der Ausführung beliebigen Codes verbunden sind, und ich habe die Vertrauenswürdigkeit der Quelle überprüft.",
|
||||
"ID": "ID",
|
||||
"Ignite curiosity": "",
|
||||
"Ignite curiosity": "Neugier entfachen",
|
||||
"Image Generation (Experimental)": "Bildgenerierung (experimentell)",
|
||||
"Image Generation Engine": "Bildgenerierungs-Engine",
|
||||
"Image Settings": "Bildeinstellungen",
|
||||
@@ -461,13 +469,13 @@
|
||||
"Import Config from JSON File": "Konfiguration aus JSON-Datei importieren",
|
||||
"Import Functions": "Funktionen importieren",
|
||||
"Import Models": "Modelle importieren",
|
||||
"Import Presets": "",
|
||||
"Import Presets": "Voreinstellungen importieren",
|
||||
"Import Prompts": "Prompts importieren",
|
||||
"Import Tools": "Werkzeuge importieren",
|
||||
"Include": "Einschließen",
|
||||
"Include `--api-auth` flag when running stable-diffusion-webui": "Fügen Sie beim Ausführen von stable-diffusion-webui die Option `--api-auth` hinzu",
|
||||
"Include `--api` flag when running stable-diffusion-webui": "Fügen Sie beim Ausführen von stable-diffusion-webui die Option `--api` hinzu",
|
||||
"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. (Default: 0.1)": "",
|
||||
"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. (Default: 0.1)": "Beeinflusst, wie schnell der Algorithmus auf Feedback aus dem generierten Text reagiert. Eine niedrigere Lernrate führt zu langsameren Anpassungen, während eine höhere Lernrate den Algorithmus reaktionsschneller macht. (Standard: 0.1)",
|
||||
"Info": "Info",
|
||||
"Input commands": "Eingabebefehle",
|
||||
"Install from Github URL": "Installiere von der Github-URL",
|
||||
@@ -476,7 +484,7 @@
|
||||
"Invalid file format.": "Ungültiges Dateiformat.",
|
||||
"Invalid Tag": "Ungültiger Tag",
|
||||
"January": "Januar",
|
||||
"Jina API Key": "",
|
||||
"Jina API Key": "Jina-API-Schlüssel",
|
||||
"join our Discord for help.": "Treten Sie unserem Discord bei, um Hilfe zu erhalten.",
|
||||
"JSON": "JSON",
|
||||
"JSON Preview": "JSON-Vorschau",
|
||||
@@ -485,31 +493,31 @@
|
||||
"JWT Expiration": "JWT-Ablauf",
|
||||
"JWT Token": "JWT-Token",
|
||||
"Keep Alive": "Verbindung aufrechterhalten",
|
||||
"Key": "",
|
||||
"Key": "Schlüssel",
|
||||
"Keyboard shortcuts": "Tastenkombinationen",
|
||||
"Knowledge": "Wissen",
|
||||
"Knowledge Access": "",
|
||||
"Knowledge Access": "Wissenszugriff",
|
||||
"Knowledge created successfully.": "Wissen erfolgreich erstellt.",
|
||||
"Knowledge deleted successfully.": "Wissen erfolgreich gelöscht.",
|
||||
"Knowledge reset successfully.": "Wissen erfolgreich zurückgesetzt.",
|
||||
"Knowledge updated successfully": "Wissen erfolgreich aktualisiert",
|
||||
"Label": "",
|
||||
"Label": "Label",
|
||||
"Landing Page Mode": "Startseitenmodus",
|
||||
"Language": "Sprache",
|
||||
"Last Active": "Zuletzt aktiv",
|
||||
"Last Modified": "Zuletzt bearbeitet",
|
||||
"LDAP": "",
|
||||
"LDAP server updated": "",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP server updated": "LDAP-Server aktualisiert",
|
||||
"Leaderboard": "Bestenliste",
|
||||
"Leave empty for unlimited": "Leer lassen für unbegrenzt",
|
||||
"Leave empty to include all models from \"{{URL}}/api/tags\" endpoint": "",
|
||||
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
|
||||
"Leave empty to include all models from \"{{URL}}/api/tags\" endpoint": "Leer lassen, um alle Modelle vom \"{{URL}}/api/tags\"-Endpunkt einzuschließen",
|
||||
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Leer lassen, um alle Modelle vom \"{{URL}}/models\"-Endpunkt einzuschließen",
|
||||
"Leave empty to include all models or select specific models": "Leer lassen, um alle Modelle einzuschließen oder spezifische Modelle auszuwählen",
|
||||
"Leave empty to use the default prompt, or enter a custom prompt": "Leer lassen, um den Standardprompt zu verwenden, oder geben Sie einen benutzerdefinierten Prompt ein",
|
||||
"Light": "Hell",
|
||||
"Listening...": "Höre zu...",
|
||||
"LLMs can make mistakes. Verify important information.": "LLMs können Fehler machen. Überprüfe wichtige Informationen.",
|
||||
"Local": "",
|
||||
"Local": "Lokal",
|
||||
"Local Models": "Lokale Modelle",
|
||||
"Lost": "Verloren",
|
||||
"LTR": "LTR",
|
||||
@@ -518,9 +526,9 @@
|
||||
"Make sure to export a workflow.json file as API format from ComfyUI.": "Stellen Sie sicher, dass sie eine workflow.json-Datei im API-Format von ComfyUI exportieren.",
|
||||
"Manage": "Verwalten",
|
||||
"Manage Arena Models": "Arena-Modelle verwalten",
|
||||
"Manage Ollama": "",
|
||||
"Manage Ollama API Connections": "",
|
||||
"Manage OpenAI API Connections": "",
|
||||
"Manage Ollama": "Ollama verwalten",
|
||||
"Manage Ollama API Connections": "Ollama-API-Verbindungen verwalten",
|
||||
"Manage OpenAI API Connections": "OpenAI-API-Verbindungen verwalten",
|
||||
"Manage Pipelines": "Pipelines verwalten",
|
||||
"March": "März",
|
||||
"Max Tokens (num_predict)": "Maximale Tokenanzahl (num_predict)",
|
||||
@@ -554,21 +562,23 @@
|
||||
"Model accepts image inputs": "Modell akzeptiert Bileingaben",
|
||||
"Model created successfully!": "Modell erfolgreich erstellt!",
|
||||
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "Modell-Dateisystempfad erkannt. Modellkurzname ist für das Update erforderlich, Fortsetzung nicht möglich.",
|
||||
"Model Filtering": "",
|
||||
"Model Filtering": "Modellfilterung",
|
||||
"Model ID": "Modell-ID",
|
||||
"Model IDs": "",
|
||||
"Model IDs": "Modell-IDs",
|
||||
"Model Name": "Modell-Name",
|
||||
"Model not selected": "Modell nicht ausgewählt",
|
||||
"Model Params": "Modell-Params",
|
||||
"Model Permissions": "",
|
||||
"Model Params": "Modell-Parameter",
|
||||
"Model Permissions": "Modellberechtigungen",
|
||||
"Model updated successfully": "Modell erfolgreich aktualisiert",
|
||||
"Modelfile Content": "Modelfile-Inhalt",
|
||||
"Models": "Modelle",
|
||||
"Models Access": "",
|
||||
"Models Access": "Modell-Zugriff",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "Mojeek Search API-Schlüssel",
|
||||
"more": "mehr",
|
||||
"More": "Mehr",
|
||||
"Name": "Name",
|
||||
"Name your knowledge base": "",
|
||||
"Name your knowledge base": "Benennen Sie Ihren Wissensspeicher",
|
||||
"New Chat": "Neue Unterhaltung",
|
||||
"New folder": "Neuer Ordner",
|
||||
"New Password": "Neues Passwort",
|
||||
@@ -578,15 +588,16 @@
|
||||
"No feedbacks found": "Kein Feedback gefunden",
|
||||
"No file selected": "Keine Datei ausgewählt",
|
||||
"No files found.": "Keine Dateien gefunden.",
|
||||
"No groups with access, add a group to grant access": "",
|
||||
"No groups with access, add a group to grant access": "Keine Gruppen mit Zugriff, fügen Sie eine Gruppe hinzu, um Zugriff zu gewähren",
|
||||
"No HTML, CSS, or JavaScript content found.": "Keine HTML-, CSS- oder JavaScript-Inhalte gefunden.",
|
||||
"No knowledge found": "Kein Wissen gefunden",
|
||||
"No model IDs": "",
|
||||
"No model IDs": "Keine Modell-IDs",
|
||||
"No models found": "Keine Modelle gefunden",
|
||||
"No models selected": "",
|
||||
"No results found": "Keine Ergebnisse gefunden",
|
||||
"No search query generated": "Keine Suchanfrage generiert",
|
||||
"No source available": "Keine Quelle verfügbar",
|
||||
"No users were found.": "",
|
||||
"No users were found.": "Keine Benutzer gefunden.",
|
||||
"No valves to update": "Keine Valves zum Aktualisieren",
|
||||
"None": "Nichts",
|
||||
"Not factually correct": "Nicht sachlich korrekt",
|
||||
@@ -605,13 +616,13 @@
|
||||
"Ollama": "Ollama",
|
||||
"Ollama API": "Ollama-API",
|
||||
"Ollama API disabled": "Ollama-API deaktiviert",
|
||||
"Ollama API settings updated": "",
|
||||
"Ollama API settings updated": "Ollama-API-Einstellungen aktualisiert",
|
||||
"Ollama Version": "Ollama-Version",
|
||||
"On": "Ein",
|
||||
"Only alphanumeric characters and hyphens are allowed": "",
|
||||
"Only alphanumeric characters and hyphens are allowed": "Nur alphanumerische Zeichen und Bindestriche sind erlaubt",
|
||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "In der Befehlszeichenfolge sind nur alphanumerische Zeichen und Bindestriche erlaubt.",
|
||||
"Only collections can be edited, create a new knowledge base to edit/add documents.": "Nur Sammlungen können bearbeitet werden. Erstellen Sie eine neue Wissensbasis, um Dokumente zu bearbeiten/hinzuzufügen.",
|
||||
"Only select users and groups with permission can access": "",
|
||||
"Only select users and groups with permission can access": "Nur ausgewählte Benutzer und Gruppen mit Berechtigung können darauf zugreifen",
|
||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Hoppla! Es scheint, dass die URL ungültig ist. Bitte überprüfen Sie diese und versuchen Sie es erneut.",
|
||||
"Oops! There are files still uploading. Please wait for the upload to complete.": "Hoppla! Es werden noch Dateien hochgeladen. Bitte warten Sie, bis der Upload abgeschlossen ist.",
|
||||
"Oops! There was an error in the previous response.": "Hoppla! Es gab einen Fehler in der vorherigen Antwort.",
|
||||
@@ -620,34 +631,34 @@
|
||||
"Open in full screen": "Im Vollbildmodus öffnen",
|
||||
"Open new chat": "Neuen Chat öffnen",
|
||||
"Open WebUI uses faster-whisper internally.": "Open WebUI verwendet intern faster-whisper.",
|
||||
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "",
|
||||
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Open WebUI verwendet SpeechT5 und CMU Arctic-Sprecher-Embeddings.",
|
||||
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Die installierte Open-WebUI-Version (v{{OPEN_WEBUI_VERSION}}) ist niedriger als die erforderliche Version (v{{REQUIRED_VERSION}})",
|
||||
"OpenAI": "OpenAI",
|
||||
"OpenAI API": "OpenAI-API",
|
||||
"OpenAI API Config": "OpenAI-API-Konfiguration",
|
||||
"OpenAI API Key is required.": "OpenAI-API-Schlüssel erforderlich.",
|
||||
"OpenAI API settings updated": "",
|
||||
"OpenAI API settings updated": "OpenAI-API-Einstellungen aktualisiert",
|
||||
"OpenAI URL/Key required.": "OpenAI-URL/Schlüssel erforderlich.",
|
||||
"or": "oder",
|
||||
"Organize your users": "",
|
||||
"Organize your users": "Organisieren Sie Ihre Benutzer",
|
||||
"Other": "Andere",
|
||||
"OUTPUT": "AUSGABE",
|
||||
"Output format": "Ausgabeformat",
|
||||
"Overview": "Übersicht",
|
||||
"page": "Seite",
|
||||
"Password": "Passwort",
|
||||
"Paste Large Text as File": "",
|
||||
"Paste Large Text as File": "Großen Text als Datei einfügen",
|
||||
"PDF document (.pdf)": "PDF-Dokument (.pdf)",
|
||||
"PDF Extract Images (OCR)": "Text von Bildern aus PDFs extrahieren (OCR)",
|
||||
"pending": "ausstehend",
|
||||
"Permission denied when accessing media devices": "Zugriff auf Mediengeräte verweigert",
|
||||
"Permission denied when accessing microphone": "Zugriff auf das Mikrofon verweigert",
|
||||
"Permission denied when accessing microphone: {{error}}": "Zugriff auf das Mikrofon verweigert: {{error}}",
|
||||
"Permissions": "",
|
||||
"Permissions": "Berechtigungen",
|
||||
"Personalization": "Personalisierung",
|
||||
"Pin": "Anheften",
|
||||
"Pinned": "Angeheftet",
|
||||
"Pioneer insights": "",
|
||||
"Pioneer insights": "Bahnbrechende Erkenntnisse",
|
||||
"Pipeline deleted successfully": "Pipeline erfolgreich gelöscht",
|
||||
"Pipeline downloaded successfully": "Pipeline erfolgreich heruntergeladen",
|
||||
"Pipelines": "Pipelines",
|
||||
@@ -659,23 +670,23 @@
|
||||
"Please enter a prompt": "Bitte geben Sie einen Prompt ein",
|
||||
"Please fill in all fields.": "Bitte füllen Sie alle Felder aus.",
|
||||
"Please select a reason": "Bitte wählen Sie einen Grund aus",
|
||||
"Port": "",
|
||||
"Port": "Port",
|
||||
"Positive attitude": "Positive Einstellung",
|
||||
"Prefix ID": "",
|
||||
"Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "",
|
||||
"Prefix ID": "Präfix-ID",
|
||||
"Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Prefix-ID wird verwendet, um Konflikte mit anderen Verbindungen zu vermeiden, indem ein Präfix zu den Modell-IDs hinzugefügt wird - leer lassen, um zu deaktivieren",
|
||||
"Previous 30 days": "Vorherige 30 Tage",
|
||||
"Previous 7 days": "Vorherige 7 Tage",
|
||||
"Profile Image": "Profilbild",
|
||||
"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Prompt (z. B. \"Erzähle mir eine interessante Tatsache über das Römische Reich\")",
|
||||
"Prompt Content": "Prompt-Inhalt",
|
||||
"Prompt created successfully": "",
|
||||
"Prompt created successfully": "Prompt erfolgreich erstellt",
|
||||
"Prompt suggestions": "Prompt-Vorschläge",
|
||||
"Prompt updated successfully": "",
|
||||
"Prompt updated successfully": "Prompt erfolgreich aktualisiert",
|
||||
"Prompts": "Prompts",
|
||||
"Prompts Access": "",
|
||||
"Prompts Access": "Prompt-Zugriff",
|
||||
"Pull \"{{searchValue}}\" from Ollama.com": "\"{{searchValue}}\" von Ollama.com beziehen",
|
||||
"Pull a model from Ollama.com": "Modell von Ollama.com beziehen",
|
||||
"Query Generation Prompt": "",
|
||||
"Query Generation Prompt": "Abfragegenerierungsprompt",
|
||||
"Query Params": "Abfrageparameter",
|
||||
"RAG Template": "RAG-Vorlage",
|
||||
"Rating": "Bewertung",
|
||||
@@ -683,7 +694,7 @@
|
||||
"Read Aloud": "Vorlesen",
|
||||
"Record voice": "Stimme aufnehmen",
|
||||
"Redirecting you to OpenWebUI Community": "Sie werden zur OpenWebUI-Community weitergeleitet",
|
||||
"Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative. (Default: 40)": "",
|
||||
"Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative. (Default: 40)": "Reduziert die Wahrscheinlichkeit, Unsinn zu generieren. Ein höherer Wert (z.B. 100) liefert vielfältigere Antworten, während ein niedrigerer Wert (z.B. 10) konservativer ist. (Standard: 40)",
|
||||
"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Beziehen Sie sich auf sich selbst als \"Benutzer\" (z. B. \"Benutzer lernt Spanisch\")",
|
||||
"References from": "Referenzen aus",
|
||||
"Refused when it shouldn't have": "Abgelehnt, obwohl es nicht hätte abgelehnt werden sollen",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Entfernen",
|
||||
"Remove Model": "Modell entfernen",
|
||||
"Rename": "Umbenennen",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Wiederhole die letzten N",
|
||||
"Request Mode": "Anforderungsmodus",
|
||||
"Reranking Model": "Reranking-Modell",
|
||||
"Reranking model disabled": "Reranking-Modell deaktiviert",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Reranking-Modell \"{{reranking_model}}\" fesgelegt",
|
||||
"Reset": "Zurücksetzen",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Upload-Verzeichnis zurücksetzen",
|
||||
"Reset Vector Storage/Knowledge": "Vektorspeicher/Wissen zurücksetzen",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Benachrichtigungen können nicht aktiviert werden, da die Website-Berechtigungen abgelehnt wurden. Bitte besuchen Sie Ihre Browser-Einstellungen, um den erforderlichen Zugriff zu gewähren.",
|
||||
@@ -722,18 +735,18 @@
|
||||
"Scroll to bottom when switching between branches": "Beim Wechsel zwischen Branches nach unten scrollen",
|
||||
"Search": "Suchen",
|
||||
"Search a model": "Modell suchen",
|
||||
"Search Base": "",
|
||||
"Search Base": "Suchbasis",
|
||||
"Search Chats": "Unterhaltungen durchsuchen...",
|
||||
"Search Collection": "Sammlung durchsuchen",
|
||||
"Search Filters": "",
|
||||
"Search Filters": "Suchfilter",
|
||||
"search for tags": "nach Tags suchen",
|
||||
"Search Functions": "Funktionen durchsuchen...",
|
||||
"Search Knowledge": "Wissen durchsuchen",
|
||||
"Search Models": "Modelle durchsuchen...",
|
||||
"Search options": "",
|
||||
"Search options": "Suchoptionen",
|
||||
"Search Prompts": "Prompts durchsuchen...",
|
||||
"Search Result Count": "Anzahl der Suchergebnisse",
|
||||
"Search the web": "",
|
||||
"Search the web": "Im Web suchen",
|
||||
"Search Tools": "Werkzeuge durchsuchen...",
|
||||
"SearchApi API Key": "SearchApi-API-Schlüssel",
|
||||
"SearchApi Engine": "SearchApi-Engine",
|
||||
@@ -748,7 +761,7 @@
|
||||
"Select a base model": "Wählen Sie ein Basismodell",
|
||||
"Select a engine": "Wählen Sie eine Engine",
|
||||
"Select a function": "Wählen Sie eine Funktion",
|
||||
"Select a group": "",
|
||||
"Select a group": "Wählen Sie eine Gruppe",
|
||||
"Select a model": "Wählen Sie ein Modell",
|
||||
"Select a pipeline": "Wählen Sie eine Pipeline",
|
||||
"Select a pipeline url": "Wählen Sie eine Pipeline-URL",
|
||||
@@ -771,7 +784,7 @@
|
||||
"Set as default": "Als Standard festlegen",
|
||||
"Set CFG Scale": "CFG-Skala festlegen",
|
||||
"Set Default Model": "Standardmodell festlegen",
|
||||
"Set embedding model": "",
|
||||
"Set embedding model": "Einbettungsmodell festlegen",
|
||||
"Set embedding model (e.g. {{model}})": "Einbettungsmodell festlegen (z. B. {{model}})",
|
||||
"Set Image Size": "Bildgröße festlegen",
|
||||
"Set reranking model (e.g. {{model}})": "Rerankingmodell festlegen (z. B. {{model}})",
|
||||
@@ -779,29 +792,29 @@
|
||||
"Set Scheduler": "Scheduler festlegen",
|
||||
"Set Steps": "Schrittgröße festlegen",
|
||||
"Set Task Model": "Aufgabenmodell festlegen",
|
||||
"Set the number of GPU devices used for computation. This option controls how many GPU devices (if available) are used to process incoming requests. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "",
|
||||
"Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "",
|
||||
"Set the number of GPU devices used for computation. This option controls how many GPU devices (if available) are used to process incoming requests. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Legt die Anzahl der für die Berechnung verwendeten GPU-Geräte fest. Diese Option steuert, wie viele GPU-Geräte (falls verfügbar) zur Verarbeitung eingehender Anfragen verwendet werden. Eine Erhöhung dieses Wertes kann die Leistung für Modelle, die für GPU-Beschleunigung optimiert sind, erheblich verbessern, kann jedoch auch mehr Strom und GPU-Ressourcen verbrauchen.",
|
||||
"Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Legt die Anzahl der für die Berechnung verwendeten GPU-Geräte fest. Diese Option steuert, wie viele GPU-Geräte (falls verfügbar) zur Verarbeitung eingehender Anfragen verwendet werden. Eine Erhöhung dieses Wertes kann die Leistung für Modelle, die für GPU-Beschleunigung optimiert sind, erheblich verbessern, kann jedoch auch mehr Strom und GPU-Ressourcen verbrauchen.",
|
||||
"Set Voice": "Stimme festlegen",
|
||||
"Set whisper model": "Whisper-Modell festlegen",
|
||||
"Sets how far back for the model to look back to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx)": "",
|
||||
"Sets how strongly to penalize repetitions. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. (Default: 1.1)": "",
|
||||
"Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt. (Default: random)": "",
|
||||
"Sets the size of the context window used to generate the next token. (Default: 2048)": "",
|
||||
"Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "",
|
||||
"Sets how far back for the model to look back to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx)": "Legt fest, wie weit das Modell zurückblicken soll, um Wiederholungen zu verhindern. (Standard: 64, 0 = deaktiviert, -1 = num_ctx)",
|
||||
"Sets how strongly to penalize repetitions. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. (Default: 1.1)": "Legt fest, wie stark Wiederholungen bestraft werden sollen. Ein höherer Wert (z.B. 1.5) bestraft Wiederholungen stärker, während ein niedrigerer Wert (z.B. 0.9) nachsichtiger ist. (Standard: 1.1)",
|
||||
"Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt. (Default: random)": "Legt den Zufallszahlengenerator-Seed für die Generierung fest. Wenn dieser auf eine bestimmte Zahl gesetzt wird, erzeugt das Modell denselben Text für denselben Prompt. (Standard: zufällig)",
|
||||
"Sets the size of the context window used to generate the next token. (Default: 2048)": "Legt die Größe des Kontextfensters fest, das zur Generierung des nächsten Tokens verwendet wird. (Standard: 2048)",
|
||||
"Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Legt die zu verwendenden Stoppsequenzen fest. Wenn dieses Muster erkannt wird, stoppt das LLM die Textgenerierung und gibt zurück. Mehrere Stoppmuster können festgelegt werden, indem mehrere separate Stopp-Parameter in einer Modelldatei angegeben werden.",
|
||||
"Settings": "Einstellungen",
|
||||
"Settings saved successfully!": "Einstellungen erfolgreich gespeichert!",
|
||||
"Share": "Teilen",
|
||||
"Share Chat": "Unterhaltung teilen",
|
||||
"Share to OpenWebUI Community": "Mit OpenWebUI Community teilen",
|
||||
"Show": "Anzeigen",
|
||||
"Show \"What's New\" modal on login": "",
|
||||
"Show \"What's New\" modal on login": "\"Was gibt's Neues\"-Modal beim Anmelden anzeigen",
|
||||
"Show Admin Details in Account Pending Overlay": "Admin-Details im Account-Pending-Overlay anzeigen",
|
||||
"Show shortcuts": "Verknüpfungen anzeigen",
|
||||
"Show your support!": "Zeigen Sie Ihre Unterstützung!",
|
||||
"Showcased creativity": "Kreativität gezeigt",
|
||||
"Sign in": "Anmelden",
|
||||
"Sign in to {{WEBUI_NAME}}": "Bei {{WEBUI_NAME}} anmelden",
|
||||
"Sign in to {{WEBUI_NAME}} with LDAP": "",
|
||||
"Sign in to {{WEBUI_NAME}} with LDAP": "Bei {{WEBUI_NAME}} mit LDAP anmelden",
|
||||
"Sign Out": "Abmelden",
|
||||
"Sign up": "Registrieren",
|
||||
"Sign up to {{WEBUI_NAME}}": "Bei {{WEBUI_NAME}} registrieren",
|
||||
@@ -826,7 +839,7 @@
|
||||
"System Instructions": "Systemanweisungen",
|
||||
"System Prompt": "System-Prompt",
|
||||
"Tags Generation Prompt": "Prompt für Tag-Generierung",
|
||||
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "",
|
||||
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "Tail-Free Sampling wird verwendet, um den Einfluss weniger wahrscheinlicher Tokens auf die Ausgabe zu reduzieren. Ein höherer Wert (z.B. 2.0) reduziert den Einfluss stärker, während ein Wert von 1.0 diese Einstellung deaktiviert. (Standard: 1)",
|
||||
"Tap to interrupt": "Zum Unterbrechen tippen",
|
||||
"Tavily API Key": "Tavily-API-Schlüssel",
|
||||
"Tell us more:": "Erzähl uns mehr",
|
||||
@@ -837,30 +850,30 @@
|
||||
"Text-to-Speech Engine": "Text-zu-Sprache-Engine",
|
||||
"Tfs Z": "Tfs Z",
|
||||
"Thanks for your feedback!": "Danke für Ihr Feedback!",
|
||||
"The Application Account DN you bind with for search": "",
|
||||
"The base to search for users": "",
|
||||
"The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory. (Default: 512)": "",
|
||||
"The Application Account DN you bind with for search": "Der Anwendungs-Konto-DN, mit dem Sie für die Suche binden",
|
||||
"The base to search for users": "Die Basis, in der nach Benutzern gesucht wird",
|
||||
"The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory. (Default: 512)": "Die Batch-Größe bestimmt, wie viele Textanfragen gleichzeitig verarbeitet werden. Eine größere Batch-Größe kann die Leistung und Geschwindigkeit des Modells erhöhen, erfordert jedoch auch mehr Speicher. (Standard: 512)",
|
||||
"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Die Entwickler hinter diesem Plugin sind leidenschaftliche Freiwillige aus der Community. Wenn Sie dieses Plugin hilfreich finden, erwägen Sie bitte, zu seiner Entwicklung beizutragen.",
|
||||
"The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "Die Bewertungs-Bestenliste basiert auf dem Elo-Bewertungssystem und wird in Echtzeit aktualisiert.",
|
||||
"The LDAP attribute that maps to the username that users use to sign in.": "",
|
||||
"The LDAP attribute that maps to the username that users use to sign in.": "Das LDAP-Attribut, das dem Benutzernamen zugeordnet ist, den Benutzer zum Anmelden verwenden.",
|
||||
"The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "Die Bestenliste befindet sich derzeit in der Beta-Phase, und es ist möglich, dass wir die Bewertungsberechnungen anpassen, während wir den Algorithmus verfeinern.",
|
||||
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Die maximale Dateigröße in MB. Wenn die Dateigröße dieses Limit überschreitet, wird die Datei nicht hochgeladen.",
|
||||
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "Die maximale Anzahl von Dateien, die gleichzeitig in der Unterhaltung verwendet werden können. Wenn die Anzahl der Dateien dieses Limit überschreitet, werden die Dateien nicht hochgeladen.",
|
||||
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Die Punktzahl sollte ein Wert zwischen 0,0 (0 %) und 1,0 (100 %) sein.",
|
||||
"The temperature of the model. Increasing the temperature will make the model answer more creatively. (Default: 0.8)": "",
|
||||
"The temperature of the model. Increasing the temperature will make the model answer more creatively. (Default: 0.8)": "Die Temperatur des Modells. Eine Erhöhung der Temperatur führt dazu, dass das Modell kreativer antwortet. (Standard: 0,8)",
|
||||
"Theme": "Design",
|
||||
"Thinking...": "Denke nach...",
|
||||
"This action cannot be undone. Do you wish to continue?": "Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie fortfahren?",
|
||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Dies stellt sicher, dass Ihre wertvollen Unterhaltungen sicher in Ihrer Backend-Datenbank gespeichert werden. Vielen Dank!",
|
||||
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Dies ist eine experimentelle Funktion, sie funktioniert möglicherweise nicht wie erwartet und kann jederzeit geändert werden.",
|
||||
"This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics. (Default: 24)": "",
|
||||
"This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated. (Default: 128)": "",
|
||||
"This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics. (Default: 24)": "Diese Option steuert, wie viele Tokens beim Aktualisieren des Kontexts beibehalten werden. Wenn sie beispielsweise auf 2 gesetzt ist, werden die letzten 2 Tokens des Gesprächskontexts beibehalten. Das Beibehalten des Kontexts kann helfen, die Kontinuität eines Gesprächs aufrechtzuerhalten, kann jedoch die Fähigkeit verringern, auf neue Themen zu reagieren. (Standard: 24)",
|
||||
"This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated. (Default: 128)": "Diese Option legt die maximale Anzahl von Tokens fest, die das Modell in seiner Antwort generieren kann. Eine Erhöhung dieses Limits ermöglicht es dem Modell, längere Antworten zu geben, kann jedoch auch die Wahrscheinlichkeit erhöhen, dass unhilfreicher oder irrelevanter Inhalt generiert wird. (Standard: 128)",
|
||||
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "Diese Option löscht alle vorhandenen Dateien in der Sammlung und ersetzt sie durch neu hochgeladene Dateien.",
|
||||
"This response was generated by \"{{model}}\"": "Diese Antwort wurde von \"{{model}}\" generiert",
|
||||
"This will delete": "Dies löscht",
|
||||
"This will delete <strong>{{NAME}}</strong> and <strong>all its contents</strong>.": "Dies löscht <strong>{{NAME}}</strong> und <strong>alle Inhalte</strong>.",
|
||||
"This will delete all models including custom models": "",
|
||||
"This will delete all models including custom models and cannot be undone.": "",
|
||||
"This will delete all models including custom models": "Dies wird alle Modelle einschließlich benutzerdefinierter Modelle löschen",
|
||||
"This will delete all models including custom models and cannot be undone.": "Dies wird alle Modelle einschließlich benutzerdefinierter Modelle löschen und kann nicht rückgängig gemacht werden.",
|
||||
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Dadurch wird die Wissensdatenbank zurückgesetzt und alle Dateien synchronisiert. Möchten Sie fortfahren?",
|
||||
"Thorough explanation": "Ausführliche Erklärung",
|
||||
"Tika": "Tika",
|
||||
@@ -872,7 +885,7 @@
|
||||
"Title Auto-Generation": "Unterhaltungstitel automatisch generieren",
|
||||
"Title cannot be an empty string.": "Titel darf nicht leer sein.",
|
||||
"Title Generation Prompt": "Prompt für Titelgenerierung",
|
||||
"TLS": "",
|
||||
"TLS": "TLS",
|
||||
"To access the available model names for downloading,": "Um auf die verfügbaren Modellnamen zuzugreifen,",
|
||||
"To access the GGUF models available for downloading,": "Um auf die verfügbaren GGUF-Modelle zuzugreifen,",
|
||||
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Um auf das WebUI zugreifen zu können, wenden Sie sich bitte an einen Administrator. Administratoren können den Benutzerstatus über das Admin-Panel verwalten.",
|
||||
@@ -890,19 +903,19 @@
|
||||
"Too verbose": "Zu ausführlich",
|
||||
"Tool created successfully": "Werkzeug erfolgreich erstellt",
|
||||
"Tool deleted successfully": "Werkzeug erfolgreich gelöscht",
|
||||
"Tool Description": "",
|
||||
"Tool ID": "",
|
||||
"Tool Description": "Werkzeugbeschreibung",
|
||||
"Tool ID": "Werkzeug-ID",
|
||||
"Tool imported successfully": "Werkzeug erfolgreich importiert",
|
||||
"Tool Name": "",
|
||||
"Tool Name": "Werkzeugname",
|
||||
"Tool updated successfully": "Werkzeug erfolgreich aktualisiert",
|
||||
"Tools": "Werkzeuge",
|
||||
"Tools Access": "",
|
||||
"Tools Access": "Werkzeugzugriff",
|
||||
"Tools are a function calling system with arbitrary code execution": "Wekzeuge sind ein Funktionssystem mit beliebiger Codeausführung",
|
||||
"Tools have a function calling system that allows arbitrary code execution": "Werkezuge verfügen über ein Funktionssystem, das die Ausführung beliebigen Codes ermöglicht",
|
||||
"Tools have a function calling system that allows arbitrary code execution.": "Werkzeuge verfügen über ein Funktionssystem, das die Ausführung beliebigen Codes ermöglicht.",
|
||||
"Top K": "Top K",
|
||||
"Top P": "Top P",
|
||||
"Transformers": "",
|
||||
"Transformers": "Transformers",
|
||||
"Trouble accessing Ollama?": "Probleme beim Zugriff auf Ollama?",
|
||||
"TTS Model": "TTS-Modell",
|
||||
"TTS Settings": "TTS-Einstellungen",
|
||||
@@ -911,12 +924,12 @@
|
||||
"Type Hugging Face Resolve (Download) URL": "Geben Sie die Hugging Face Resolve-URL ein",
|
||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Ups! Es gab ein Problem bei der Verbindung mit {{provider}}.",
|
||||
"UI": "Oberfläche",
|
||||
"Unarchive All": "",
|
||||
"Unarchive All Archived Chats": "",
|
||||
"Unarchive Chat": "",
|
||||
"Unlock mysteries": "",
|
||||
"Unarchive All": "Alle wiederherstellen",
|
||||
"Unarchive All Archived Chats": "Alle archivierten Unterhaltungen wiederherstellen",
|
||||
"Unarchive Chat": "Unterhaltung wiederherstellen",
|
||||
"Unlock mysteries": "Geheimnisse entsperren",
|
||||
"Unpin": "Lösen",
|
||||
"Unravel secrets": "",
|
||||
"Unravel secrets": "Geheimnisse lüften",
|
||||
"Untagged": "Ungetaggt",
|
||||
"Update": "Aktualisieren",
|
||||
"Update and Copy Link": "Aktualisieren und Link kopieren",
|
||||
@@ -932,18 +945,18 @@
|
||||
"Upload Files": "Datei(en) hochladen",
|
||||
"Upload Pipeline": "Pipeline hochladen",
|
||||
"Upload Progress": "Hochladefortschritt",
|
||||
"URL": "",
|
||||
"URL": "URL",
|
||||
"URL Mode": "URL-Modus",
|
||||
"Use '#' in the prompt input to load and include your knowledge.": "Nutzen Sie '#' in der Prompt-Eingabe, um Ihr Wissen zu laden und einzuschließen.",
|
||||
"Use Gravatar": "Gravatar verwenden",
|
||||
"Use groups to group your users and assign permissions.": "",
|
||||
"Use groups to group your users and assign permissions.": "Nutzen Sie Gruppen, um Ihre Benutzer zu gruppieren und Berechtigungen zuzuweisen.",
|
||||
"Use Initials": "Initialen verwenden",
|
||||
"use_mlock (Ollama)": "use_mlock (Ollama)",
|
||||
"use_mmap (Ollama)": "use_mmap (Ollama)",
|
||||
"user": "Benutzer",
|
||||
"User": "Benutzer",
|
||||
"User location successfully retrieved.": "Benutzerstandort erfolgreich ermittelt.",
|
||||
"Username": "",
|
||||
"Username": "Benutzername",
|
||||
"Users": "Benutzer",
|
||||
"Using the default arena model with all models. Click the plus button to add custom models.": "Verwendung des Standard-Arena-Modells mit allen Modellen. Klicken Sie auf die Plus-Schaltfläche, um benutzerdefinierte Modelle hinzuzufügen.",
|
||||
"Utilize": "Verwende",
|
||||
@@ -955,12 +968,12 @@
|
||||
"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
|
||||
"Version": "Version",
|
||||
"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} von {{totalVersions}}",
|
||||
"Visibility": "",
|
||||
"Visibility": "Sichtbarkeit",
|
||||
"Voice": "Stimme",
|
||||
"Voice Input": "Spracheingabe",
|
||||
"Warning": "Warnung",
|
||||
"Warning:": "Warnung:",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "Warnung: Wenn Sie dies aktivieren, können Benutzer beliebigen Code auf dem Server hochladen.",
|
||||
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Warnung: Wenn Sie das Einbettungsmodell aktualisieren oder ändern, müssen Sie alle Dokumente erneut importieren.",
|
||||
"Web": "Web",
|
||||
"Web API": "Web-API",
|
||||
@@ -969,29 +982,30 @@
|
||||
"Web Search Engine": "Suchmaschine",
|
||||
"Webhook URL": "Webhook URL",
|
||||
"WebUI Settings": "WebUI-Einstellungen",
|
||||
"WebUI will make requests to \"{{url}}/api/chat\"": "",
|
||||
"WebUI will make requests to \"{{url}}/chat/completions\"": "",
|
||||
"What are you trying to achieve?": "",
|
||||
"What are you working on?": "",
|
||||
"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI wird Anfragen an \"{{url}}/api/chat\" senden",
|
||||
"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI wird Anfragen an \"{{url}}/chat/completions\" senden",
|
||||
"What are you trying to achieve?": "Was versuchen Sie zu erreichen?",
|
||||
"What are you working on?": "Woran arbeiten Sie?",
|
||||
"What’s New in": "Neuigkeiten von",
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Wenn aktiviert, antwortet das Modell in Echtzeit auf jede Chat-Nachricht und generiert eine Antwort, sobald der Benutzer eine Nachricht sendet. Dieser Modus ist nützlich für Live-Chat-Anwendungen, kann jedoch die Leistung auf langsamerer Hardware beeinträchtigen.",
|
||||
"wherever you are": "wo immer Sie sind",
|
||||
"Whisper (Local)": "Whisper (lokal)",
|
||||
"Why?": "Warum?",
|
||||
"Widescreen Mode": "Breitbildmodus",
|
||||
"Won": "Gewonnen",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "Funktioniert zusammen mit top-k. Ein höherer Wert (z.B. 0,95) führt zu vielfältigerem Text, während ein niedrigerer Wert (z.B. 0,5) fokussierteren und konservativeren Text erzeugt. (Standard: 0,9)",
|
||||
"Workspace": "Arbeitsbereich",
|
||||
"Workspace Permissions": "",
|
||||
"Workspace Permissions": "Arbeitsbereichsberechtigungen",
|
||||
"Write a prompt suggestion (e.g. Who are you?)": "Schreiben Sie einen Promptvorschlag (z. B. Wer sind Sie?)",
|
||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Schreibe eine kurze Zusammenfassung in 50 Wörtern, die [Thema oder Schlüsselwort] zusammenfasst.",
|
||||
"Write something...": "Schreiben Sie etwas...",
|
||||
"Write your model template content here": "",
|
||||
"Write your model template content here": "Schreiben Sie hier Ihren Modellvorlageninhalt",
|
||||
"Yesterday": "Gestern",
|
||||
"You": "Sie",
|
||||
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Sie können nur mit maximal {{maxCount}} Datei(en) gleichzeitig chatten.",
|
||||
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Personalisieren Sie Interaktionen mit LLMs, indem Sie über die Schaltfläche \"Verwalten\" Erinnerungen hinzufügen.",
|
||||
"You cannot upload an empty file.": "Sie können keine leere Datei hochladen.",
|
||||
"You do not have permission to upload files.": "",
|
||||
"You do not have permission to upload files.": "Sie haben keine Berechtigung zum Hochladen von Dateien.",
|
||||
"You have no archived conversations.": "Du hast keine archivierten Unterhaltungen.",
|
||||
"You have shared this chat": "Sie haben diese Unterhaltung geteilt",
|
||||
"You're a helpful assistant.": "Du bist ein hilfreicher Assistent.",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Such account exists?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "such assistant",
|
||||
"and": "and",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 Base URL is required.",
|
||||
"Available list": "",
|
||||
"available!": "available! So excite!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Back",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Confirm Password",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "",
|
||||
"Default Model": "",
|
||||
"Default model updated": "Default model much updated",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Default Prompt Suggestions",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "",
|
||||
"Deleted {{deleteModelTag}}": "Deleted {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Enter model doge tag (e.g. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Enter Number of Steps (e.g. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "",
|
||||
"Failed to read clipboard contents": "Failed to read clipboard borks",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Hide",
|
||||
"Host": "",
|
||||
"How can I help you today?": "How can I halp u today?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Modelfile Content",
|
||||
"Models": "Wowdels",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "",
|
||||
"Name": "Name",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "",
|
||||
"No search query generated": "",
|
||||
"No source available": "No source available",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "",
|
||||
"Remove Model": "",
|
||||
"Rename": "",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Repeat Last N",
|
||||
"Request Mode": "Request Bark",
|
||||
"Reranking Model": "",
|
||||
"Reranking model disabled": "",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -979,6 +992,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "",
|
||||
"and": "",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "",
|
||||
"Available list": "",
|
||||
"available!": "",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "",
|
||||
"Default Model": "",
|
||||
"Default model updated": "",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "",
|
||||
"Deleted {{deleteModelTag}}": "",
|
||||
"Deleted {{name}}": "",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "",
|
||||
"Didn't fully follow instructions": "",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "",
|
||||
"Failed to read clipboard contents": "",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "",
|
||||
"Host": "",
|
||||
"How can I help you today?": "",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "",
|
||||
"Models": "",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "",
|
||||
"Name": "",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "",
|
||||
"No search query generated": "",
|
||||
"No source available": "",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "",
|
||||
"Remove Model": "",
|
||||
"Rename": "",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "",
|
||||
"Request Mode": "",
|
||||
"Reranking Model": "",
|
||||
"Reranking model disabled": "",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "",
|
||||
"and": "",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "",
|
||||
"Available list": "",
|
||||
"available!": "",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "",
|
||||
"Default Model": "",
|
||||
"Default model updated": "",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "",
|
||||
"Deleted {{deleteModelTag}}": "",
|
||||
"Deleted {{name}}": "",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "",
|
||||
"Didn't fully follow instructions": "",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "",
|
||||
"Failed to read clipboard contents": "",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "",
|
||||
"Host": "",
|
||||
"How can I help you today?": "",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "",
|
||||
"Models": "",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "",
|
||||
"Name": "",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "",
|
||||
"No search query generated": "",
|
||||
"No source available": "",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "",
|
||||
"Remove Model": "",
|
||||
"Rename": "",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "",
|
||||
"Request Mode": "",
|
||||
"Reranking Model": "",
|
||||
"Reranking model disabled": "",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Permitir interrupción de voz en llamada",
|
||||
"Already have an account?": "¿Ya tienes una cuenta?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "un asistente",
|
||||
"and": "y",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "La dirección URL de AUTOMATIC1111 es requerida.",
|
||||
"Available list": "Lista disponible",
|
||||
"available!": "¡disponible!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "Región de Azure",
|
||||
"Back": "Volver",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Solicitudes simultáneas",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Confirmar",
|
||||
"Confirm Password": "Confirmar Contraseña",
|
||||
"Confirm your action": "Confirma tu acción",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Predeterminado (SentenceTransformers)",
|
||||
"Default Model": "Modelo predeterminado",
|
||||
"Default model updated": "El modelo por defecto ha sido actualizado",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Sugerencias de mensajes por defecto",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Borrar Usuario",
|
||||
"Deleted {{deleteModelTag}}": "Se borró {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Eliminado {{nombre}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Descripción",
|
||||
"Didn't fully follow instructions": "No siguió las instrucciones",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Ingrese códigos de idioma",
|
||||
"Enter Model ID": "Ingresa el ID del modelo",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Ingrese la etiqueta del modelo (p.ej. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Ingrese el número de pasos (p.ej., 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Ingrese el sampler (p.ej., Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Ingrese el planificador (p.ej., Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "No se pudo crear la clave API.",
|
||||
"Failed to read clipboard contents": "No se pudo leer el contenido del portapapeles",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Falla al actualizar los ajustes",
|
||||
"Failed to upload file.": "Falla al subir el archivo.",
|
||||
"February": "Febrero",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Esconder",
|
||||
"Host": "",
|
||||
"How can I help you today?": "¿Cómo puedo ayudarte hoy?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Búsqueda Híbrida",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Aseguro que he leído y entiendo las implicaciones de mi acción. Estoy consciente de los riesgos asociados con la ejecución de código arbitrario y he verificado la confianza de la fuente.",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Contenido del Modelfile",
|
||||
"Models": "Modelos",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Más",
|
||||
"Name": "Nombre",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "No se encontró ningún conocimiento",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "No se han encontrado resultados",
|
||||
"No search query generated": "No se ha generado ninguna consulta de búsqueda",
|
||||
"No source available": "No hay fuente disponible",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Eliminar",
|
||||
"Remove Model": "Eliminar modelo",
|
||||
"Rename": "Renombrar",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Repetir las últimas N",
|
||||
"Request Mode": "Modo de petición",
|
||||
"Reranking Model": "Modelo de reranking",
|
||||
"Reranking model disabled": "Modelo de reranking deshabilitado",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Modelo de reranking establecido en \"{{reranking_model}}\"",
|
||||
"Reset": "Reiniciar",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Reiniciar Directorio de carga",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Las notificaciones de respuesta no pueden activarse debido a que los permisos del sitio web han sido denegados. Por favor, visite las configuraciones de su navegador para otorgar el acceso necesario.",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (Local)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Modo de pantalla ancha",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "از قبل حساب کاربری دارید؟",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "یک دستیار",
|
||||
"and": "و",
|
||||
"and {{COUNT}} more": "و {{COUNT}} مورد دیگر",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "به URL پایه AUTOMATIC1111 مورد نیاز است.",
|
||||
"Available list": "فهرست دردسترس",
|
||||
"available!": "در دسترس!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "سخنگوی هوش\u200cمصنوعی Azure",
|
||||
"Azure Region": "منطقهٔ Azure",
|
||||
"Back": "بازگشت",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "درخواست های همزمان",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "تایید",
|
||||
"Confirm Password": "تایید رمز عبور",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "پیشفرض (SentenceTransformers)",
|
||||
"Default Model": "مدل پیشفرض",
|
||||
"Default model updated": "مدل پیشفرض به\u200cروزرسانی شد",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "پیشنهادات پرامپت پیش فرض",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "حذف کاربر",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} پاک شد",
|
||||
"Deleted {{name}}": "حذف شده {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "توضیحات",
|
||||
"Didn't fully follow instructions": "نمی تواند دستورالعمل را کامل پیگیری کند",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "کد زبان را وارد کنید",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "تگ مدل را وارد کنید (مثلا {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "تعداد گام ها را وارد کنید (مثال: 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "خطا در افزودن پرونده",
|
||||
"Failed to create API Key.": "ایجاد کلید API با خطا مواجه شد.",
|
||||
"Failed to read clipboard contents": "خواندن محتوای کلیپ بورد ناموفق بود",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "خطا در به\u200cروزرسانی تنظیمات",
|
||||
"Failed to upload file.": "خطا در بارگذاری پرونده",
|
||||
"February": "فوریه",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "پنهان\u200cسازی",
|
||||
"Host": "",
|
||||
"How can I help you today?": "امروز چطور می توانم کمک تان کنم؟",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "جستجوی همزمان",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "محتویات فایل مدل",
|
||||
"Models": "مدل\u200cها",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "بیشتر",
|
||||
"Name": "نام",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "نتیجه\u200cای یافت نشد",
|
||||
"No search query generated": "پرسوجوی جستجویی ایجاد نشده است",
|
||||
"No source available": "منبعی در دسترس نیست",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "حذف",
|
||||
"Remove Model": "حذف مدل",
|
||||
"Rename": "تغییر نام",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Repeat Last N",
|
||||
"Request Mode": "حالت درخواست",
|
||||
"Reranking Model": "مدل ری\u200cشناسی مجدد غیرفعال است",
|
||||
"Reranking model disabled": "مدل ری\u200cشناسی مجدد غیرفعال است",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "مدل ری\u200cشناسی مجدد به \"{{reranking_model}}\" تنظیم شده است",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "حالت صفحهٔ عریض",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Onko sinulla jo tili?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "avustaja",
|
||||
"and": "ja",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111-perus-URL vaaditaan.",
|
||||
"Available list": "",
|
||||
"available!": "saatavilla!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Takaisin",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Samanaikaiset pyynnöt",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Vahvista salasana",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Oletus (SentenceTransformers)",
|
||||
"Default Model": "Oletusmalli",
|
||||
"Default model updated": "Oletusmalli päivitetty",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Oletuskehotteiden ehdotukset",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Poista käyttäjä",
|
||||
"Deleted {{deleteModelTag}}": "Poistettu {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Poistettu {{nimi}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Kuvaus",
|
||||
"Didn't fully follow instructions": "Ei noudattanut ohjeita täysin",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Syötä kielikoodit",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Syötä mallitagi (esim. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Syötä askelien määrä (esim. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "API-avaimen luonti epäonnistui.",
|
||||
"Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "helmikuu",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Piilota",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Kuinka voin auttaa tänään?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hybridihaku",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Mallitiedoston sisältö",
|
||||
"Models": "Mallit",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Lisää",
|
||||
"Name": "Nimi",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Ei tuloksia",
|
||||
"No search query generated": "Hakukyselyä ei luotu",
|
||||
"No source available": "Ei lähdettä saatavilla",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Poista",
|
||||
"Remove Model": "Poista malli",
|
||||
"Rename": "Nimeä uudelleen",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Viimeinen N -toisto",
|
||||
"Request Mode": "Pyyntötila",
|
||||
"Reranking Model": "Uudelleenpisteytysmalli",
|
||||
"Reranking model disabled": "Uudelleenpisteytysmalli poistettu käytöstä",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "\"{{reranking_model}}\" valittu uudelleenpisteytysmalliksi",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Autoriser l'interruption vocale pendant un appel",
|
||||
"Already have an account?": "Avez-vous déjà un compte ?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "un assistant",
|
||||
"and": "et",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "L'URL de base {AUTOMATIC1111} est requise.",
|
||||
"Available list": "",
|
||||
"available!": "disponible !",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Retour en arrière",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Demandes concurrentes",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Confirmer",
|
||||
"Confirm Password": "Confirmer le mot de passe",
|
||||
"Confirm your action": "Confirmez votre action",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Par défaut (Sentence Transformers)",
|
||||
"Default Model": "Modèle standard",
|
||||
"Default model updated": "Modèle par défaut mis à jour",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Suggestions de prompts par défaut",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Supprimer le compte d'utilisateur",
|
||||
"Deleted {{deleteModelTag}}": "Supprimé {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Supprimé {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "N'a pas entièrement respecté les instructions",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Entrez les codes de langue",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Entrez l'étiquette du modèle (par ex. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Entrez le nombre de pas (par ex. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Échec de la création de la clé API.",
|
||||
"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Échec de la mise à jour des paramètres",
|
||||
"Failed to upload file.": "",
|
||||
"February": "Février",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Cacher",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Comment puis-je vous être utile aujourd'hui ?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Recherche hybride",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Contenu du Fichier de Modèle",
|
||||
"Models": "Modèles",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Plus de",
|
||||
"Name": "Nom",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Aucun résultat trouvé",
|
||||
"No search query generated": "Aucune requête de recherche générée",
|
||||
"No source available": "Aucune source n'est disponible",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Retirer",
|
||||
"Remove Model": "Retirer le modèle",
|
||||
"Rename": "Renommer",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Répéter les N derniers",
|
||||
"Request Mode": "Mode de Requête",
|
||||
"Reranking Model": "Modèle de ré-ranking",
|
||||
"Reranking model disabled": "Modèle de ré-ranking désactivé",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Modèle de ré-ranking défini sur « {{reranking_model}} »",
|
||||
"Reset": "Réinitialiser",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Répertoire de téléchargement réinitialisé",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez visiter les paramètres de votre navigateur pour accorder l'accès nécessaire.",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (local)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Mode Grand Écran",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Autoriser l'interruption vocale pendant un appel",
|
||||
"Already have an account?": "Avez-vous déjà un compte ?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "un assistant",
|
||||
"and": "et",
|
||||
"and {{COUNT}} more": "et {{COUNT}} autres",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "L'URL de base {AUTOMATIC1111} est requise.",
|
||||
"Available list": "Liste disponible",
|
||||
"available!": "disponible !",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "Azure AI Speech",
|
||||
"Azure Region": "Région Azure",
|
||||
"Back": "Retour en arrière",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "Complétions",
|
||||
"Concurrent Requests": "Demandes concurrentes",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Confirmer",
|
||||
"Confirm Password": "Confirmer le mot de passe",
|
||||
"Confirm your action": "Confirmer votre action",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Par défaut (Sentence Transformers)",
|
||||
"Default Model": "Modèle standard",
|
||||
"Default model updated": "Modèle par défaut mis à jour",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Suggestions de prompts par défaut",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Supprimer le compte d'utilisateur",
|
||||
"Deleted {{deleteModelTag}}": "Supprimé {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Supprimé {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Description",
|
||||
"Didn't fully follow instructions": "N'a pas entièrement respecté les instructions",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Entrez les codes de langue",
|
||||
"Enter Model ID": "Entrez l'ID du modèle",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Entrez le tag du modèle (par ex. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Entrez le nombre d'étapes (par ex. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Entrez le sampler (par ex. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Entrez le planificateur (par ex. Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "Échec de l'ajout du fichier.",
|
||||
"Failed to create API Key.": "Échec de la création de la clé API.",
|
||||
"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Échec de la mise à jour des paramètres",
|
||||
"Failed to upload file.": "Échec du téléchargement du fichier.",
|
||||
"February": "Février",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Cacher",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Comment puis-je vous aider aujourd'hui ?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Recherche hybride",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Je reconnais avoir lu et compris les implications de mes actions. Je suis conscient des risques associés à l'exécution d'un code arbitraire et j'ai vérifié la fiabilité de la source.",
|
||||
"ID": "ID",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Contenu du Fichier de Modèle",
|
||||
"Models": "Modèles",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "plus",
|
||||
"More": "Plus",
|
||||
"Name": "Nom d'utilisateur",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "Aucune connaissance trouvée",
|
||||
"No model IDs": "",
|
||||
"No models found": "Aucun modèle trouvé",
|
||||
"No models selected": "",
|
||||
"No results found": "Aucun résultat trouvé",
|
||||
"No search query generated": "Aucune requête de recherche générée",
|
||||
"No source available": "Aucune source n'est disponible",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Retirer",
|
||||
"Remove Model": "Retirer le modèle",
|
||||
"Rename": "Renommer",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Répéter les N derniers",
|
||||
"Request Mode": "Mode de requête",
|
||||
"Reranking Model": "Modèle de ré-ranking",
|
||||
"Reranking model disabled": "Modèle de ré-ranking désactivé",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Modèle de ré-ranking défini sur « {{reranking_model}} »",
|
||||
"Reset": "Réinitialiser",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Réinitialiser le répertoire de téléchargement",
|
||||
"Reset Vector Storage/Knowledge": "Réinitialiser le stockage vectoriel/connaissances",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez vérifier les paramètres de votre navigateur pour accorder l'accès nécessaire.",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (local)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Mode grand écran",
|
||||
"Won": "Gagné",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "כבר יש לך חשבון?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "עוזר",
|
||||
"and": "וגם",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "נדרשת כתובת URL בסיסית של AUTOMATIC1111",
|
||||
"Available list": "",
|
||||
"available!": "זמין!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "חזור",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "בקשות בו-זמניות",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "אשר סיסמה",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "ברירת מחדל (SentenceTransformers)",
|
||||
"Default Model": "מודל ברירת מחדל",
|
||||
"Default model updated": "המודל המוגדר כברירת מחדל עודכן",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "הצעות ברירת מחדל לפקודות",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "מחק משתמש",
|
||||
"Deleted {{deleteModelTag}}": "נמחק {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "נמחק {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "תיאור",
|
||||
"Didn't fully follow instructions": "לא עקב אחרי ההוראות באופן מלא",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "הזן קודי שפה",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "הזן תג מודל (למשל {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "הזן מספר שלבים (למשל 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "יצירת מפתח API נכשלה.",
|
||||
"Failed to read clipboard contents": "קריאת תוכן הלוח נכשלה",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "פברואר",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "הסתר",
|
||||
"Host": "",
|
||||
"How can I help you today?": "כיצד אוכל לעזור לך היום?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "חיפוש היברידי",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "תוכן קובץ מודל",
|
||||
"Models": "מודלים",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "עוד",
|
||||
"Name": "שם",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "לא נמצאו תוצאות",
|
||||
"No search query generated": "לא נוצרה שאילתת חיפוש",
|
||||
"No source available": "אין מקור זמין",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "הסר",
|
||||
"Remove Model": "הסר מודל",
|
||||
"Rename": "שנה שם",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "חזור על ה-N האחרונים",
|
||||
"Request Mode": "מצב בקשה",
|
||||
"Reranking Model": "מודל דירוג מחדש",
|
||||
"Reranking model disabled": "מודל דירוג מחדש מושבת",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "מודל דירוג מחדש הוגדר ל-\"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "क्या आपके पास पहले से एक खाता मौजूद है?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "एक सहायक",
|
||||
"and": "और",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 का बेस यूआरएल आवश्यक है।",
|
||||
"Available list": "",
|
||||
"available!": "उपलब्ध!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "पीछे",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "समवर्ती अनुरोध",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "पासवर्ड की पुष्टि कीजिये",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "डिफ़ॉल्ट (SentenceTransformers)",
|
||||
"Default Model": "डिफ़ॉल्ट मॉडल",
|
||||
"Default model updated": "डिफ़ॉल्ट मॉडल अपडेट किया गया",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "डिफ़ॉल्ट प्रॉम्प्ट सुझाव",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "उपभोक्ता मिटायें",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} हटा दिया गया",
|
||||
"Deleted {{name}}": "{{name}} हटा दिया गया",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "विवरण",
|
||||
"Didn't fully follow instructions": "निर्देशों का पूरी तरह से पालन नहीं किया",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "भाषा कोड दर्ज करें",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Model tag दर्ज करें (उदा. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "चरणों की संख्या दर्ज करें (उदा. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "एपीआई कुंजी बनाने में विफल.",
|
||||
"Failed to read clipboard contents": "क्लिपबोर्ड सामग्री पढ़ने में विफल",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "फरवरी",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "छुपाएं",
|
||||
"Host": "",
|
||||
"How can I help you today?": "आज मैं आपकी कैसे मदद कर सकता हूँ?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "हाइब्रिड खोज",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "मॉडल फ़ाइल सामग्री",
|
||||
"Models": "सभी मॉडल",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "और..",
|
||||
"Name": "नाम",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "कोई परिणाम नहीं मिला",
|
||||
"No search query generated": "कोई खोज क्वेरी जनरेट नहीं हुई",
|
||||
"No source available": "कोई स्रोत उपलब्ध नहीं है",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "हटा दें",
|
||||
"Remove Model": "मोडेल हटाएँ",
|
||||
"Rename": "नाम बदलें",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "अंतिम N दोहराएँ",
|
||||
"Request Mode": "अनुरोध मोड",
|
||||
"Reranking Model": "रीरैकिंग मोड",
|
||||
"Reranking model disabled": "पुनर्रैंकिंग मॉडल अक्षम किया गया",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "रीरैंकिंग मॉडल को \"{{reranking_model}}\" पर \u200b\u200bसेट किया गया",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Već imate račun?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "asistent",
|
||||
"and": "i",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "Potreban je AUTOMATIC1111 osnovni URL.",
|
||||
"Available list": "",
|
||||
"available!": "dostupno!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Natrag",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Istodobni zahtjevi",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Potvrdite lozinku",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Zadano (SentenceTransformers)",
|
||||
"Default Model": "Zadani model",
|
||||
"Default model updated": "Zadani model ažuriran",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Zadani prijedlozi prompta",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Izbriši korisnika",
|
||||
"Deleted {{deleteModelTag}}": "Izbrisan {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Izbrisano {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Opis",
|
||||
"Didn't fully follow instructions": "Nije u potpunosti slijedio upute",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Unesite kodove jezika",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Unesite oznaku modela (npr. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Unesite broj koraka (npr. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Neuspješno stvaranje API ključa.",
|
||||
"Failed to read clipboard contents": "Neuspješno čitanje sadržaja međuspremnika",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Greška kod ažuriranja postavki",
|
||||
"Failed to upload file.": "",
|
||||
"February": "Veljača",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Sakrij",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Kako vam mogu pomoći danas?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hibridna pretraga",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Sadržaj datoteke modela",
|
||||
"Models": "Modeli",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Više",
|
||||
"Name": "Ime",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Nema rezultata",
|
||||
"No search query generated": "Nije generiran upit za pretraživanje",
|
||||
"No source available": "Nema dostupnog izvora",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Ukloni",
|
||||
"Remove Model": "Ukloni model",
|
||||
"Rename": "Preimenuj",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Ponovi zadnjih N",
|
||||
"Request Mode": "Način zahtjeva",
|
||||
"Reranking Model": "Model za ponovno rangiranje",
|
||||
"Reranking model disabled": "Model za ponovno rangiranje onemogućen",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Model za ponovno rangiranje postavljen na \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Poništi upload direktorij",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (lokalno)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Mod širokog zaslona",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Hang megszakítás engedélyezése hívás közben",
|
||||
"Already have an account?": "Már van fiókod?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "egy asszisztens",
|
||||
"and": "és",
|
||||
"and {{COUNT}} more": "és még {{COUNT}} db",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 alap URL szükséges.",
|
||||
"Available list": "Elérhető lista",
|
||||
"available!": "elérhető!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "Azure AI beszéd",
|
||||
"Azure Region": "Azure régió",
|
||||
"Back": "Vissza",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "Kiegészítések",
|
||||
"Concurrent Requests": "Párhuzamos kérések",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Megerősítés",
|
||||
"Confirm Password": "Jelszó megerősítése",
|
||||
"Confirm your action": "Erősítsd meg a műveletet",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Alapértelmezett (SentenceTransformers)",
|
||||
"Default Model": "Alapértelmezett modell",
|
||||
"Default model updated": "Alapértelmezett modell frissítve",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Alapértelmezett prompt javaslatok",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Felhasználó törlése",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} törölve",
|
||||
"Deleted {{name}}": "{{name}} törölve",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Leírás",
|
||||
"Didn't fully follow instructions": "Nem követte teljesen az utasításokat",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Add meg a nyelvi kódokat",
|
||||
"Enter Model ID": "Add meg a modell azonosítót",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Add meg a modell címkét (pl. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Add meg a lépések számát (pl. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Add meg a mintavételezőt (pl. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Add meg az ütemezőt (pl. Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "Nem sikerült hozzáadni a fájlt.",
|
||||
"Failed to create API Key.": "Nem sikerült létrehozni az API kulcsot.",
|
||||
"Failed to read clipboard contents": "Nem sikerült olvasni a vágólap tartalmát",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Nem sikerült frissíteni a beállításokat",
|
||||
"Failed to upload file.": "Nem sikerült feltölteni a fájlt.",
|
||||
"February": "Február",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Elrejtés",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Hogyan segíthetek ma?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Hibrid keresés",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Elismerem, hogy elolvastam és megértem a cselekedetem következményeit. Tisztában vagyok a tetszőleges kód végrehajtásával járó kockázatokkal, és ellenőriztem a forrás megbízhatóságát.",
|
||||
"ID": "Azonosító",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Modellfájl tartalom",
|
||||
"Models": "Modellek",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "több",
|
||||
"More": "Több",
|
||||
"Name": "Név",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "Nem található tudásbázis",
|
||||
"No model IDs": "",
|
||||
"No models found": "Nem található modell",
|
||||
"No models selected": "",
|
||||
"No results found": "Nincs találat",
|
||||
"No search query generated": "Nem generálódott keresési lekérdezés",
|
||||
"No source available": "Nincs elérhető forrás",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Eltávolítás",
|
||||
"Remove Model": "Modell eltávolítása",
|
||||
"Rename": "Átnevezés",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Utolsó N ismétlése",
|
||||
"Request Mode": "Kérési mód",
|
||||
"Reranking Model": "Újrarangsoroló modell",
|
||||
"Reranking model disabled": "Újrarangsoroló modell letiltva",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Újrarangsoroló modell beállítva erre: \"{{reranking_model}}\"",
|
||||
"Reset": "Visszaállítás",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Feltöltési könyvtár visszaállítása",
|
||||
"Reset Vector Storage/Knowledge": "Vektor tárhely/tudásbázis visszaállítása",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "A válasz értesítések nem aktiválhatók, mert a weboldal engedélyei meg lettek tagadva. Kérjük, látogasson el a böngésző beállításaihoz a szükséges hozzáférés megadásához.",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (helyi)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Szélesvásznú mód",
|
||||
"Won": "Nyert",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "Izinkan Gangguan Suara dalam Panggilan",
|
||||
"Already have an account?": "Sudah memiliki akun?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "asisten",
|
||||
"and": "dan",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 URL Dasar diperlukan.",
|
||||
"Available list": "",
|
||||
"available!": "tersedia!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Kembali",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Permintaan Bersamaan",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Konfirmasi",
|
||||
"Confirm Password": "Konfirmasi Kata Sandi",
|
||||
"Confirm your action": "Konfirmasi tindakan Anda",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Default (Pengubah Kalimat)",
|
||||
"Default Model": "Model Default",
|
||||
"Default model updated": "Model default diperbarui",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Saran Permintaan Default",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Menghapus Pengguna",
|
||||
"Deleted {{deleteModelTag}}": "Menghapus {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Menghapus {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Deskripsi",
|
||||
"Didn't fully follow instructions": "Tidak sepenuhnya mengikuti instruksi",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Masukkan kode bahasa",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Masukkan tag model (misalnya {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Masukkan Jumlah Langkah (mis. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Gagal membuat API Key.",
|
||||
"Failed to read clipboard contents": "Gagal membaca konten papan klip",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Gagal memperbarui pengaturan",
|
||||
"Failed to upload file.": "",
|
||||
"February": "Februari",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Sembunyikan",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Ada yang bisa saya bantu hari ini?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Pencarian Hibrida",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Konten File Model",
|
||||
"Models": "Model",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Lainnya",
|
||||
"Name": "Nama",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Tidak ada hasil yang ditemukan",
|
||||
"No search query generated": "Tidak ada permintaan pencarian yang dibuat",
|
||||
"No source available": "Tidak ada sumber yang tersedia",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Hapus",
|
||||
"Remove Model": "Hapus Model",
|
||||
"Rename": "Ganti nama",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Ulangi N Terakhir",
|
||||
"Request Mode": "Mode Permintaan",
|
||||
"Reranking Model": "Model Pemeringkatan Ulang",
|
||||
"Reranking model disabled": "Model pemeringkatan ulang dinonaktifkan",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Model pemeringkatan diatur ke \"{{reranking_model}}\"",
|
||||
"Reset": "Atur Ulang",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Setel Ulang Direktori Unggahan",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Notifikasi respons tidak dapat diaktifkan karena izin situs web telah ditolak. Silakan kunjungi pengaturan browser Anda untuk memberikan akses yang diperlukan.",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Bisikan (Lokal)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "Mode Layar Lebar",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -11,33 +11,33 @@
|
||||
"A task model is used when performing tasks such as generating titles for chats and web search queries": "Úsáidtear samhail tasc agus tascanna á ndéanamh agat mar theidil a ghiniúint do chomhráite agus ceisteanna cuardaigh gréasáin",
|
||||
"a user": "úsáideoir",
|
||||
"About": "Maidir",
|
||||
"Access": "",
|
||||
"Access Control": "",
|
||||
"Accessible to all users": "",
|
||||
"Access": "Rochtain",
|
||||
"Access Control": "Rialaithe Rochtana",
|
||||
"Accessible to all users": "Inrochtana do gach úsáideoir",
|
||||
"Account": "Cuntas",
|
||||
"Account Activation Pending": "Gníomhachtaithe Cuntas",
|
||||
"Accurate information": "Faisnéis chruinn",
|
||||
"Actions": "Gníomhartha",
|
||||
"Activate this command by typing \"/{{COMMAND}}\" to chat input.": "",
|
||||
"Activate this command by typing \"/{{COMMAND}}\" to chat input.": "Gníomhachtaigh an t-ordú seo trí \"/{{COMMAND}}\" a chlóscríobh chun ionchur comhrá a dhéanamh.",
|
||||
"Active Users": "Úsáideoirí Gníomhacha",
|
||||
"Add": "Cuir",
|
||||
"Add a model ID": "",
|
||||
"Add a model ID": "Cuir ID samhail leis",
|
||||
"Add a short description about what this model does": "Cuir cur síos gairid leis faoin méid a dhéanann an tsamhail seo",
|
||||
"Add a tag": "Cuir clib leis",
|
||||
"Add Arena Model": "Cuir Múnla Arena leis",
|
||||
"Add Connection": "",
|
||||
"Add Connection": "Cuir Ceangal leis",
|
||||
"Add Content": "Cuir Ábhar leis",
|
||||
"Add content here": "Cuir ábhar anseo",
|
||||
"Add custom prompt": "Cuir pras saincheaptha leis",
|
||||
"Add Files": "Cuir Comhaid",
|
||||
"Add Group": "",
|
||||
"Add Group": "Cuir Grúpa leis",
|
||||
"Add Memory": "Cuir Cuimhne",
|
||||
"Add Model": "Cuir múnla leis",
|
||||
"Add Tag": "Cuir Clib leis",
|
||||
"Add Tags": "Cuir Clibeanna leis",
|
||||
"Add text content": "Cuir ábhar téacs leis",
|
||||
"Add User": "Cuir Úsáideoir leis",
|
||||
"Add User Group": "",
|
||||
"Add User Group": "Cuir Grúpa Úsáideoirí leis",
|
||||
"Adjusting these settings will apply changes universally to all users.": "Cuirfear na socruithe seo ag coigeartú athruithe go huilíoch ar gach úsáideoir.",
|
||||
"admin": "riarachán",
|
||||
"Admin": "Riarachán",
|
||||
@@ -48,17 +48,18 @@
|
||||
"Advanced Params": "Paraiméid Casta",
|
||||
"All chats": "Gach comhrá",
|
||||
"All Documents": "Gach Doiciméad",
|
||||
"All models deleted successfully": "",
|
||||
"Allow Chat Delete": "",
|
||||
"All models deleted successfully": "Scriosadh na samhlacha go léir go rathúil",
|
||||
"Allow Chat Delete": "Ceadaigh Comhrá a Scriosadh",
|
||||
"Allow Chat Deletion": "Cead Scriosadh Comhrá",
|
||||
"Allow Chat Edit": "",
|
||||
"Allow File Upload": "",
|
||||
"Allow Chat Edit": "Ceadaigh Eagarthóireacht Comhrá",
|
||||
"Allow File Upload": "Ceadaigh Uaslódáil Comhad",
|
||||
"Allow non-local voices": "Lig guthanna neamh-áitiúla",
|
||||
"Allow Temporary Chat": "Cead Comhrá Sealadach",
|
||||
"Allow User Location": "Ceadaigh Suíomh Úsáideora",
|
||||
"Allow Voice Interruption in Call": "Ceadaigh Briseadh Guth i nGlao",
|
||||
"Already have an account?": "Tá cuntas agat cheana féin?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Rogha eile seachas an top_p, agus tá sé mar aidhm aige cothromaíocht cáilíochta agus éagsúlachta a chinntiú. Léiríonn an paraiméadar p an dóchúlacht íosta go mbreithneofar comhartha, i gcoibhneas le dóchúlacht an chomhartha is dóichí. Mar shampla, le p=0.05 agus dóchúlacht 0.9 ag an comhartha is dóichí, déantar logits le luach níos lú ná 0.045 a scagadh amach. (Réamhshocrú: 0.0)",
|
||||
"Amazing": "Iontach",
|
||||
"an assistant": "cúntóir",
|
||||
"and": "agus",
|
||||
"and {{COUNT}} more": "agus {{COUNT}} eile",
|
||||
@@ -67,15 +68,15 @@
|
||||
"API Key": "Eochair API",
|
||||
"API Key created.": "Cruthaíodh Eochair API.",
|
||||
"API keys": "Eochracha API",
|
||||
"Application DN": "",
|
||||
"Application DN Password": "",
|
||||
"applies to all users with the \"user\" role": "",
|
||||
"Application DN": "Feidhmchlár DN",
|
||||
"Application DN Password": "Feidhmchlár DN Pasfhocal",
|
||||
"applies to all users with the \"user\" role": "baineann sé le gach úsáideoir a bhfuil an ról \"úsáideoir\" aige",
|
||||
"April": "Aibreán",
|
||||
"Archive": "Cartlann",
|
||||
"Archive All Chats": "Cartlann Gach Comhrá",
|
||||
"Archived Chats": "Comhráite Cartlann",
|
||||
"archived-chat-export": "",
|
||||
"Are you sure you want to unarchive all archived chats?": "",
|
||||
"archived-chat-export": "gcartlann-comhrá-onnmhairiú",
|
||||
"Are you sure you want to unarchive all archived chats?": "An bhfuil tú cinnte gur mhaith leat gach comhrá cartlainne a dhíchartlannú?",
|
||||
"Are you sure?": "An bhfuil tú cinnte?",
|
||||
"Arena Models": "Múnlaí Airéine",
|
||||
"Artifacts": "Déantáin",
|
||||
@@ -83,10 +84,10 @@
|
||||
"Assistant": "Cúntóir",
|
||||
"Attach file": "Ceangail comhad",
|
||||
"Attention to detail": "Aird ar mhionsonraí",
|
||||
"Attribute for Username": "",
|
||||
"Attribute for Username": "Tréith don Ainm Úsáideora",
|
||||
"Audio": "Fuaim",
|
||||
"August": "Lúnasa",
|
||||
"Authenticate": "",
|
||||
"Authenticate": "Fíordheimhnigh",
|
||||
"Auto-Copy Response to Clipboard": "Freagra AutoCopy go Gearrthaisce",
|
||||
"Auto-playback response": "Freagra uathsheinm",
|
||||
"Automatic1111": "Uathoibríoch1111",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "Tá URL bonn UATHOMATIC1111 ag teastáil.",
|
||||
"Available list": "Liosta atá ar fáil",
|
||||
"available!": "ar fáil!",
|
||||
"Awful": "Uafásach",
|
||||
"Azure AI Speech": "Óráid Azure AI",
|
||||
"Azure Region": "Réigiún Azure",
|
||||
"Back": "Ar ais",
|
||||
@@ -104,27 +106,27 @@
|
||||
"Batch Size (num_batch)": "Méid Baisc (num_batch)",
|
||||
"before": "roimh",
|
||||
"Being lazy": "A bheith leisciúil",
|
||||
"Bing Search V7 Endpoint": "",
|
||||
"Bing Search V7 Subscription Key": "",
|
||||
"Bing Search V7 Endpoint": "Cuardach Bing V7 Críochphointe",
|
||||
"Bing Search V7 Subscription Key": "Eochair Síntiúis Bing Cuardach V7",
|
||||
"Brave Search API Key": "Eochair API Cuardaigh Brave",
|
||||
"By {{name}}": "",
|
||||
"By {{name}}": "Le {{name}}",
|
||||
"Bypass SSL verification for Websites": "Seachbhachtar fíorú SSL do Láithreáin",
|
||||
"Call": "Glaoigh",
|
||||
"Call feature is not supported when using Web STT engine": "Ní thacaítear le gné glaonna agus inneall Web STT á úsáid",
|
||||
"Camera": "Ceamara",
|
||||
"Cancel": "Cealaigh",
|
||||
"Capabilities": "Cumais",
|
||||
"Certificate Path": "",
|
||||
"Certificate Path": "Cosán Teastais",
|
||||
"Change Password": "Athraigh Pasfhocal",
|
||||
"Character": "Carachtar",
|
||||
"Chart new frontiers": "",
|
||||
"Chart new frontiers": "Cairt teorainneacha nua",
|
||||
"Chat": "Comhrá",
|
||||
"Chat Background Image": "Íomhá Cúlra Comhrá",
|
||||
"Chat Bubble UI": "Comhrá Bubble UI",
|
||||
"Chat Controls": "Rialuithe Comhrá",
|
||||
"Chat direction": "Treo comhrá",
|
||||
"Chat Overview": "Forbhreathnú ar an",
|
||||
"Chat Permissions": "",
|
||||
"Chat Permissions": "Ceadanna Comhrá",
|
||||
"Chat Tags Auto-Generation": "Clibeanna Comhrá Auto-Giniúint",
|
||||
"Chats": "Comhráite",
|
||||
"Check Again": "Seiceáil Arís",
|
||||
@@ -134,11 +136,11 @@
|
||||
"Chunk Overlap": "Forluí smután",
|
||||
"Chunk Params": "Chunk Params",
|
||||
"Chunk Size": "Méid an Píosa",
|
||||
"Ciphers": "",
|
||||
"Ciphers": "Cipéirí",
|
||||
"Citation": "Lua",
|
||||
"Clear memory": "Cuimhne ghlan",
|
||||
"click here": "",
|
||||
"Click here for filter guides.": "",
|
||||
"click here": "cliceáil anseo",
|
||||
"Click here for filter guides.": "Cliceáil anseo le haghaidh treoracha scagaire.",
|
||||
"Click here for help.": "Cliceáil anseo le haghaidh cabhair.",
|
||||
"Click here to": "Cliceáil anseo chun",
|
||||
"Click here to download user import template file.": "Cliceáil anseo chun an comhad iompórtála úsáideora a íoslódáil.",
|
||||
@@ -155,7 +157,7 @@
|
||||
"Code execution": "Cód a fhorghníomhú",
|
||||
"Code formatted successfully": "Cód formáidithe go rathúil",
|
||||
"Collection": "Bailiúchán",
|
||||
"Color": "",
|
||||
"Color": "Dath",
|
||||
"ComfyUI": "ComfyUI",
|
||||
"ComfyUI Base URL": "URL Bonn ComfyUI",
|
||||
"ComfyUI Base URL is required.": "Teastaíonn URL ComfyUI Base.",
|
||||
@@ -164,7 +166,8 @@
|
||||
"Command": "Ordú",
|
||||
"Completions": "Críochnaithe",
|
||||
"Concurrent Requests": "Iarrataí Comhthéime",
|
||||
"Configure": "",
|
||||
"Configure": "Cumraigh",
|
||||
"Configure Models": "",
|
||||
"Confirm": "Deimhnigh",
|
||||
"Confirm Password": "Deimhnigh Pasfhocal",
|
||||
"Confirm your action": "Deimhnigh do ghníomh",
|
||||
@@ -175,11 +178,11 @@
|
||||
"Context Length": "Fad Comhthéacs",
|
||||
"Continue Response": "Leanúint ar aghaidh",
|
||||
"Continue with {{provider}}": "Lean ar aghaidh le {{provider}}",
|
||||
"Continue with Email": "",
|
||||
"Continue with LDAP": "",
|
||||
"Continue with Email": "Lean ar aghaidh le Ríomhphost",
|
||||
"Continue with LDAP": "Lean ar aghaidh le LDAP",
|
||||
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "Rialú conas a roinntear téacs teachtaireachta d'iarratais TTS. Roinneann 'poncaíocht' ina abairtí, scoilteann 'míreanna' i míreanna, agus coinníonn 'aon' an teachtaireacht mar shreang amháin.",
|
||||
"Controls": "Rialuithe",
|
||||
"Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text. (Default: 5.0)": "",
|
||||
"Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text. (Default: 5.0)": "Rialaíonn sé an chothromaíocht idir comhleanúnachas agus éagsúlacht an aschuir. Beidh téacs níos dírithe agus níos soiléire mar thoradh ar luach níos ísle. (Réamhshocrú: 5.0)",
|
||||
"Copied": "Cóipeáladh",
|
||||
"Copied shared chat URL to clipboard!": "Cóipeáladh URL an chomhrá roinnte chuig an ngearrthaisce!",
|
||||
"Copied to clipboard": "Cóipeáilte go gear",
|
||||
@@ -189,12 +192,12 @@
|
||||
"Copy Link": "Cóipeáil Nasc",
|
||||
"Copy to clipboard": "Cóipeáil chuig an ngearrthaisce",
|
||||
"Copying to clipboard was successful!": "D'éirigh le cóipeáil chuig an ngearrthaisce!",
|
||||
"Create": "",
|
||||
"Create a knowledge base": "",
|
||||
"Create": "Cruthaigh",
|
||||
"Create a knowledge base": "Cruthaigh bonn eolais",
|
||||
"Create a model": "Cruthaigh samhail",
|
||||
"Create Account": "Cruthaigh Cuntas",
|
||||
"Create Admin Account": "",
|
||||
"Create Group": "",
|
||||
"Create Admin Account": "Cruthaigh Cuntas Riaracháin",
|
||||
"Create Group": "Cruthaigh Grúpa",
|
||||
"Create Knowledge": "Cruthaigh Eolais",
|
||||
"Create new key": "Cruthaigh eochair nua",
|
||||
"Create new secret key": "Cruthaigh eochair rúnda nua",
|
||||
@@ -213,16 +216,17 @@
|
||||
"Default (SentenceTransformers)": "Réamhshocraithe (SentenceTransFormers)",
|
||||
"Default Model": "Samhail Réamhshocraithe",
|
||||
"Default model updated": "An tsamhail réamhshocraithe",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Models": "",
|
||||
"Default permissions": "Ceadanna réamhshocraithe",
|
||||
"Default permissions updated successfully": "D'éirigh le ceadanna réamhshocraithe a nuashonrú",
|
||||
"Default Prompt Suggestions": "Moltaí Pras Réamhshocraithe",
|
||||
"Default to 389 or 636 if TLS is enabled": "",
|
||||
"Default to ALL": "",
|
||||
"Default to 389 or 636 if TLS is enabled": "Réamhshocrú go 389 nó 636 má tá TLS cumasaithe",
|
||||
"Default to ALL": "Réamhshocrú do GACH",
|
||||
"Default User Role": "Ról Úsáideora Réamhshoc",
|
||||
"Delete": "Scrios",
|
||||
"Delete a model": "Scrios samhail",
|
||||
"Delete All Chats": "Scrios Gach Comhrá",
|
||||
"Delete All Models": "",
|
||||
"Delete All Models": "Scrios Gach Múnla",
|
||||
"Delete chat": "Scrios comhrá",
|
||||
"Delete Chat": "Scrios Comhrá",
|
||||
"Delete chat?": "Scrios comhrá?",
|
||||
@@ -234,7 +238,8 @@
|
||||
"Delete User": "Scrios Úsáideoir",
|
||||
"Deleted {{deleteModelTag}}": "Scriosta {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Scriosta {{name}}",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Deleted User": "Úsáideoir Scriosta",
|
||||
"Describe your knowledge base and objectives": "Déan cur síos ar do bhunachar eolais agus do chuspóirí",
|
||||
"Description": "Cur síos",
|
||||
"Didn't fully follow instructions": "Níor lean sé treoracha go hiomlán",
|
||||
"Disabled": "Díchumasaithe",
|
||||
@@ -242,17 +247,17 @@
|
||||
"Discover a model": "Faigh amach samhail",
|
||||
"Discover a prompt": "Faigh amach pras",
|
||||
"Discover a tool": "Faigh amach uirlis",
|
||||
"Discover wonders": "",
|
||||
"Discover wonders": "Faigh amach iontais",
|
||||
"Discover, download, and explore custom functions": "Faigh amach, íoslódáil agus iniúchadh feidhmeanna saincheaptha",
|
||||
"Discover, download, and explore custom prompts": "Leideanna saincheaptha a fháil amach, a íoslódáil agus a iniúchadh",
|
||||
"Discover, download, and explore custom tools": "Uirlisí saincheaptha a fháil amach, íoslódáil agus iniúchadh",
|
||||
"Discover, download, and explore model presets": "Réamhshocruithe samhail a fháil amach, a íoslódáil agus a iniúchadh",
|
||||
"Dismissible": "Dífhostaithe",
|
||||
"Display": "",
|
||||
"Display": "Taispeáin",
|
||||
"Display Emoji in Call": "Taispeáin Emoji i nGlao",
|
||||
"Display the username instead of You in the Chat": "Taispeáin an t-ainm úsáideora in ionad Tú sa Comhrá",
|
||||
"Displays citations in the response": "",
|
||||
"Dive into knowledge": "",
|
||||
"Displays citations in the response": "Taispeánann sé luanna sa fhreagra",
|
||||
"Dive into knowledge": "Léim isteach eolas",
|
||||
"Do not install functions from sources you do not fully trust.": "Ná suiteáil feidhmeanna ó fhoinsí nach bhfuil muinín iomlán agat.",
|
||||
"Do not install tools from sources you do not fully trust.": "Ná suiteáil uirlisí ó fhoinsí nach bhfuil muinín iomlán agat.",
|
||||
"Document": "Doiciméad",
|
||||
@@ -267,39 +272,39 @@
|
||||
"Download": "Íoslódáil",
|
||||
"Download canceled": "Íoslódáil cealaithe",
|
||||
"Download Database": "Íoslódáil Bunachair",
|
||||
"Drag and drop a file to upload or select a file to view": "",
|
||||
"Drag and drop a file to upload or select a file to view": "Tarraing agus scaoil comhad le huaslódáil nó roghnaigh comhad le féachaint air",
|
||||
"Draw": "Tarraing",
|
||||
"Drop any files here to add to the conversation": "Scaoil aon chomhaid anseo le cur leis an gcomhrá",
|
||||
"e.g. '30s','10m'. Valid time units are 's', 'm', 'h'.": "m.sh. '30s', '10m'. Is iad aonaid ama bailí ná 's', 'm', 'h'.",
|
||||
"e.g. A filter to remove profanity from text": "",
|
||||
"e.g. My Filter": "",
|
||||
"e.g. My Tools": "",
|
||||
"e.g. my_filter": "",
|
||||
"e.g. my_tools": "",
|
||||
"e.g. Tools for performing various operations": "",
|
||||
"e.g. A filter to remove profanity from text": "m.h. Scagaire chun profanity a bhaint as téacs",
|
||||
"e.g. My Filter": "m.sh. Mo Scagaire",
|
||||
"e.g. My Tools": "e.g. Mo Uirlisí",
|
||||
"e.g. my_filter": "m.sh. mo_scagaire",
|
||||
"e.g. my_tools": "m.sh. mo_uirlisí",
|
||||
"e.g. Tools for performing various operations": "m.sh. Uirlisí chun oibríochtaí éagsúla a dhéanamh",
|
||||
"Edit": "Cuir in eagar",
|
||||
"Edit Arena Model": "Cuir Samhail Airéine in Eagar",
|
||||
"Edit Connection": "",
|
||||
"Edit Default Permissions": "",
|
||||
"Edit Connection": "Cuir Ceangal in Eagar",
|
||||
"Edit Default Permissions": "Cuir Ceadanna Réamhshocraithe in Eagar",
|
||||
"Edit Memory": "Cuir Cuimhne in eagar",
|
||||
"Edit User": "Cuir Úsáideoir in eagar",
|
||||
"Edit User Group": "",
|
||||
"Edit User Group": "Cuir Grúpa Úsáideoirí in Eagar",
|
||||
"ElevenLabs": "Eleven Labs",
|
||||
"Email": "Ríomhphost",
|
||||
"Embark on adventures": "",
|
||||
"Embark on adventures": "Dul ar eachtraí",
|
||||
"Embedding Batch Size": "Méid Baisc a ionchorprú",
|
||||
"Embedding Model": "Múnla Leabháilte",
|
||||
"Embedding Model Engine": "Inneall Múnla Ionchorprú",
|
||||
"Embedding model set to \"{{embedding_model}}\"": "Samhail leabaithe atá socraithe go \"{{embedding_model}}\"",
|
||||
"Enable API Key Auth": "",
|
||||
"Enable API Key Auth": "Cumasaigh Fíordheimhniú Eochracha API",
|
||||
"Enable Community Sharing": "Cumasaigh Comhroinnt Pobail",
|
||||
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "",
|
||||
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "",
|
||||
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Cumasaigh Glasáil Cuimhne (mlock) chun sonraí samhaltaithe a chosc ó RAM. Glasálann an rogha seo sraith oibre leathanaigh an mhúnla isteach i RAM, ag cinntiú nach ndéanfar iad a mhalartú go diosca. Is féidir leis seo cabhrú le feidhmíocht a choinneáil trí lochtanna leathanaigh a sheachaint agus rochtain tapa ar shonraí a chinntiú.",
|
||||
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Cumasaigh Mapáil Cuimhne (mmap) chun sonraí samhla a lódáil. Ligeann an rogha seo don chóras stóráil diosca a úsáid mar leathnú ar RAM trí chomhaid diosca a chóireáil amhail is dá mba i RAM iad. Is féidir leis seo feidhmíocht na samhla a fheabhsú trí rochtain níos tapúla ar shonraí a cheadú. Mar sin féin, d'fhéadfadh sé nach n-oibreoidh sé i gceart le gach córas agus féadfaidh sé méid suntasach spáis diosca a ithe.",
|
||||
"Enable Message Rating": "Cumasaigh Rátáil Teachtai",
|
||||
"Enable Mirostat sampling for controlling perplexity. (Default: 0, 0 = Disabled, 1 = Mirostat, 2 = Mirostat 2.0)": "",
|
||||
"Enable Mirostat sampling for controlling perplexity. (Default: 0, 0 = Disabled, 1 = Mirostat, 2 = Mirostat 2.0)": "Cumasaigh sampláil Mirostat chun seachrán a rialú. (Réamhshocrú: 0, 0 = Díchumasaithe, 1 = Mirostat, 2 = Mirostat 2.0)",
|
||||
"Enable New Sign Ups": "Cumasaigh Clárúcháin Nua",
|
||||
"Enable Retrieval Query Generation": "",
|
||||
"Enable Tags Generation": "",
|
||||
"Enable Retrieval Query Generation": "Cumasaigh Giniúint Iarratas Aisghabhála",
|
||||
"Enable Tags Generation": "Cumasaigh Giniúint Clibeanna",
|
||||
"Enable Web Search": "Cumasaigh Cuardach Gréasáin",
|
||||
"Enable Web Search Query Generation": "Cumasaigh Giniúint Ceist Cuardaigh Gréasáin",
|
||||
"Enabled": "Cumasaithe",
|
||||
@@ -308,12 +313,12 @@
|
||||
"Enter {{role}} message here": "Cuir isteach teachtaireacht {{role}} anseo",
|
||||
"Enter a detail about yourself for your LLMs to recall": "Cuir isteach mionsonraí fút féin chun do LLManna a mheabhrú",
|
||||
"Enter api auth string (e.g. username:password)": "Cuir isteach sreang auth api (m.sh. ainm úsáideora: pasfhocal)",
|
||||
"Enter Application DN": "",
|
||||
"Enter Application DN Password": "",
|
||||
"Enter Bing Search V7 Endpoint": "",
|
||||
"Enter Bing Search V7 Subscription Key": "",
|
||||
"Enter Brave Search API Key": "Cuir isteach Eochair API Brave Search",
|
||||
"Enter certificate path": "",
|
||||
"Enter Application DN": "Cuir isteach Feidhmchlár DN",
|
||||
"Enter Application DN Password": "Iontráil Feidhmchlár DN Pasfhocal",
|
||||
"Enter Bing Search V7 Endpoint": "Cuir isteach Cuardach Bing V7 Críochphointe",
|
||||
"Enter Bing Search V7 Subscription Key": "Cuir isteach Eochair Síntiúis Bing Cuardach V7",
|
||||
"Enter Brave Search API Key": "Cuir isteach Eochair API Brave Cuardach",
|
||||
"Enter certificate path": "Cuir isteach cosán an teastais",
|
||||
"Enter CFG Scale (e.g. 7.0)": "Cuir isteach Scála CFG (m.sh. 7.0)",
|
||||
"Enter Chunk Overlap": "Cuir isteach Chunk Forluí",
|
||||
"Enter Chunk Size": "Cuir isteach Méid an Chunc",
|
||||
@@ -322,10 +327,11 @@
|
||||
"Enter Google PSE API Key": "Cuir isteach Eochair API Google PSE",
|
||||
"Enter Google PSE Engine Id": "Cuir isteach ID Inneall Google PSE",
|
||||
"Enter Image Size (e.g. 512x512)": "Iontráil Méid Íomhá (m.sh. 512x512)",
|
||||
"Enter Jina API Key": "",
|
||||
"Enter Jina API Key": "Cuir isteach Eochair API Jina",
|
||||
"Enter language codes": "Cuir isteach cóid teanga",
|
||||
"Enter Model ID": "Iontráil ID Mhúnla",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Cuir isteach chlib samhail (m.sh. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Iontráil Líon na gCéimeanna (m.sh. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "Cuir isteach Sampler (m.sh. Euler a)",
|
||||
"Enter Scheduler (e.g. Karras)": "Cuir isteach Sceidealóir (m.sh. Karras)",
|
||||
@@ -333,13 +339,13 @@
|
||||
"Enter SearchApi API Key": "Cuir isteach Eochair API SearchAPI",
|
||||
"Enter SearchApi Engine": "Cuir isteach Inneall SearchAPI",
|
||||
"Enter Searxng Query URL": "Cuir isteach URL Ceist Searxng",
|
||||
"Enter Seed": "",
|
||||
"Enter Seed": "Cuir isteach Síl",
|
||||
"Enter Serper API Key": "Cuir isteach Eochair API Serper",
|
||||
"Enter Serply API Key": "Cuir isteach Eochair API Serply",
|
||||
"Enter Serpstack API Key": "Cuir isteach Eochair API Serpstack",
|
||||
"Enter server host": "",
|
||||
"Enter server label": "",
|
||||
"Enter server port": "",
|
||||
"Enter server host": "Cuir isteach óstach freastalaí",
|
||||
"Enter server label": "Cuir isteach lipéad freastalaí",
|
||||
"Enter server port": "Cuir isteach port freastalaí",
|
||||
"Enter stop sequence": "Cuir isteach seicheamh stad",
|
||||
"Enter system prompt": "Cuir isteach an chóras pras",
|
||||
"Enter Tavily API Key": "Cuir isteach eochair API Tavily",
|
||||
@@ -352,38 +358,39 @@
|
||||
"Enter your message": "Cuir isteach do theachtaireacht",
|
||||
"Enter Your Password": "Cuir isteach do phasfhocal",
|
||||
"Enter Your Role": "Cuir isteach do Ról",
|
||||
"Enter Your Username": "",
|
||||
"Enter Your Username": "Cuir isteach D'Ainm Úsáideora",
|
||||
"Error": "Earráid",
|
||||
"ERROR": "EARRÁID",
|
||||
"Evaluations": "Meastóireachtaí",
|
||||
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "",
|
||||
"Example: ALL": "",
|
||||
"Example: ou=users,dc=foo,dc=example": "",
|
||||
"Example: sAMAccountName or uid or userPrincipalName": "",
|
||||
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Sampla: (&(objectClass=inetOrgPerson)(uid=%s))",
|
||||
"Example: ALL": "Sampla: GACH",
|
||||
"Example: ou=users,dc=foo,dc=example": "Sampla: ou=úsáideoirí,dc=foo,dc=sampla",
|
||||
"Example: sAMAccountName or uid or userPrincipalName": "Sampla: sAMAaccountName nó uid nó userPrincipalName",
|
||||
"Exclude": "Eisigh",
|
||||
"Experimental": "Turgnamhach",
|
||||
"Explore the cosmos": "",
|
||||
"Explore the cosmos": "Déan iniúchadh ar an cosmos",
|
||||
"Export": "Easpórtáil",
|
||||
"Export All Archived Chats": "",
|
||||
"Export All Archived Chats": "Easpórtáil Gach Comhrá Cartlainne",
|
||||
"Export All Chats (All Users)": "Easpórtáil gach comhrá (Gach Úsáideoir)",
|
||||
"Export chat (.json)": "Easpórtáil comhrá (.json)",
|
||||
"Export Chats": "Comhráite Easpórtá",
|
||||
"Export Config to JSON File": "Easpórtáil Cumraíocht chuig Comhad JSON",
|
||||
"Export Functions": "Feidhmeanna Easp",
|
||||
"Export Models": "Múnlaí a Easpórtáil",
|
||||
"Export Presets": "",
|
||||
"Export Presets": "Easpórtáil Gach Comhrá Cartlainne",
|
||||
"Export Prompts": "Leideanna Easpórtála",
|
||||
"Export to CSV": "",
|
||||
"Export to CSV": "Easpórtáil go CSV",
|
||||
"Export Tools": "Uirlisí Easpór",
|
||||
"External Models": "Múnlaí Seachtracha",
|
||||
"Failed to add file.": "Theip ar an gcomhad a chur leis.",
|
||||
"Failed to create API Key.": "Theip ar an eochair API a chruthú.",
|
||||
"Failed to read clipboard contents": "Theip ar ábhar gearrthaisce a lé",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "Theip ar shocruithe a nuashonrú",
|
||||
"Failed to upload file.": "Theip ar uaslódáil an chomhaid.",
|
||||
"February": "Feabhra",
|
||||
"Feedback History": "Stair Aiseolais",
|
||||
"Feedbacks": "",
|
||||
"Feedbacks": "Aiseolas",
|
||||
"Feel free to add specific details": "Ná bíodh leisce ort sonraí ar leith a chur leis",
|
||||
"File": "Comhad",
|
||||
"File added successfully.": "D'éirigh leis an gcomhad a chur leis.",
|
||||
@@ -404,18 +411,18 @@
|
||||
"Folder name cannot be empty.": "Ní féidir ainm fillteáin a bheith folamh.",
|
||||
"Folder name updated successfully": "D'éirigh le hainm an fhillteáin a nuashonrú",
|
||||
"Followed instructions perfectly": "Lean treoracha go foirfe",
|
||||
"Forge new paths": "",
|
||||
"Forge new paths": "Déan cosáin nua a chruthú",
|
||||
"Form": "Foirm",
|
||||
"Format your variables using brackets like this:": "Formáidigh na hathróga ag baint úsáide as lúibíní mar seo:",
|
||||
"Frequency Penalty": "Pionós Minicíochta",
|
||||
"Function": "Feidhm",
|
||||
"Function created successfully": "Cruthaíodh feidhm go rathúil",
|
||||
"Function deleted successfully": "Feidhm scriosta go rathúil",
|
||||
"Function Description": "",
|
||||
"Function ID": "",
|
||||
"Function Description": "Cur síos ar Fheidhm",
|
||||
"Function ID": "ID Feidhme",
|
||||
"Function is now globally disabled": "Tá an fheidhm faoi mhíchumas go domhanda",
|
||||
"Function is now globally enabled": "Tá feidhm cumasaithe go domhanda anois",
|
||||
"Function Name": "",
|
||||
"Function Name": "Ainm Feidhme",
|
||||
"Function updated successfully": "Feidhm nuashonraithe",
|
||||
"Functions": "Feidhmeanna",
|
||||
"Functions allow arbitrary code execution": "Ligeann feidhmeanna forghníomhú cód",
|
||||
@@ -426,33 +433,34 @@
|
||||
"Generate Image": "Ginigh Íomhá",
|
||||
"Generating search query": "Giniúint ceist cuardaigh",
|
||||
"Generation Info": "Eolas Giniúin",
|
||||
"Get started": "",
|
||||
"Get started with {{WEBUI_NAME}}": "",
|
||||
"Get started": "Cuir tús leis",
|
||||
"Get started with {{WEBUI_NAME}}": "Cuir tús le {{WEBUI_NAME}}",
|
||||
"Global": "Domhanda",
|
||||
"Good Response": "Freagra Mhaith",
|
||||
"Google PSE API Key": "Eochair API Google PSE",
|
||||
"Google PSE Engine Id": "ID Inneall Google PSE",
|
||||
"Group created successfully": "",
|
||||
"Group deleted successfully": "",
|
||||
"Group Description": "",
|
||||
"Group Name": "",
|
||||
"Group updated successfully": "",
|
||||
"Groups": "",
|
||||
"Group created successfully": "Grúpa cruthaithe go rathúil",
|
||||
"Group deleted successfully": "D'éirigh le scriosadh an ghrúpa",
|
||||
"Group Description": "Cur síos ar an nGrúpa",
|
||||
"Group Name": "Ainm an Ghrúpa",
|
||||
"Group updated successfully": "D'éirigh le nuashonrú an ghrúpa",
|
||||
"Groups": "Grúpaí",
|
||||
"h:mm a": "h: mm a",
|
||||
"Haptic Feedback": "Aiseolas Haptic",
|
||||
"has no conversations.": "níl aon chomhráite aige.",
|
||||
"Hello, {{name}}": "Dia duit, {{name}}",
|
||||
"Help": "Cabhair",
|
||||
"Help us create the best community leaderboard by sharing your feedback history!": "Cabhraigh linn an clár ceannairí pobail is fearr a chruthú trí do stair aiseolais a roinnt!",
|
||||
"Hex Color": "",
|
||||
"Hex Color - Leave empty for default color": "",
|
||||
"Hex Color": "Dath Heics",
|
||||
"Hex Color - Leave empty for default color": "Dath Heics - Fág folamh don dath réamhshocraithe",
|
||||
"Hide": "Folaigh",
|
||||
"Host": "",
|
||||
"Host": "Óstach",
|
||||
"How can I help you today?": "Conas is féidir liom cabhrú leat inniu?",
|
||||
"How would you rate this response?": "Cad é mar a mheasfá an freagra seo?",
|
||||
"Hybrid Search": "Cuardach Hibrideach",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Admhaím gur léigh mé agus tuigim impleachtaí mo ghníomhaíochta. Táim ar an eolas faoi na rioscaí a bhaineann le cód treallach a fhorghníomhú agus tá iontaofacht na foinse fíoraithe agam.",
|
||||
"ID": "ID",
|
||||
"Ignite curiosity": "",
|
||||
"Ignite curiosity": "Las fiosracht",
|
||||
"Image Generation (Experimental)": "Giniúint Íomhá (Turgnaimh)",
|
||||
"Image Generation Engine": "Inneall Giniúna Íomh",
|
||||
"Image Settings": "Socruithe Íomhá",
|
||||
@@ -461,13 +469,13 @@
|
||||
"Import Config from JSON File": "Cumraíocht Iompórtáil ó Chomhad JSON",
|
||||
"Import Functions": "Feidhmeanna Iom",
|
||||
"Import Models": "Múnlaí a Iompórtáil",
|
||||
"Import Presets": "",
|
||||
"Import Presets": "Réamhshocruithe Iompórtáil",
|
||||
"Import Prompts": "Leideanna Iompórtála",
|
||||
"Import Tools": "Uirlisí Iomp",
|
||||
"Include": "Cuir san áireamh",
|
||||
"Include `--api-auth` flag when running stable-diffusion-webui": "Cuir bratach `--api-auth` san áireamh agus webui stable-diffusion-reatha á rith",
|
||||
"Include `--api` flag when running stable-diffusion-webui": "Cuir bratach `--api` san áireamh agus webui cobhsaí-scaipthe á rith",
|
||||
"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. (Default: 0.1)": "",
|
||||
"Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. (Default: 0.1)": "Bíonn tionchar aige ar chomh tapa agus a fhreagraíonn an t-algartam d’aiseolas ón téacs ginte. Beidh coigeartuithe níos moille mar thoradh ar ráta foghlama níos ísle, agus déanfaidh ráta foghlama níos airde an t-algartam níos freagraí. (Réamhshocrú: 0.1)",
|
||||
"Info": "Eolas",
|
||||
"Input commands": "Orduithe ionchuir",
|
||||
"Install from Github URL": "Suiteáil ó Github URL",
|
||||
@@ -476,7 +484,7 @@
|
||||
"Invalid file format.": "Formáid comhaid neamhbhailí.",
|
||||
"Invalid Tag": "Clib neamhbhailí",
|
||||
"January": "Eanáir",
|
||||
"Jina API Key": "",
|
||||
"Jina API Key": "Jina API Eochair",
|
||||
"join our Discord for help.": "bí inár Discord chun cabhair a fháil.",
|
||||
"JSON": "JSON",
|
||||
"JSON Preview": "Réamhamharc JSON",
|
||||
@@ -485,31 +493,31 @@
|
||||
"JWT Expiration": "Éag JWT",
|
||||
"JWT Token": "Comhartha JWT",
|
||||
"Keep Alive": "Coinnigh Beo",
|
||||
"Key": "",
|
||||
"Key": "Eochair",
|
||||
"Keyboard shortcuts": "Aicearraí méarchlár",
|
||||
"Knowledge": "Eolas",
|
||||
"Knowledge Access": "",
|
||||
"Knowledge Access": "Rochtain Eolais",
|
||||
"Knowledge created successfully.": "Eolas cruthaithe go rathúil.",
|
||||
"Knowledge deleted successfully.": "D'éirigh leis an eolas a scriosadh.",
|
||||
"Knowledge reset successfully.": "D'éirigh le hathshocrú eolais.",
|
||||
"Knowledge updated successfully": "D'éirigh leis an eolas a nuashonrú",
|
||||
"Label": "",
|
||||
"Label": "Lipéad",
|
||||
"Landing Page Mode": "Mód Leathanach Tuirlingthe",
|
||||
"Language": "Teanga",
|
||||
"Last Active": "Gníomhach Deiridh",
|
||||
"Last Modified": "Athraithe Deiridh",
|
||||
"LDAP": "",
|
||||
"LDAP server updated": "",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP server updated": "Nuashonraíodh freastalaí LDAP",
|
||||
"Leaderboard": "An Clár Ceannairí",
|
||||
"Leave empty for unlimited": "Fág folamh le haghaidh neamhtheoranta",
|
||||
"Leave empty to include all models from \"{{URL}}/api/tags\" endpoint": "",
|
||||
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "",
|
||||
"Leave empty to include all models from \"{{URL}}/api/tags\" endpoint": "Fág folamh chun gach múnla ó chríochphointe \"{{URL}}/api/tags\" a chur san áireamh",
|
||||
"Leave empty to include all models from \"{{URL}}/models\" endpoint": "Fág folamh chun gach múnla ón gcríochphointe \"{{URL}}/models\" a chur san áireamh",
|
||||
"Leave empty to include all models or select specific models": "Fág folamh chun gach múnla a chur san áireamh nó roghnaigh múnlaí sonracha",
|
||||
"Leave empty to use the default prompt, or enter a custom prompt": "Fág folamh chun an pras réamhshocraithe a úsáid, nó cuir isteach pras saincheaptha",
|
||||
"Light": "Solas",
|
||||
"Listening...": "Éisteacht...",
|
||||
"LLMs can make mistakes. Verify important information.": "Is féidir le LLManna botúin a dhéanamh. Fíoraigh faisnéis thábhachtach.",
|
||||
"Local": "",
|
||||
"Local": "Áitiúil",
|
||||
"Local Models": "Múnlaí Áitiúla",
|
||||
"Lost": "Cailleadh",
|
||||
"LTR": "LTR",
|
||||
@@ -518,9 +526,9 @@
|
||||
"Make sure to export a workflow.json file as API format from ComfyUI.": "Déan cinnte comhad workflow.json a onnmhairiú mar fhormáid API ó ComfyUI.",
|
||||
"Manage": "Bainistiú",
|
||||
"Manage Arena Models": "Bainistigh Múnlaí Airéine",
|
||||
"Manage Ollama": "",
|
||||
"Manage Ollama API Connections": "",
|
||||
"Manage OpenAI API Connections": "",
|
||||
"Manage Ollama": "Bainistigh Ollama",
|
||||
"Manage Ollama API Connections": "Bainistigh Naisc API Ollama",
|
||||
"Manage OpenAI API Connections": "Bainistigh Naisc API OpenAI",
|
||||
"Manage Pipelines": "Bainistigh píblín",
|
||||
"March": "Márta",
|
||||
"Max Tokens (num_predict)": "Comharthaí Uasta (num_predicate)",
|
||||
@@ -543,8 +551,8 @@
|
||||
"Mirostat Eta": "Mirostat Eta",
|
||||
"Mirostat Tau": "Mirostat Tau",
|
||||
"MMMM DD, YYYY": "MMMM LL, BBBB",
|
||||
"MMMM DD, YYYY HH:mm": "MMMM LL, BBBB HH:mm",
|
||||
"MMMM DD, YYYY hh:mm:ss A": "MMMM LL, BBBB hh:mm:ss A",
|
||||
"MMMM DD, YYYY HH:mm": "MMMM LL, BBBB UU:nn",
|
||||
"MMMM DD, YYYY hh:mm:ss A": "MMMM LL, BBBB uu:nn:ss A",
|
||||
"Model": "Múnla",
|
||||
"Model '{{modelName}}' has been successfully downloaded.": "Rinneadh an tsamhail '{{modelName}}' a íoslódáil go rathúil.",
|
||||
"Model '{{modelTag}}' is already in queue for downloading.": "Tá múnla ‘{{modelTag}}’ sa scuaine cheana féin le híoslódáil.",
|
||||
@@ -554,21 +562,23 @@
|
||||
"Model accepts image inputs": "Glacann múnla le hionchuir",
|
||||
"Model created successfully!": "Cruthaíodh múnla go rathúil!",
|
||||
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "Braitheadh \u200b\u200bconair chóras comhad samhail. Teastaíonn mionainm múnla le haghaidh nuashonraithe, ní féidir leanúint ar aghaidh.",
|
||||
"Model Filtering": "",
|
||||
"Model ID": "ID Mhúnla",
|
||||
"Model IDs": "",
|
||||
"Model Filtering": "Scagadh Múnla",
|
||||
"Model ID": "ID Múnla",
|
||||
"Model IDs": "IDanna Múnla",
|
||||
"Model Name": "Ainm Múnla",
|
||||
"Model not selected": "Múnla nach roghnaíodh",
|
||||
"Model Params": "Múnla Params",
|
||||
"Model Permissions": "",
|
||||
"Model Permissions": "Ceadanna Múnla",
|
||||
"Model updated successfully": "An tsamhail nuashonraithe",
|
||||
"Modelfile Content": "Ábhar Modelfile",
|
||||
"Models": "Múnlaí",
|
||||
"Models Access": "",
|
||||
"Models Access": "Rochtain Múnlaí",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "níos mó",
|
||||
"More": "Tuilleadh",
|
||||
"Name": "Ainm",
|
||||
"Name your knowledge base": "",
|
||||
"Name your knowledge base": "Cuir ainm ar do bhunachar eolais",
|
||||
"New Chat": "Comhrá Nua",
|
||||
"New folder": "Fillteán nua",
|
||||
"New Password": "Pasfhocal Nua",
|
||||
@@ -578,15 +588,16 @@
|
||||
"No feedbacks found": "Níor aimsíodh aon aiseolas",
|
||||
"No file selected": "Níl aon chomhad roghnaithe",
|
||||
"No files found.": "Níor aimsíodh aon chomhaid.",
|
||||
"No groups with access, add a group to grant access": "",
|
||||
"No groups with access, add a group to grant access": "Gan aon ghrúpa a bhfuil rochtain acu, cuir grúpa leis chun rochtain a dheonú",
|
||||
"No HTML, CSS, or JavaScript content found.": "Níor aimsíodh aon ábhar HTML, CSS nó JavaScript.",
|
||||
"No knowledge found": "Níor aimsíodh aon eolas",
|
||||
"No model IDs": "",
|
||||
"No model IDs": "Gan IDanna múnla",
|
||||
"No models found": "Níor aimsíodh aon mhúnlaí",
|
||||
"No models selected": "",
|
||||
"No results found": "Níl aon torthaí le fáil",
|
||||
"No search query generated": "Ní ghintear aon cheist cuardaigh",
|
||||
"No source available": "Níl aon fhoinse ar fáil",
|
||||
"No users were found.": "",
|
||||
"No users were found.": "Níor aimsíodh aon úsáideoirí.",
|
||||
"No valves to update": "Gan comhlaí le nuashonrú",
|
||||
"None": "Dada",
|
||||
"Not factually correct": "Níl sé ceart go fírineach",
|
||||
@@ -605,13 +616,13 @@
|
||||
"Ollama": "Ollama",
|
||||
"Ollama API": "Ollama API",
|
||||
"Ollama API disabled": "Ollama API faoi mhíchumas",
|
||||
"Ollama API settings updated": "",
|
||||
"Ollama API settings updated": "Nuashonraíodh socruithe Olama API",
|
||||
"Ollama Version": "Leagan Ollama",
|
||||
"On": "Ar",
|
||||
"Only alphanumeric characters and hyphens are allowed": "",
|
||||
"Only alphanumeric characters and hyphens are allowed": "Ní cheadaítear ach carachtair alfa-uimhriúla agus fleiscíní",
|
||||
"Only alphanumeric characters and hyphens are allowed in the command string.": "Ní cheadaítear ach carachtair alfauméireacha agus braithíní sa sreangán ordaithe.",
|
||||
"Only collections can be edited, create a new knowledge base to edit/add documents.": "Ní féidir ach bailiúcháin a chur in eagar, bonn eolais nua a chruthú chun doiciméid a chur in eagar/a chur leis.",
|
||||
"Only select users and groups with permission can access": "",
|
||||
"Only select users and groups with permission can access": "Ní féidir ach le húsáideoirí roghnaithe agus le grúpaí a bhfuil cead acu rochtain a fháil",
|
||||
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Ups! Is cosúil go bhfuil an URL neamhbhailí. Seiceáil faoi dhó le do thoil agus iarracht arís.",
|
||||
"Oops! There are files still uploading. Please wait for the upload to complete.": "Úps! Tá comhaid fós á n-uaslódáil. Fan go mbeidh an uaslódáil críochnaithe.",
|
||||
"Oops! There was an error in the previous response.": "Úps! Bhí earráid sa fhreagra roimhe seo.",
|
||||
@@ -620,34 +631,34 @@
|
||||
"Open in full screen": "Oscail i scáileán iomlán",
|
||||
"Open new chat": "Oscail comhrá nua",
|
||||
"Open WebUI uses faster-whisper internally.": "Úsáideann Open WebUI cogar níos tapúla go hinmheánach.",
|
||||
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "",
|
||||
"Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.": "Úsáideann Open WebUI úsáidí SpeechT5 agus CMU leabaithe cainteoir Artach.",
|
||||
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Tá leagan WebUI oscailte (v{{OPEN_WEBUI_VERSION}}) níos ísle ná an leagan riachtanach (v{{REQUIRED_VERSION}})",
|
||||
"OpenAI": "OpenAI",
|
||||
"OpenAI API": "API OpenAI",
|
||||
"OpenAI API Config": "Cumraíocht API OpenAI",
|
||||
"OpenAI API Key is required.": "Tá Eochair API OpenAI ag teastáil.",
|
||||
"OpenAI API settings updated": "",
|
||||
"OpenAI API settings updated": "Nuashonraíodh socruithe OpenAI API",
|
||||
"OpenAI URL/Key required.": "Teastaíonn URL/eochair OpenAI.",
|
||||
"or": "nó",
|
||||
"Organize your users": "",
|
||||
"Organize your users": "Eagraigh do chuid úsáideoirí",
|
||||
"Other": "Eile",
|
||||
"OUTPUT": "ASCHUR",
|
||||
"Output format": "Formáid aschuir",
|
||||
"Overview": "Forbhreathnú",
|
||||
"page": "leathanach",
|
||||
"Password": "Pasfhocal",
|
||||
"Paste Large Text as File": "",
|
||||
"Paste Large Text as File": "Greamaigh Téacs Mór mar Chomhad",
|
||||
"PDF document (.pdf)": "Doiciméad PDF (.pdf)",
|
||||
"PDF Extract Images (OCR)": "Íomhánna Sliocht PDF (OCR)",
|
||||
"pending": "ar feitheamh",
|
||||
"Permission denied when accessing media devices": "Cead diúltaithe nuair a bhíonn rochtain agat",
|
||||
"Permission denied when accessing microphone": "Cead diúltaithe agus tú ag rochtain ar",
|
||||
"Permission denied when accessing microphone: {{error}}": "Cead diúltaithe agus tú ag teacht ar mhicreafón: {{error}}",
|
||||
"Permissions": "",
|
||||
"Permissions": "Ceadanna",
|
||||
"Personalization": "Pearsantú",
|
||||
"Pin": "Bioráin",
|
||||
"Pinned": "Pinneáilte",
|
||||
"Pioneer insights": "",
|
||||
"Pioneer insights": "Léargais ceannródaí",
|
||||
"Pipeline deleted successfully": "Scriosta píblíne go rathúil",
|
||||
"Pipeline downloaded successfully": "Íoslódáilte píblíne",
|
||||
"Pipelines": "Píblínte",
|
||||
@@ -659,23 +670,23 @@
|
||||
"Please enter a prompt": "Cuir isteach leid",
|
||||
"Please fill in all fields.": "Líon isteach gach réimse le do thoil.",
|
||||
"Please select a reason": "Roghnaigh cúis le do thoil",
|
||||
"Port": "",
|
||||
"Port": "Port",
|
||||
"Positive attitude": "Dearcadh dearfach",
|
||||
"Prefix ID": "",
|
||||
"Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "",
|
||||
"Prefix ID": "Aitheantas Réimír",
|
||||
"Prefix ID is used to avoid conflicts with other connections by adding a prefix to the model IDs - leave empty to disable": "Úsáidtear Aitheantas Réimír chun coinbhleachtaí le naisc eile a sheachaint trí réimír a chur le haitheantas na samhla - fág folamh le díchumasú",
|
||||
"Previous 30 days": "30 lá roimhe seo",
|
||||
"Previous 7 days": "7 lá roimhe seo",
|
||||
"Profile Image": "Íomhá Próifíl",
|
||||
"Prompt (e.g. Tell me a fun fact about the Roman Empire)": "Pras (m.sh. inis dom fíric spraíúil faoin Impireacht Rómhánach)",
|
||||
"Prompt Content": "Ábhar Pras",
|
||||
"Prompt created successfully": "",
|
||||
"Prompt created successfully": "Leid cruthaithe go rathúil",
|
||||
"Prompt suggestions": "Moltaí pras",
|
||||
"Prompt updated successfully": "",
|
||||
"Prompt updated successfully": "D'éirigh leis an leid a nuashonrú",
|
||||
"Prompts": "Leabhair",
|
||||
"Prompts Access": "",
|
||||
"Prompts Access": "Rochtain ar Chuirí",
|
||||
"Pull \"{{searchValue}}\" from Ollama.com": "Tarraing \"{{searchValue}}\" ó Ollama.com",
|
||||
"Pull a model from Ollama.com": "Tarraing múnla ó Ollama.com",
|
||||
"Query Generation Prompt": "",
|
||||
"Query Generation Prompt": "Cuirí Ginearáil Ceisteanna",
|
||||
"Query Params": "Fiosrúcháin Params",
|
||||
"RAG Template": "Teimpléad RAG",
|
||||
"Rating": "Rátáil",
|
||||
@@ -683,7 +694,7 @@
|
||||
"Read Aloud": "Léigh Ard",
|
||||
"Record voice": "Taifead guth",
|
||||
"Redirecting you to OpenWebUI Community": "Tú a atreorú chuig OpenWebUI Community",
|
||||
"Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative. (Default: 40)": "",
|
||||
"Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative. (Default: 40)": "Laghdaíonn sé an dóchúlacht go giniúint nonsense. Tabharfaidh luach níos airde (m.sh. 100) freagraí níos éagsúla, agus beidh luach níos ísle (m.sh. 10) níos coimeádaí. (Réamhshocrú: 40)",
|
||||
"Refer to yourself as \"User\" (e.g., \"User is learning Spanish\")": "Tagairt duit féin mar \"Úsáideoir\" (m.sh., \"Tá an úsáideoir ag foghlaim Spáinnis\")",
|
||||
"References from": "Tagairtí ó",
|
||||
"Refused when it shouldn't have": "Diúltaíodh nuair nár chóir dó",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Bain",
|
||||
"Remove Model": "Bain Múnla",
|
||||
"Rename": "Athainmnigh",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Déan an N deireanach arís",
|
||||
"Request Mode": "Mód Iarratais",
|
||||
"Reranking Model": "Múnla Athrangú",
|
||||
"Reranking model disabled": "Samhail athrangú faoi mhíchumas",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Samhail athrangú socraithe go \"{{reranking_model}}\"",
|
||||
"Reset": "Athshocraigh",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "Athshocraigh Eolaire Uas",
|
||||
"Reset Vector Storage/Knowledge": "Athshocraigh Stóráil/Eolas Veicteoir",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Ní féidir fógraí freagartha a ghníomhachtú toisc gur diúltaíodh ceadanna an tsuímh Ghréasáin. Tabhair cuairt ar do shocruithe brabhsálaí chun an rochtain riachtanach a dheonú.",
|
||||
@@ -721,19 +734,19 @@
|
||||
"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": "Ní thacaítear le logaí comhrá a shábháil go díreach chuig stóráil do bhrabhsálaí Tóg nóiméad chun do logaí comhrá a íoslódáil agus a scriosadh trí chliceáil an cnaipe thíos. Ná bíodh imní ort, is féidir leat do logaí comhrá a athiompórtáil go héasca chuig an gcúltaca trí",
|
||||
"Scroll to bottom when switching between branches": "Scrollaigh go bun agus tú ag athrú idir brainsí",
|
||||
"Search": "Cuardaigh",
|
||||
"Search a model": "Cuardaigh samhail",
|
||||
"Search Base": "",
|
||||
"Search a model": "Cuardaigh múnla",
|
||||
"Search Base": "Bonn Cuardaigh",
|
||||
"Search Chats": "Cuardaigh Comhráite",
|
||||
"Search Collection": "Bailiúchán Cuardaigh",
|
||||
"Search Filters": "",
|
||||
"Search Filters": "Scagairí Cuardaigh",
|
||||
"search for tags": "cuardach le haghaidh clibeanna",
|
||||
"Search Functions": "Feidhmeanna Cuardaigh",
|
||||
"Search Knowledge": "Cuardaigh Eolais",
|
||||
"Search Models": "Múnlaí Cuardaigh",
|
||||
"Search options": "",
|
||||
"Search options": "Roghanna cuardaigh",
|
||||
"Search Prompts": "Leideanna Cuardaigh",
|
||||
"Search Result Count": "Líon Torthaí Cuardaigh",
|
||||
"Search the web": "",
|
||||
"Search the web": "Cuardaigh an gréasán",
|
||||
"Search Tools": "Uirlisí Cuardaigh",
|
||||
"SearchApi API Key": "Eochair API SearchAPI",
|
||||
"SearchApi Engine": "Inneall SearchAPI",
|
||||
@@ -748,7 +761,7 @@
|
||||
"Select a base model": "Roghnaigh bunmhúnla",
|
||||
"Select a engine": "Roghnaigh inneall",
|
||||
"Select a function": "Roghnaigh feidhm",
|
||||
"Select a group": "",
|
||||
"Select a group": "Roghnaigh grúpa",
|
||||
"Select a model": "Roghnaigh samhail",
|
||||
"Select a pipeline": "Roghnaigh píblíne",
|
||||
"Select a pipeline url": "Roghnaigh url píblíne",
|
||||
@@ -771,7 +784,7 @@
|
||||
"Set as default": "Socraigh mar réamhshocraithe",
|
||||
"Set CFG Scale": "Socraigh Scála CFG",
|
||||
"Set Default Model": "Socraigh Samhail Réamhshocrú",
|
||||
"Set embedding model": "",
|
||||
"Set embedding model": "Socraigh samhail leabaithe",
|
||||
"Set embedding model (e.g. {{model}})": "Socraigh samhail leabaithe (m.sh. {{model}})",
|
||||
"Set Image Size": "Socraigh Méid Íomhá",
|
||||
"Set reranking model (e.g. {{model}})": "Socraigh samhail athrangú (m.sh. {{model}})",
|
||||
@@ -779,29 +792,29 @@
|
||||
"Set Scheduler": "Socraigh Sceidealóir",
|
||||
"Set Steps": "Socraigh Céimeanna",
|
||||
"Set Task Model": "Socraigh Samhail Tasc",
|
||||
"Set the number of GPU devices used for computation. This option controls how many GPU devices (if available) are used to process incoming requests. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "",
|
||||
"Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "",
|
||||
"Set the number of GPU devices used for computation. This option controls how many GPU devices (if available) are used to process incoming requests. Increasing this value can significantly improve performance for models that are optimized for GPU acceleration but may also consume more power and GPU resources.": "Socraigh líon na bhfeistí GPU a úsáidtear le haghaidh ríomh. Rialaíonn an rogha seo cé mhéad gléas GPU (má tá siad ar fáil) a úsáidtear chun iarratais isteach a phróiseáil. Is féidir leis an luach seo a mhéadú feabhas suntasach a chur ar fheidhmíocht do mhúnlaí atá optamaithe le haghaidh luasghéarú GPU ach d’fhéadfadh go n-ídíonn siad níos mó cumhachta agus acmhainní GPU freisin.",
|
||||
"Set the number of worker threads used for computation. This option controls how many threads are used to process incoming requests concurrently. Increasing this value can improve performance under high concurrency workloads but may also consume more CPU resources.": "Socraigh líon na snáitheanna oibrithe a úsáidtear le haghaidh ríomh. Rialaíonn an rogha seo cé mhéad snáithe a úsáidtear chun iarratais a thagann isteach a phróiseáil i gcomhthráth. D'fhéadfadh méadú ar an luach seo feidhmíocht a fheabhsú faoi ualaí oibre comhairgeadra ard ach féadfaidh sé níos mó acmhainní LAP a úsáid freisin.",
|
||||
"Set Voice": "Socraigh Guth",
|
||||
"Set whisper model": "Socraigh múnla cogar",
|
||||
"Sets how far back for the model to look back to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx)": "",
|
||||
"Sets how strongly to penalize repetitions. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. (Default: 1.1)": "",
|
||||
"Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt. (Default: random)": "",
|
||||
"Sets the size of the context window used to generate the next token. (Default: 2048)": "",
|
||||
"Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "",
|
||||
"Sets how far back for the model to look back to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx)": "Socraíonn sé cé chomh fada siar is atá an tsamhail le breathnú siar chun athrá a chosc. (Réamhshocrú: 64, 0 = díchumasaithe, -1 = num_ctx)",
|
||||
"Sets how strongly to penalize repetitions. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. (Default: 1.1)": "Socraíonn sé cé chomh láidir is féidir pionós a ghearradh ar athrá. Cuirfidh luach níos airde (m.sh., 1.5) pionós níos láidre ar athrá, agus beidh luach níos ísle (m.sh., 0.9) níos boige. (Réamhshocrú: 1.1)",
|
||||
"Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt. (Default: random)": "Socraíonn sé an síol uimhir randamach a úsáid le haghaidh giniúna. Má shocraítear é seo ar uimhir shainiúil, ginfidh an tsamhail an téacs céanna don leid céanna. (Réamhshocrú: randamach)",
|
||||
"Sets the size of the context window used to generate the next token. (Default: 2048)": "Socraíonn sé méid na fuinneoige comhthéacs a úsáidtear chun an chéad chomhartha eile a ghiniúint. (Réamhshocrú: 2048)",
|
||||
"Sets the stop sequences to use. When this pattern is encountered, the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile.": "Socraíonn sé na stadanna le húsáid. Nuair a thagtar ar an bpatrún seo, stopfaidh an LLM ag giniúint téacs agus ag filleadh. Is féidir patrúin stad iolracha a shocrú trí pharaiméadair stadanna iolracha a shonrú i gcomhad samhail.",
|
||||
"Settings": "Socruithe",
|
||||
"Settings saved successfully!": "Socruithe sábhálta go rathúil!",
|
||||
"Share": "Comhroinn",
|
||||
"Share Chat": "Comhroinn Comhrá",
|
||||
"Share to OpenWebUI Community": "Comhroinn le Pobal OpenWebUI",
|
||||
"Show": "Taispeáin",
|
||||
"Show \"What's New\" modal on login": "",
|
||||
"Show \"What's New\" modal on login": "Taispeáin módúil \"Cad atá Nua\" ar logáil isteach",
|
||||
"Show Admin Details in Account Pending Overlay": "Taispeáin Sonraí Riaracháin sa Chuntas ar Feitheamh Forleagan",
|
||||
"Show shortcuts": "Taispeáin aicearraí",
|
||||
"Show your support!": "Taispeáin do thacaíocht!",
|
||||
"Showcased creativity": "Cruthaitheacht léirithe",
|
||||
"Sign in": "Sínigh isteach",
|
||||
"Sign in to {{WEBUI_NAME}}": "Sínigh isteach ar {{WEBUI_NAME}}",
|
||||
"Sign in to {{WEBUI_NAME}} with LDAP": "",
|
||||
"Sign in to {{WEBUI_NAME}} with LDAP": "Sínigh isteach ar {{WEBUI_NAME}} le LDAP",
|
||||
"Sign Out": "Sínigh Amach",
|
||||
"Sign up": "Cláraigh",
|
||||
"Sign up to {{WEBUI_NAME}}": "Cláraigh le {{WEBUI_NAME}}",
|
||||
@@ -826,7 +839,7 @@
|
||||
"System Instructions": "Treoracha Córas",
|
||||
"System Prompt": "Córas Pras",
|
||||
"Tags Generation Prompt": "Clibeanna Giniúint Pras",
|
||||
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "",
|
||||
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "Úsáidtear sampláil saor ó eireabaill chun tionchar na n-chomharthaí ón aschur nach bhfuil chomh dóchúil céanna a laghdú. Laghdóidh luach níos airde (m.sh., 2.0) an tionchar níos mó, agus díchumasaíonn luach 1.0 an socrú seo. (réamhshocraithe: 1)",
|
||||
"Tap to interrupt": "Tapáil chun cur isteach",
|
||||
"Tavily API Key": "Eochair API Tavily",
|
||||
"Tell us more:": "Inis dúinn níos mó:",
|
||||
@@ -837,30 +850,30 @@
|
||||
"Text-to-Speech Engine": "Inneall téacs-go-labhra",
|
||||
"Tfs Z": "TFS Z",
|
||||
"Thanks for your feedback!": "Go raibh maith agat as do chuid aiseolas!",
|
||||
"The Application Account DN you bind with for search": "",
|
||||
"The base to search for users": "",
|
||||
"The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory. (Default: 512)": "",
|
||||
"The Application Account DN you bind with for search": "An Cuntas Feidhmchláir DN a nascann tú leis le haghaidh cuardaigh",
|
||||
"The base to search for users": "An bonn chun cuardach a dhéanamh ar úsáideoirí",
|
||||
"The batch size determines how many text requests are processed together at once. A higher batch size can increase the performance and speed of the model, but it also requires more memory. (Default: 512)": "Cinneann méid an bhaisc cé mhéad iarratas téacs a phróiseáiltear le chéile ag an am céanna. Is féidir le méid baisc níos airde feidhmíocht agus luas an mhúnla a mhéadú, ach éilíonn sé níos mó cuimhne freisin. (Réamhshocrú: 512)",
|
||||
"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Is deonacha paiseanta ón bpobal iad na forbróirí taobh thiar den bhreiseán seo. Má aimsíonn an breiseán seo cabhrach leat, smaoinigh ar rannchuidiú lena fhorbairt.",
|
||||
"The evaluation leaderboard is based on the Elo rating system and is updated in real-time.": "Tá an clár ceannairí meastóireachta bunaithe ar chóras rátála Elo agus déantar é a nuashonrú i bhfíor-am.",
|
||||
"The LDAP attribute that maps to the username that users use to sign in.": "",
|
||||
"The LDAP attribute that maps to the username that users use to sign in.": "An tréith LDAP a mhapálann don ainm úsáideora a úsáideann úsáideoirí chun síniú isteach.",
|
||||
"The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.": "Tá an clár ceannairí i béite faoi láthair, agus d'fhéadfaimis na ríomhanna rátála a choigeartú de réir mar a dhéanfaimid an t-algartam a bheachtú.",
|
||||
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "Uasmhéid an chomhaid i MB. Má sháraíonn méid an chomhaid an teorainn seo, ní uaslódófar an comhad.",
|
||||
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "An líon uasta na gcomhaid is féidir a úsáid ag an am céanna i gcomhrá. Má sháraíonn líon na gcomhaid an teorainn seo, ní uaslódófar na comhaid.",
|
||||
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "Ba chóir go mbeadh an scór ina luach idir 0.0 (0%) agus 1.0 (100%).",
|
||||
"The temperature of the model. Increasing the temperature will make the model answer more creatively. (Default: 0.8)": "",
|
||||
"The temperature of the model. Increasing the temperature will make the model answer more creatively. (Default: 0.8)": "Teocht an mhúnla. Déanfaidh méadú ar an teocht an freagra múnla níos cruthaithí. (Réamhshocrú: 0.8)",
|
||||
"Theme": "Téama",
|
||||
"Thinking...": "Smaointeoireacht...",
|
||||
"This action cannot be undone. Do you wish to continue?": "Ní féidir an gníomh seo a chur ar ais. Ar mhaith leat leanúint ar aghaidh?",
|
||||
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Cinntíonn sé seo go sábhálfar do chomhráite luachmhara go daingean i do bhunachar sonraí cúltaca Go raibh maith agat!",
|
||||
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Is gné turgnamhach í seo, b'fhéidir nach bhfeidhmeoidh sé mar a bhíothas ag súil leis agus tá sé faoi réir athraithe ag am ar bith.",
|
||||
"This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics. (Default: 24)": "",
|
||||
"This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated. (Default: 128)": "",
|
||||
"This option controls how many tokens are preserved when refreshing the context. For example, if set to 2, the last 2 tokens of the conversation context will be retained. Preserving context can help maintain the continuity of a conversation, but it may reduce the ability to respond to new topics. (Default: 24)": "Rialaíonn an rogha seo cé mhéad comhartha a chaomhnaítear agus an comhthéacs á athnuachan. Mar shampla, má shocraítear go 2 é, coinneofar an 2 chomhartha dheireanacha de chomhthéacs an chomhrá. Is féidir le comhthéacs a chaomhnú cabhrú le leanúnachas comhrá a choinneáil, ach d’fhéadfadh sé laghdú a dhéanamh ar an gcumas freagairt do thopaicí nua. (Réamhshocrú: 24)",
|
||||
"This option sets the maximum number of tokens the model can generate in its response. Increasing this limit allows the model to provide longer answers, but it may also increase the likelihood of unhelpful or irrelevant content being generated. (Default: 128)": "Socraíonn an rogha seo an t-uaslíon comharthaí is féidir leis an tsamhail a ghiniúint ina fhreagra. Tríd an teorainn seo a mhéadú is féidir leis an tsamhail freagraí níos faide a sholáthar, ach d’fhéadfadh go méadódh sé an dóchúlacht go nginfear ábhar neamhchabhrach nó nach mbaineann le hábhar. (Réamhshocrú: 128)",
|
||||
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "Scriosfaidh an rogha seo gach comhad atá sa bhailiúchán agus cuirfear comhaid nua-uaslódála ina n-ionad.",
|
||||
"This response was generated by \"{{model}}\"": "Gin an freagra seo ag \"{{model}}\"",
|
||||
"This will delete": "Scriosfaidh sé seo",
|
||||
"This will delete <strong>{{NAME}}</strong> and <strong>all its contents</strong>.": "Scriosfaidh sé seo <strong>{{NAME}}</strong> agus <strong>a bhfuil ann go léir</strong>.",
|
||||
"This will delete all models including custom models": "",
|
||||
"This will delete all models including custom models and cannot be undone.": "",
|
||||
"This will delete all models including custom models": "Scriosfaidh sé seo gach múnla lena n-áirítear samhlacha saincheaptha",
|
||||
"This will delete all models including custom models and cannot be undone.": "Scriosfaidh sé seo gach samhail lena n-áirítear samhlacha saincheaptha agus ní féidir é a chealú.",
|
||||
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Déanfaidh sé seo an bonn eolais a athshocrú agus gach comhad a shioncronú. Ar mhaith leat leanúint ar aghaidh?",
|
||||
"Thorough explanation": "Míniú críochnúil",
|
||||
"Tika": "Tika",
|
||||
@@ -872,7 +885,7 @@
|
||||
"Title Auto-Generation": "Teideal Auto-Generation",
|
||||
"Title cannot be an empty string.": "Ní féidir leis an teideal a bheith ina teaghrán folamh.",
|
||||
"Title Generation Prompt": "Pras Giniúint Teideal",
|
||||
"TLS": "",
|
||||
"TLS": "TLS",
|
||||
"To access the available model names for downloading,": "Chun teacht ar na hainmneacha múnla atá ar fáil le híoslódáil,",
|
||||
"To access the GGUF models available for downloading,": "Chun rochtain a fháil ar na múnlaí GGUF atá ar fáil le híoslódáil,",
|
||||
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Chun rochtain a fháil ar an WebUI, déan teagmháil leis an riarthóir le do thoil. Is féidir le riarthóirí stádas úsáideora a bhainistiú ón bPainéal Riaracháin.",
|
||||
@@ -890,19 +903,19 @@
|
||||
"Too verbose": "Ró-fhocal",
|
||||
"Tool created successfully": "Uirlis cruthaithe go rathúil",
|
||||
"Tool deleted successfully": "Uirlis scriosta go rathúil",
|
||||
"Tool Description": "",
|
||||
"Tool ID": "",
|
||||
"Tool Description": "Cur síos ar an Uirlis",
|
||||
"Tool ID": "ID Uirlis",
|
||||
"Tool imported successfully": "Uirlis iompórtáilte",
|
||||
"Tool Name": "",
|
||||
"Tool Name": "Ainm Uirlis",
|
||||
"Tool updated successfully": "An uirlis nuashonraithe",
|
||||
"Tools": "Uirlisí",
|
||||
"Tools Access": "",
|
||||
"Tools Access": "Rochtain Uirlisí",
|
||||
"Tools are a function calling system with arbitrary code execution": "Is córas glaonna feidhme iad uirlisí le forghníomhú cód treallach",
|
||||
"Tools have a function calling system that allows arbitrary code execution": "Tá córas glaonna feidhme ag uirlisí a cheadaíonn forghníomhú cód treallach",
|
||||
"Tools have a function calling system that allows arbitrary code execution.": "Tá córas glaonna feidhme ag uirlisí a cheadaíonn forghníomhú cód treallach.",
|
||||
"Top K": "Barr K",
|
||||
"Top P": "Barr P",
|
||||
"Transformers": "",
|
||||
"Transformers": "Claochladáin",
|
||||
"Trouble accessing Ollama?": "Deacracht teacht ar Ollama?",
|
||||
"TTS Model": "TTS Múnla",
|
||||
"TTS Settings": "Socruithe TTS",
|
||||
@@ -911,12 +924,12 @@
|
||||
"Type Hugging Face Resolve (Download) URL": "Cineál Hugging Face Resolve (Íoslódáil) URL",
|
||||
"Uh-oh! There was an issue connecting to {{provider}}.": "Uh-oh! Bhí ceist ann ag nascadh le {{provider}}.",
|
||||
"UI": "UI",
|
||||
"Unarchive All": "",
|
||||
"Unarchive All Archived Chats": "",
|
||||
"Unarchive Chat": "",
|
||||
"Unlock mysteries": "",
|
||||
"Unarchive All": "Díchartlannaigh Uile",
|
||||
"Unarchive All Archived Chats": "Díchartlannaigh Gach Comhrá Cartlainne",
|
||||
"Unarchive Chat": "Comhrá a dhíchartlannú",
|
||||
"Unlock mysteries": "Díghlasáil rúndiamhra",
|
||||
"Unpin": "Díphoráil",
|
||||
"Unravel secrets": "",
|
||||
"Unravel secrets": "Rúin a réiteach",
|
||||
"Untagged": "Gan chlib",
|
||||
"Update": "Nuashonraigh",
|
||||
"Update and Copy Link": "Nuashonraigh agus Cóipeáil Nasc",
|
||||
@@ -932,18 +945,18 @@
|
||||
"Upload Files": "Uaslódáil Comhaid",
|
||||
"Upload Pipeline": "Uaslódáil píblíne",
|
||||
"Upload Progress": "Uaslódáil an Dul",
|
||||
"URL": "",
|
||||
"URL": "URL",
|
||||
"URL Mode": "Mód URL",
|
||||
"Use '#' in the prompt input to load and include your knowledge.": "Úsáid '#' san ionchur pras chun do chuid eolais a lódáil agus a chur san áireamh.",
|
||||
"Use Gravatar": "Úsáid Gravatar",
|
||||
"Use groups to group your users and assign permissions.": "",
|
||||
"Use groups to group your users and assign permissions.": "Úsáid grúpaí chun d'úsáideoirí a ghrúpáil agus ceadanna a shannadh",
|
||||
"Use Initials": "Úsáid ceannlitreacha",
|
||||
"use_mlock (Ollama)": "use_mlock (Ollama)",
|
||||
"use_mmap (Ollama)": "use_mmap (Ollama)",
|
||||
"user": "úsáideoir",
|
||||
"User": "Úsáideoir",
|
||||
"User location successfully retrieved.": "Fuarthas suíomh an úsáideora go rathúil.",
|
||||
"Username": "",
|
||||
"Username": "Ainm Úsáideora",
|
||||
"Users": "Úsáideoirí",
|
||||
"Using the default arena model with all models. Click the plus button to add custom models.": "Ag baint úsáide as an múnla réimse réamhshocraithe le gach múnlaí. Cliceáil ar an gcnaipe móide chun múnlaí saincheaptha a chur leis.",
|
||||
"Utilize": "Úsáid",
|
||||
@@ -955,12 +968,12 @@
|
||||
"variable to have them replaced with clipboard content.": "athróg chun ábhar gearrthaisce a chur in ionad iad.",
|
||||
"Version": "Leagan",
|
||||
"Version {{selectedVersion}} of {{totalVersions}}": "Leagan {{selectedVersion}} de {{totalVersions}}",
|
||||
"Visibility": "",
|
||||
"Visibility": "Infheictheacht",
|
||||
"Voice": "Guth",
|
||||
"Voice Input": "Ionchur Gutha",
|
||||
"Warning": "Rabhadh",
|
||||
"Warning:": "Rabhadh:",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "",
|
||||
"Warning: Enabling this will allow users to upload arbitrary code on the server.": "Rabhadh: Cuirfidh sé seo ar chumas úsáideoirí cód treallach a uaslódáil ar an bhfreastalaí.",
|
||||
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Rabhadh: Má nuashonraíonn tú nó má athraíonn tú do mhúnla leabaithe, beidh ort gach doiciméad a athiompórtáil.",
|
||||
"Web": "Gréasán",
|
||||
"Web API": "API Gréasáin",
|
||||
@@ -969,29 +982,30 @@
|
||||
"Web Search Engine": "Inneall Cuardaigh Gréasáin",
|
||||
"Webhook URL": "URL Webhook",
|
||||
"WebUI Settings": "Socruithe WebUI",
|
||||
"WebUI will make requests to \"{{url}}/api/chat\"": "",
|
||||
"WebUI will make requests to \"{{url}}/chat/completions\"": "",
|
||||
"What are you trying to achieve?": "",
|
||||
"What are you working on?": "",
|
||||
"WebUI will make requests to \"{{url}}/api/chat\"": "Déanfaidh WebUI iarratais ar \"{{url}}/api/chat\"",
|
||||
"WebUI will make requests to \"{{url}}/chat/completions\"": "Déanfaidh WebUI iarratais ar \"{{url}}/chat/completions\"",
|
||||
"What are you trying to achieve?": "Cad atá tú ag iarraidh a bhaint amach?",
|
||||
"What are you working on?": "Cad air a bhfuil tú ag obair?",
|
||||
"What’s New in": "Cad atá Nua i",
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "Nuair a bheidh sé cumasaithe, freagróidh an tsamhail gach teachtaireacht comhrá i bhfíor-am, ag giniúint freagra a luaithe a sheolann an t-úsáideoir teachtaireacht. Tá an mód seo úsáideach le haghaidh feidhmchláir chomhrá beo, ach d’fhéadfadh tionchar a bheith aige ar fheidhmíocht ar chrua-earraí níos moille.",
|
||||
"wherever you are": "aon áit a bhfuil tú",
|
||||
"Whisper (Local)": "Whisper (Áitiúil)",
|
||||
"Why?": "Cén fáth?",
|
||||
"Widescreen Mode": "Mód Leathanscáileán",
|
||||
"Won": "Bhuaigh",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "Oibríonn sé le barr-k. Beidh téacs níos éagsúla mar thoradh ar luach níos airde (m.sh., 0.95), agus ginfidh luach níos ísle (m.sh., 0.5) téacs níos dírithe agus níos coimeádaí. (Réamhshocrú: 0.9)",
|
||||
"Workspace": "Spás oibre",
|
||||
"Workspace Permissions": "",
|
||||
"Workspace Permissions": "Ceadanna Spás Oibre",
|
||||
"Write a prompt suggestion (e.g. Who are you?)": "Scríobh moladh pras (m.sh. Cé hé tú?)",
|
||||
"Write a summary in 50 words that summarizes [topic or keyword].": "Scríobh achoimre i 50 focal a dhéanann achoimre ar [ábhar nó eochairfhocal].",
|
||||
"Write something...": "Scríobh rud...",
|
||||
"Write your model template content here": "",
|
||||
"Write your model template content here": "Scríobh do mhúnla ábhar teimpléad anseo",
|
||||
"Yesterday": "Inné",
|
||||
"You": "Tú",
|
||||
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "Ní féidir leat comhrá a dhéanamh ach le comhad {{maxCount}} ar a mhéad ag an am.",
|
||||
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "Is féidir leat do chuid idirghníomhaíochtaí le LLManna a phearsantú ach cuimhní cinn a chur leis tríd an gcnaipe 'Bainistigh' thíos, rud a fhágann go mbeidh siad níos cabhrach agus níos oiriúnaí duit.",
|
||||
"You cannot upload an empty file.": "Ní féidir leat comhad folamh a uaslódáil.",
|
||||
"You do not have permission to upload files.": "",
|
||||
"You do not have permission to upload files.": "Níl cead agat comhaid a uaslódáil.",
|
||||
"You have no archived conversations.": "Níl aon chomhráite cartlainne agat.",
|
||||
"You have shared this chat": "Tá an comhrá seo roinnte agat",
|
||||
"You're a helpful assistant.": "Is cúntóir cabhrach tú.",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "Hai già un account?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "un assistente",
|
||||
"and": "e",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "L'URL base AUTOMATIC1111 è obbligatorio.",
|
||||
"Available list": "",
|
||||
"available!": "disponibile!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "Indietro",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "Richieste simultanee",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "Conferma password",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "Predefinito (SentenceTransformers)",
|
||||
"Default Model": "Modello di default",
|
||||
"Default model updated": "Modello predefinito aggiornato",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "Suggerimenti prompt predefiniti",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "Elimina utente",
|
||||
"Deleted {{deleteModelTag}}": "Eliminato {{deleteModelTag}}",
|
||||
"Deleted {{name}}": "Eliminato {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "Descrizione",
|
||||
"Didn't fully follow instructions": "Non ha seguito completamente le istruzioni",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "Inserisci i codici lingua",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "Inserisci il tag del modello (ad esempio {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "Inserisci il numero di passaggi (ad esempio 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "Impossibile creare la chiave API.",
|
||||
"Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "Febbraio",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "Nascondi",
|
||||
"Host": "",
|
||||
"How can I help you today?": "Come posso aiutarti oggi?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "Ricerca ibrida",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Contenuto del file modello",
|
||||
"Models": "Modelli",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "Altro",
|
||||
"Name": "Nome",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "Nessun risultato trovato",
|
||||
"No search query generated": "Nessuna query di ricerca generata",
|
||||
"No source available": "Nessuna fonte disponibile",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "Rimuovi",
|
||||
"Remove Model": "Rimuovi modello",
|
||||
"Rename": "Rinomina",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "Ripeti ultimi N",
|
||||
"Request Mode": "Modalità richiesta",
|
||||
"Reranking Model": "Modello di riclassificazione",
|
||||
"Reranking model disabled": "Modello di riclassificazione disabilitato",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Modello di riclassificazione impostato su \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -978,6 +991,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "通話中に音声の割り込みを許可",
|
||||
"Already have an account?": "すでにアカウントをお持ちですか?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "アシスタント",
|
||||
"and": "および",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。",
|
||||
"Available list": "利用可能リスト",
|
||||
"available!": "利用可能!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "AzureAIスピーチ",
|
||||
"Azure Region": "Azureリージョン",
|
||||
"Back": "戻る",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "同時リクエスト",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "確認",
|
||||
"Confirm Password": "パスワードを確認",
|
||||
"Confirm your action": "あなたのアクションの確認",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "デフォルト (SentenceTransformers)",
|
||||
"Default Model": "デフォルトモデル",
|
||||
"Default model updated": "デフォルトモデルが更新されました",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "デフォルトのプロンプトの提案",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "ユーザーを削除",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} を削除しました",
|
||||
"Deleted {{name}}": "{{name}}を削除しました",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "説明",
|
||||
"Didn't fully follow instructions": "説明に沿って操作していませんでした",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "言語コードを入力してください",
|
||||
"Enter Model ID": "モデルIDを入力してください。",
|
||||
"Enter model tag (e.g. {{modelTag}})": "モデルタグを入力してください (例: {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "ステップ数を入力してください (例: 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "サンプラーを入力してください(e.g. Euler a)。",
|
||||
"Enter Scheduler (e.g. Karras)": "スケジューラーを入力してください。(e.g. Karras)",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "APIキーの作成に失敗しました。",
|
||||
"Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "設定アップデート失敗",
|
||||
"Failed to upload file.": "ファイルアップロード失敗",
|
||||
"February": "2月",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "非表示",
|
||||
"Host": "",
|
||||
"How can I help you today?": "今日はどのようにお手伝いしましょうか?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "ブリッジ検索",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "モデルファイルの内容",
|
||||
"Models": "モデル",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "もっと見る",
|
||||
"Name": "名前",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "知識が見つかりません",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "結果が見つかりません",
|
||||
"No search query generated": "検索クエリは生成されません",
|
||||
"No source available": "使用可能なソースがありません",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "削除",
|
||||
"Remove Model": "モデルを削除",
|
||||
"Rename": "名前を変更",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "最後の N を繰り返す",
|
||||
"Request Mode": "リクエストモード",
|
||||
"Reranking Model": "モデルの再ランキング",
|
||||
"Reranking model disabled": "再ランキングモデルが無効です",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "再ランキングモデルを \"{{reranking_model}}\" に設定しました",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "アップロードディレクトリをリセット",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -976,6 +989,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "ワイドスクリーンモード",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "",
|
||||
"Already have an account?": "უკვე გაქვს ანგარიში?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "ასისტენტი",
|
||||
"and": "და",
|
||||
"and {{COUNT}} more": "",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 საბაზისო მისამართი აუცილებელია",
|
||||
"Available list": "",
|
||||
"available!": "ხელმისაწვდომია!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "",
|
||||
"Azure Region": "",
|
||||
"Back": "უკან",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "",
|
||||
"Concurrent Requests": "თანმხლები მოთხოვნები",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "",
|
||||
"Confirm Password": "პაროლის დამოწმება",
|
||||
"Confirm your action": "",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "დეფოლტ (SentenceTransformers)",
|
||||
"Default Model": "ნაგულისხმები მოდელი",
|
||||
"Default model updated": "დეფოლტ მოდელი განახლებულია",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "დეფოლტ პრომპტი პირველი პირველი",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "მომხმარებლის წაშლა",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} წაშლილია",
|
||||
"Deleted {{name}}": "Deleted {{name}}",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "აღწერა",
|
||||
"Didn't fully follow instructions": "ვერ ყველა ინფორმაციისთვის ვერ ხელახლა ჩაწერე",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "შეიყვანეთ ენის კოდი",
|
||||
"Enter Model ID": "",
|
||||
"Enter model tag (e.g. {{modelTag}})": "შეიყვანეთ მოდელის ტეგი (მაგ. {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "შეიყვანეთ ნაბიჯების რაოდენობა (მაგ. 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "",
|
||||
"Enter Scheduler (e.g. Karras)": "",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "",
|
||||
"Failed to create API Key.": "API ღილაკის შექმნა ვერ მოხერხდა.",
|
||||
"Failed to read clipboard contents": "ბუფერში შიგთავსის წაკითხვა ვერ მოხერხდა",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "",
|
||||
"Failed to upload file.": "",
|
||||
"February": "თებერვალი",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "დამალვა",
|
||||
"Host": "",
|
||||
"How can I help you today?": "როგორ შემიძლია დაგეხმარო დღეს?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "ჰიბრიდური ძებნა",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "მოდელური ფაილის კონტენტი",
|
||||
"Models": "მოდელები",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "",
|
||||
"More": "ვრცლად",
|
||||
"Name": "სახელი",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "",
|
||||
"No model IDs": "",
|
||||
"No models found": "",
|
||||
"No models selected": "",
|
||||
"No results found": "ჩვენ ვერ პოულობით ნაპოვნი ჩაწერები",
|
||||
"No search query generated": "ძიების მოთხოვნა არ არის გენერირებული",
|
||||
"No source available": "წყარო არ არის ხელმისაწვდომი",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "პოპულარობის რაოდენობა",
|
||||
"Remove Model": "პოპულარობის რაოდენობა",
|
||||
"Rename": "პოპულარობის რაოდენობა",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "გაიმეორეთ ბოლო N",
|
||||
"Request Mode": "მოთხოვნის რეჟიმი",
|
||||
"Reranking Model": "რექვექტირება",
|
||||
"Reranking model disabled": "რექვექტირება არაა ჩართული",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Reranking model set to \"{{reranking_model}}\"",
|
||||
"Reset": "",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "",
|
||||
"Reset Vector Storage/Knowledge": "",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "",
|
||||
"Won": "",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"Allow Voice Interruption in Call": "음성 기능에서 음성 방해 허용",
|
||||
"Already have an account?": "이미 계정이 있으신가요?",
|
||||
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
|
||||
"Amazing": "",
|
||||
"an assistant": "어시스턴트",
|
||||
"and": "그리고",
|
||||
"and {{COUNT}} more": "그리고 {{COUNT}} 더",
|
||||
@@ -95,6 +96,7 @@
|
||||
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 기본 URL 설정이 필요합니다.",
|
||||
"Available list": "가능한 목록",
|
||||
"available!": "사용 가능!",
|
||||
"Awful": "",
|
||||
"Azure AI Speech": "Azure AI 음성",
|
||||
"Azure Region": "Azure 지역",
|
||||
"Back": "뒤로가기",
|
||||
@@ -165,6 +167,7 @@
|
||||
"Completions": "완성됨",
|
||||
"Concurrent Requests": "동시 요청 수",
|
||||
"Configure": "",
|
||||
"Configure Models": "",
|
||||
"Confirm": "확인",
|
||||
"Confirm Password": "비밀번호 확인",
|
||||
"Confirm your action": "액션 확인",
|
||||
@@ -213,6 +216,7 @@
|
||||
"Default (SentenceTransformers)": "기본값 (SentenceTransformers)",
|
||||
"Default Model": "기본 모델",
|
||||
"Default model updated": "기본 모델이 업데이트되었습니다.",
|
||||
"Default Models": "",
|
||||
"Default permissions": "",
|
||||
"Default permissions updated successfully": "",
|
||||
"Default Prompt Suggestions": "기본 프롬프트 제안",
|
||||
@@ -234,6 +238,7 @@
|
||||
"Delete User": "사용자 삭제",
|
||||
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} 삭제됨",
|
||||
"Deleted {{name}}": "{{name}}을(를) 삭제했습니다.",
|
||||
"Deleted User": "",
|
||||
"Describe your knowledge base and objectives": "",
|
||||
"Description": "설명",
|
||||
"Didn't fully follow instructions": "완전히 지침을 따르지 않음",
|
||||
@@ -326,6 +331,7 @@
|
||||
"Enter language codes": "언어 코드 입력",
|
||||
"Enter Model ID": "모델 ID 입력",
|
||||
"Enter model tag (e.g. {{modelTag}})": "모델 태그 입력(예: {{modelTag}})",
|
||||
"Enter Mojeek Search API Key": "",
|
||||
"Enter Number of Steps (e.g. 50)": "단계 수 입력(예: 50)",
|
||||
"Enter Sampler (e.g. Euler a)": "샘플러 입력 (예: 오일러 a(Euler a))",
|
||||
"Enter Scheduler (e.g. Karras)": "스케쥴러 입력 (예: 카라스(Karras))",
|
||||
@@ -379,6 +385,7 @@
|
||||
"Failed to add file.": "파일추가에 실패했습니다",
|
||||
"Failed to create API Key.": "API 키 생성에 실패했습니다.",
|
||||
"Failed to read clipboard contents": "클립보드 내용 가져오기를 실패하였습니다.",
|
||||
"Failed to save models configuration": "",
|
||||
"Failed to update settings": "설정 업데이트에 실패하였습니다.",
|
||||
"Failed to upload file.": "파일 업로드에 실패했습니다",
|
||||
"February": "2월",
|
||||
@@ -449,6 +456,7 @@
|
||||
"Hide": "숨기기",
|
||||
"Host": "",
|
||||
"How can I help you today?": "오늘 어떻게 도와드릴까요?",
|
||||
"How would you rate this response?": "",
|
||||
"Hybrid Search": "하이브리드 검색",
|
||||
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
|
||||
"ID": "ID",
|
||||
@@ -565,6 +573,8 @@
|
||||
"Modelfile Content": "Modelfile 내용",
|
||||
"Models": "모델",
|
||||
"Models Access": "",
|
||||
"Models configuration saved successfully": "",
|
||||
"Mojeek Search API Key": "",
|
||||
"more": "더보기",
|
||||
"More": "더보기",
|
||||
"Name": "이름",
|
||||
@@ -583,6 +593,7 @@
|
||||
"No knowledge found": "지식 기반 없음",
|
||||
"No model IDs": "",
|
||||
"No models found": "모델 없음",
|
||||
"No models selected": "",
|
||||
"No results found": "결과 없음",
|
||||
"No search query generated": "검색어가 생성되지 않았습니다.",
|
||||
"No source available": "사용 가능한 소스 없음",
|
||||
@@ -693,12 +704,14 @@
|
||||
"Remove": "삭제",
|
||||
"Remove Model": "모델 삭제",
|
||||
"Rename": "이름 변경",
|
||||
"Reorder Models": "",
|
||||
"Repeat Last N": "마지막 N 반복",
|
||||
"Request Mode": "요청 모드",
|
||||
"Reranking Model": "Reranking 모델",
|
||||
"Reranking model disabled": "Reranking 모델 비활성화",
|
||||
"Reranking model set to \"{{reranking_model}}\"": "Reranking 모델을 \"{{reranking_model}}\"로 설정",
|
||||
"Reset": "초기화",
|
||||
"Reset All Models": "",
|
||||
"Reset Upload Directory": "업로드 디렉토리 초기화",
|
||||
"Reset Vector Storage/Knowledge": "벡터 저장 공간/지식 기반 초기화",
|
||||
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "웹사이트 권환과 같이 응답 알림이 활성화될 수 없습니다. 필요한 접근을 사용하기 위해 브라우져 설정을 확인 부탁드립니다.",
|
||||
@@ -977,6 +990,7 @@
|
||||
"When enabled, the model will respond to each chat message in real-time, generating a response as soon as the user sends a message. This mode is useful for live chat applications, but may impact performance on slower hardware.": "",
|
||||
"wherever you are": "",
|
||||
"Whisper (Local)": "Whisper (로컬)",
|
||||
"Why?": "",
|
||||
"Widescreen Mode": "와이드스크린 모드",
|
||||
"Won": "이김",
|
||||
"Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. (Default: 0.9)": "",
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
"code": "es-ES",
|
||||
"title": "Spanish (Español)"
|
||||
},
|
||||
{
|
||||
"code": "eu-ES",
|
||||
"title": "Basque (Euskara)"
|
||||
},
|
||||
{
|
||||
"code": "fa-IR",
|
||||
"title": "Persian (فارسی)"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user