mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into parser-v2
This commit is contained in:
10
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
10
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -69,16 +69,16 @@ body:
|
|||||||
required: false
|
required: false
|
||||||
|
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: idiot-check
|
id: user-check
|
||||||
attributes:
|
attributes:
|
||||||
label: Please tick the boxes
|
label: Please tick the boxes
|
||||||
description: Before submitting, please ensure that
|
description: Before submitting, please ensure that you have completed the following checklist
|
||||||
options:
|
options:
|
||||||
- label: You have explained the issue clearly, and included all relevant info
|
- label: I have explained the issue clearly, and I included all relevant info
|
||||||
required: true
|
required: true
|
||||||
- label: You've checked that this [issue hasn't already been raised](https://github.com/SillyTavern/SillyTavern/issues?q=is%3Aissue)
|
- label: I have checked that this [issue hasn't already been raised](https://github.com/SillyTavern/SillyTavern/issues?q=is%3Aissue)
|
||||||
required: true
|
required: true
|
||||||
- label: You've checked the [docs](https://docs.sillytavern.app/) 
|
- label: I have checked the [docs](https://docs.sillytavern.app/) 
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
12
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
12
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -15,7 +15,7 @@ body:
|
|||||||
- 'No'
|
- 'No'
|
||||||
- 'Yes'
|
- 'Yes'
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: true
|
||||||
|
|
||||||
# Field 2 - Is it bug-related
|
# Field 2 - Is it bug-related
|
||||||
- type: textarea
|
- type: textarea
|
||||||
@@ -67,16 +67,16 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
# Field 7 - Can the user implement
|
# Field 7 - Can the user user test in staging
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: canImplement
|
id: canTestStaging
|
||||||
attributes:
|
attributes:
|
||||||
label: Is this something you would be keen to implement?
|
label: Are you willing to test this on staging/unstable branch if this is implemented?
|
||||||
description: Are you raising this ticket in order to get an issue number for your PR?
|
description: Otherwise you'll need to wait until the next stable release after the feature is developed.
|
||||||
options:
|
options:
|
||||||
- 'No'
|
- 'No'
|
||||||
- 'Maybe'
|
- 'Maybe'
|
||||||
- 'Yes!'
|
- 'Yes'
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
143
.github/readme.md
vendored
143
.github/readme.md
vendored
@@ -1,6 +1,8 @@
|
|||||||
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
English | [中文](readme-zh_cn.md) | [日本語](readme-ja_jp.md)
|
English | [中文](readme-zh_cn.md) | [日本語](readme-ja_jp.md)
|
||||||
|
|
||||||

|
![][cover]
|
||||||
|
|
||||||
Mobile-friendly layout, Multi-API (KoboldAI/CPP, Horde, NovelAI, Ooba, OpenAI, OpenRouter, Claude, Scale), VN-like Waifu Mode, Stable Diffusion, TTS, WorldInfo (lorebooks), customizable UI, auto-translate, and more prompt options than you'd ever want or need + ability to install third-party extensions.
|
Mobile-friendly layout, Multi-API (KoboldAI/CPP, Horde, NovelAI, Ooba, OpenAI, OpenRouter, Claude, Scale), VN-like Waifu Mode, Stable Diffusion, TTS, WorldInfo (lorebooks), customizable UI, auto-translate, and more prompt options than you'd ever want or need + ability to install third-party extensions.
|
||||||
|
|
||||||
@@ -22,6 +24,11 @@ SillyTavern is a user interface you can install on your computer (and Android ph
|
|||||||
|
|
||||||
SillyTavern is a fork of TavernAI 1.2.8 which is under more active development and has added many major features. At this point, they can be thought of as completely independent programs.
|
SillyTavern is a fork of TavernAI 1.2.8 which is under more active development and has added many major features. At this point, they can be thought of as completely independent programs.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
<img width="400" alt="image" src="https://github.com/SillyTavern/SillyTavern/assets/61471128/e902c7a2-45a6-4415-97aa-c59c597669c1">
|
||||||
|
<img width="400" alt="image" src="https://github.com/SillyTavern/SillyTavern/assets/61471128/f8a79c47-4fe9-4564-9e4a-bf247ed1c961">
|
||||||
|
|
||||||
### Branches
|
### Branches
|
||||||
|
|
||||||
SillyTavern is being developed using a two-branch system to ensure a smooth experience for all users.
|
SillyTavern is being developed using a two-branch system to ensure a smooth experience for all users.
|
||||||
@@ -31,36 +38,25 @@ SillyTavern is being developed using a two-branch system to ensure a smooth expe
|
|||||||
|
|
||||||
If you're not familiar with using the git CLI or don't understand what a branch is, don't worry! The release branch is always the preferable option for you.
|
If you're not familiar with using the git CLI or don't understand what a branch is, don't worry! The release branch is always the preferable option for you.
|
||||||
|
|
||||||
### What do I need other than Tavern?
|
### What do I need other than SillyTavern?
|
||||||
|
|
||||||
On its own Tavern is useless, as it's just a user interface. You have to have access to an AI system backend that can act as the roleplay character. There are various supported backends: OpenAPI API (GPT), KoboldAI (either running locally or on Google Colab), and more. You can read more about this in [the FAQ](https://docs.sillytavern.app/usage/faq/).
|
On its own SillyTavern is useless, as it's just a user interface. You have to have access to an AI system backend that can act as the roleplay character. There are various supported backends: OpenAPI API (GPT), KoboldAI (either running locally or on Google Colab), and more. You can read more about this in [the FAQ](https://docs.sillytavern.app/usage/faq/).
|
||||||
|
|
||||||
### Do I need a powerful PC to run Tavern?
|
### Do I need a powerful PC to run SillyTavern?
|
||||||
|
|
||||||
Since Tavern is only a user interface, it has tiny hardware requirements, it will run on anything. It's the AI system backend that needs to be powerful.
|
Since SillyTavern is only a user interface, it has tiny hardware requirements, it will run on anything. It's the AI system backend that needs to be powerful.
|
||||||
|
|
||||||
## Mobile support
|
|
||||||
|
|
||||||
> **Note**
|
|
||||||
|
|
||||||
> **This fork can be run natively on Android phones using Termux. Please refer to this guide by ArroganceComplex#2659:**
|
|
||||||
|
|
||||||
<https://rentry.org/STAI-Termux>
|
|
||||||
|
|
||||||
## Questions or suggestions?
|
## Questions or suggestions?
|
||||||
|
|
||||||
### We now have a community Discord server
|
### We now have a community Discord server
|
||||||
|
|
||||||
Get support, share favorite characters and prompts:
|
| [![][discord-shield-badge]][discord-link] | [Join our Discord community!](https://discord.gg/sillytavern) Get support, share favorite characters and prompts. |
|
||||||
|
| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
|
||||||
|
|
||||||
### [Join](https://discord.gg/sillytavern)
|
Or get in touch with the developers directly:
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
Get in touch with the developers directly:
|
|
||||||
|
|
||||||
* Discord: cohee or rossascends
|
* Discord: cohee or rossascends
|
||||||
* Reddit: /u/RossAscends or /u/sillylossy
|
* Reddit: [/u/RossAscends](https://www.reddit.com/user/RossAscends/) or [/u/sillylossy](https://www.reddit.com/user/sillylossy/)
|
||||||
* [Post a GitHub issue](https://github.com/SillyTavern/SillyTavern/issues)
|
* [Post a GitHub issue](https://github.com/SillyTavern/SillyTavern/issues)
|
||||||
|
|
||||||
## This version includes
|
## This version includes
|
||||||
@@ -124,61 +120,88 @@ A full list of included extensions and tutorials on how to use them can be found
|
|||||||
* Customizable page colors for 'main text', 'quoted text', and 'italics text'.
|
* Customizable page colors for 'main text', 'quoted text', and 'italics text'.
|
||||||
* Customizable UI background color and blur amount
|
* Customizable UI background color and blur amount
|
||||||
|
|
||||||
## Installation
|
# ⌛ Installation
|
||||||
|
|
||||||
*NOTE: This software is intended for local install purposes, and has not been thoroughly tested on a colab or other cloud notebook service.*
|
> \[!WARNING]
|
||||||
|
> * DO NOT INSTALL INTO ANY WINDOWS CONTROLLED FOLDER (Program Files, System32, etc).
|
||||||
|
> * DO NOT RUN START.BAT WITH ADMIN PERMISSIONS
|
||||||
|
> * INSTALLATION ON WINDOWS 7 IS IMPOSSIBLE AS IT CAN NOT RUN NODEJS 18.16
|
||||||
|
|
||||||
> **Warning**
|
## 🪟 Windows
|
||||||
|
|
||||||
> DO NOT INSTALL INTO ANY WINDOWS CONTROLLED FOLDER (Program Files, System32, etc).
|
|
||||||
|
|
||||||
> DO NOT RUN START.BAT WITH ADMIN PERMISSIONS
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
Installing via Git (recommended for easy updating)
|
|
||||||
|
|
||||||
An easy-to-follow guide with pretty pictures:
|
|
||||||
<https://docs.sillytavern.app/installation/windows/>
|
|
||||||
|
|
||||||
|
## Installing via Git
|
||||||
1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended)
|
1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended)
|
||||||
2. Install [GitHub Desktop](https://central.github.com/deployments/desktop/desktop/latest/win32)
|
2. Install [Git for Windows](https://gitforwindows.org/)
|
||||||
3. Open Windows Explorer (`Win+E`)
|
3. Open Windows Explorer (`Win+E`)
|
||||||
4. Browse to or Create a folder that is not controlled or monitored by Windows. (ex: C:\MySpecialFolder\)
|
4. Browse to or Create a folder that is not controlled or monitored by Windows. (ex: C:\MySpecialFolder\)
|
||||||
5. Open a Command Prompt inside that folder by clicking in the 'Address Bar' at the top, typing `cmd`, and pressing Enter.
|
5. Open a Command Prompt inside that folder by clicking in the 'Address Bar' at the top, typing `cmd`, and pressing Enter.
|
||||||
6. Once the black box (Command Prompt) pops up, type ONE of the following into it and press Enter:
|
6. Once the black box (Command Prompt) pops up, type ONE of the following into it and press Enter:
|
||||||
|
|
||||||
* for Release Branch: `git clone https://github.com/SillyTavern/SillyTavern -b release`
|
- for Release Branch: `git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||||
* for Staging Branch: `git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
- for Staging Branch: `git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||||
|
|
||||||
7. Once everything is cloned, double-click `Start.bat` to make NodeJS install its requirements.
|
7. Once everything is cloned, double-click `Start.bat` to make NodeJS install its requirements.
|
||||||
8. The server will then start, and SillyTavern will pop up in your browser.
|
8. The server will then start, and SillyTavern will pop up in your browser.
|
||||||
|
|
||||||
Installing via ZIP download (discouraged)
|
## Installing via SillyTavern Launcher
|
||||||
|
1. Install [Git for Windows](https://gitforwindows.org/)
|
||||||
|
2. Open Windows Explorer (`Win+E`) and make or choose a folder where you wanna install the launcher to
|
||||||
|
3. Open a Command Prompt inside that folder by clicking in the 'Address Bar' at the top, typing `cmd`, and pressing Enter.
|
||||||
|
4. When you see a black box, insert the following command: `git clone https://github.com/SillyTavern/SillyTavern-Launcher.git`
|
||||||
|
5. Double-click on `installer.bat` and choose what you wanna install
|
||||||
|
6. After installation double-click on `launcher.bat`
|
||||||
|
|
||||||
|
## Installing via GitHub Desktop
|
||||||
|
(This allows git usage **only** in GitHub Desktop, if you want to use `git` on the command line too, you also need to install [Git for Windows](https://gitforwindows.org/))
|
||||||
1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended)
|
1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended)
|
||||||
2. Download the zip from this GitHub repo. (Get the `Source code (zip)` from [Releases](https://github.com/SillyTavern/SillyTavern/releases/latest))
|
2. Install [GitHub Desktop](https://central.github.com/deployments/desktop/desktop/latest/win32)
|
||||||
3. Unzip it into a folder of your choice
|
3. After installing GitHub Desktop, click on `Clone a repository from the internet....` (Note: You **do NOT need** to create a GitHub account for this step)
|
||||||
4. Run `Start.bat` by double-clicking or in a command line.
|
4. On the menu, click the URL tab, enter this URL `https://github.com/SillyTavern/SillyTavern`, and click Clone. You can change the Local path to change where SillyTavern is going to be downloaded.
|
||||||
5. Once the server has prepared everything for you, it will open a tab in your browser.
|
6. To open SillyTavern, use Windows Explorer to browse into the folder where you cloned the repository. By default, the repository will be cloned here: `C:\Users\[Your Windows Username]\Documents\GitHub\SillyTavern`
|
||||||
|
7. Double-click on the `start.bat` file. (Note: the `.bat` part of the file name might be hidden by your OS, in that case, it will look like a file called "`Start`". This is what you double-click to run SillyTavern)
|
||||||
|
8. After double-clicking, a large black command console window should open and SillyTavern will begin to install what it needs to operate.
|
||||||
|
9. After the installation process, if everything is working, the command console window should look like this and a SillyTavern tab should be open in your browser:
|
||||||
|
10. Connect to any of the [supported APIs](https://docs.sillytavern.app/usage/api-connections/) and start chatting!
|
||||||
|
|
||||||
### Linux
|
## 🐧 Linux & 🍎 MacOS
|
||||||
|
|
||||||
#### Unofficial Debian/Ubuntu PKGBUILD
|
For MacOS / Linux all of these will be done in a Terminal.
|
||||||
|
|
||||||
> **This installation method is unofficial and not supported by the project. Report any issues to the PKGBUILD maintainer.**
|
1. Install git and nodeJS (the method for doing this will vary depending on your OS)
|
||||||
> The method is intended for Debian-based distributions (Ubuntu, Mint, etc).
|
2. Clone the repo
|
||||||
|
|
||||||
1. Install [makedeb](https://www.makedeb.org/).
|
- for Release Branch: `git clone https://github.com/SillyTavern/SillyTavern -b release`
|
||||||
2. Ensure you have Node.js v18 or higher installed by running `node -v`. If you need to upgrade, you can install a [node.js repo](https://mpr.makedeb.org/packages/nodejs-repo) (you'll might need to edit the version inside the PKGBUILD). As an alternative, install and configure [nvm](https://mpr.makedeb.org/packages/nvm) to manage multiple node.js installations. Finally, you can [install node.js manually](https://nodejs.org/en/download), but you will need to update the PATH variable of your environment.
|
- for Staging Branch: `git clone https://github.com/SillyTavern/SillyTavern -b staging`
|
||||||
3. Now build the [sillytavern package](https://mpr.makedeb.org/packages/sillytavern). The build needs to run with the correct node.js version.
|
|
||||||
|
|
||||||
#### Manual
|
3. `cd SillyTavern` to navigate into the install folder.
|
||||||
|
4. Run the `start.sh` script with one of these commands:
|
||||||
|
|
||||||
|
- `./start.sh`
|
||||||
|
- `bash start.sh`
|
||||||
|
|
||||||
|
## Installing via SillyTavern Launcher
|
||||||
|
|
||||||
|
### For Linux users
|
||||||
|
1. Open your favorite terminal and install git
|
||||||
|
2. Download Sillytavern Launcher with: `git clone https://github.com/SillyTavern/SillyTavern-Launcher.git`
|
||||||
|
3. Navigate to the SillyTavern-Launcher with: `cd SillyTavern-Launcher`
|
||||||
|
4. Start the install launcher with: `chmod +x install.sh && ./install.sh` and choose what you wanna install
|
||||||
|
5. After installation start the launcher with: `chmod +x launcher.sh && ./launcher.sh`
|
||||||
|
|
||||||
|
### For Mac users
|
||||||
|
1. Open a terminal and install brew with: `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
||||||
|
2. Then install git with: `brew install git`
|
||||||
|
3. Download Sillytavern Launcher with: `git clone https://github.com/SillyTavern/SillyTavern-Launcher.git`
|
||||||
|
4. Navigate to the SillyTavern-Launcher with: `cd SillyTavern-Launcher`
|
||||||
|
5. Start the install launcher with: `chmod +x install.sh && ./install.sh` and choose what you wanna install
|
||||||
|
6. After installation start the launcher with: `chmod +x launcher.sh && ./launcher.sh`
|
||||||
|
|
||||||
|
## 📱 Mobile - Installing via termux
|
||||||
|
|
||||||
|
> \[!NOTE]
|
||||||
|
> **SillyTavern can be run natively on Android phones using Termux. Please refer to this guide by ArroganceComplex#2659:**
|
||||||
|
> * <https://rentry.org/STAI-Termux>
|
||||||
|
|
||||||
1. Ensure you have Node.js v18 or higher (the latest [LTS version](https://nodejs.org/en/download/) is recommended) installed by running `node -v`.
|
|
||||||
Alternatively, use the [Node Version Manager](https://github.com/nvm-sh/nvm#installing-and-updating) script to quickly and easily manage your Node installations.
|
|
||||||
2. Run the `start.sh` script.
|
|
||||||
3. Enjoy.
|
|
||||||
|
|
||||||
## API keys management
|
## API keys management
|
||||||
|
|
||||||
@@ -222,7 +245,7 @@ or
|
|||||||
CIDR masks are also accepted (eg. 10.0.0.0/24).
|
CIDR masks are also accepted (eg. 10.0.0.0/24).
|
||||||
|
|
||||||
* Save the `whitelist.txt` file.
|
* Save the `whitelist.txt` file.
|
||||||
* Restart your TAI server.
|
* Restart your ST server.
|
||||||
|
|
||||||
Now devices which have the IP specified in the file will be able to connect.
|
Now devices which have the IP specified in the file will be able to connect.
|
||||||
|
|
||||||
@@ -293,10 +316,7 @@ You can find them archived here:
|
|||||||
|
|
||||||
<https://files.catbox.moe/1xevnc.zip>
|
<https://files.catbox.moe/1xevnc.zip>
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
|
|
||||||
<img width="400" alt="image" src="https://github.com/SillyTavern/SillyTavern/assets/61471128/e902c7a2-45a6-4415-97aa-c59c597669c1">
|
|
||||||
<img width="400" alt="image" src="https://github.com/SillyTavern/SillyTavern/assets/61471128/f8a79c47-4fe9-4564-9e4a-bf247ed1c961">
|
|
||||||
|
|
||||||
|
|
||||||
## License and credits
|
## License and credits
|
||||||
@@ -327,3 +347,10 @@ GNU Affero General Public License for more details.**
|
|||||||
* Korean translation by @doloroushyeonse
|
* Korean translation by @doloroushyeonse
|
||||||
* k_euler_a support for Horde by <https://github.com/Teashrock>
|
* k_euler_a support for Horde by <https://github.com/Teashrock>
|
||||||
* Chinese translation by [@XXpE3](https://github.com/XXpE3), 中文 ISSUES 可以联系 @XXpE3
|
* Chinese translation by [@XXpE3](https://github.com/XXpE3), 中文 ISSUES 可以联系 @XXpE3
|
||||||
|
|
||||||
|
<!-- LINK GROUP -->
|
||||||
|
[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square
|
||||||
|
[cover]: https://github.com/SillyTavern/SillyTavern/assets/18619528/c2be4c3f-aada-4f64-87a3-ae35a68b61a4
|
||||||
|
[discord-link]: https://discord.gg/sillytavern
|
||||||
|
[discord-shield]: https://img.shields.io/discord/1100685673633153084?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
|
||||||
|
[discord-shield-badge]: https://img.shields.io/discord/1100685673633153084?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge
|
||||||
|
73
.github/workflows/docker-publish.yml
vendored
73
.github/workflows/docker-publish.yml
vendored
@@ -1,45 +1,78 @@
|
|||||||
# This workflow will publish a docker image for every full release to the GitHub package repository
|
# This workflow will publish a docker image for every full release to the GitHub package repository
|
||||||
|
|
||||||
name: Create Docker Image on Release
|
name: Create Docker Image (Release and Staging)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
# Allow pre-releases
|
# Allow pre-releases
|
||||||
types: [published]
|
types: [published]
|
||||||
|
schedule:
|
||||||
|
# Build the staging image everyday at 00:00 UTC
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# This should allow creation of docker images even in forked repositories
|
# This should allow creation of docker images even in forked repositories
|
||||||
# Image name may not contain uppercase characters, so we can not use the repository name
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
# Creates a string like: ghcr.io/SillyTavern/sillytavern
|
REGISTRY: ghcr.io
|
||||||
image_name: ghcr.io/sillytavern/sillytavern
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
# Using the following workaround because currently GitHub Actions
|
||||||
|
# does not support logical AND/OR operations on triggers
|
||||||
|
# It's currently not possible to have `branches` under the `schedule` trigger
|
||||||
|
- name: Checkout the release branch
|
||||||
|
if: ${{ github.event_name == 'release' }}
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
ref: "release"
|
||||||
|
|
||||||
# Build docker image using dockerfile and tag it with branch name
|
- name: Checkout the staging branch
|
||||||
# Assumes branch name is the version number
|
if: ${{ github.event_name == 'schedule' }}
|
||||||
- name: Build the Docker image
|
uses: actions/checkout@v3
|
||||||
run: |
|
with:
|
||||||
docker build . --file Dockerfile --tag $image_name:${{ github.ref_name }}
|
ref: "staging"
|
||||||
|
|
||||||
|
# Setting up QEMU for multi-arch image build
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for the image
|
||||||
|
uses: docker/metadata-action@v5.5.1
|
||||||
|
id: metadata
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: ${{ github.ref_name }}
|
||||||
|
|
||||||
# Login into package repository as the person who created the release
|
# Login into package repository as the person who created the release
|
||||||
- name: Login to GitHub Container Registry
|
- name: Log in to the Container registry
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
# Assumes release is the latest and marks image as such
|
# Build docker image using dockerfile for amd64 and arm64
|
||||||
- name: Docker Tag and Push
|
# Tag it with branch name
|
||||||
|
# Assumes branch name is the version number
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v5.3.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
file: Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.metadata.outputs.tags }}
|
||||||
|
labels: ${{ steps.metadata.outputs.labels }}
|
||||||
|
|
||||||
|
# If the workflow is triggered by a release, marks and push the image as such
|
||||||
|
- name: Docker tag latest and push
|
||||||
|
if: ${{ github.event_name == 'release' }}
|
||||||
run: |
|
run: |
|
||||||
docker tag $image_name:${{ github.ref_name }} $image_name:latest
|
docker tag $IMAGE_NAME:${{ github.ref_name }} $IMAGE_NAME:latest
|
||||||
docker push $image_name:${{ github.ref_name }}
|
docker push $IMAGE_NAME:latest
|
||||||
docker push $image_name:latest
|
|
||||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.11.6",
|
"version": "1.11.7",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.11.6",
|
"version": "1.11.7",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@@ -59,7 +59,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||||
},
|
},
|
||||||
"version": "1.11.6",
|
"version": "1.11.7",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"start-multi": "node server.js --disableCsrf",
|
"start-multi": "node server.js --disableCsrf",
|
||||||
|
@@ -73,6 +73,11 @@
|
|||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.placeholder-expander {
|
||||||
|
cursor: alias;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.tagListHint {
|
.tagListHint {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -2758,15 +2758,17 @@
|
|||||||
<div class="drawer-content">
|
<div class="drawer-content">
|
||||||
<h3 class="margin0" data-i18n="Advanced Formatting">
|
<h3 class="margin0" data-i18n="Advanced Formatting">
|
||||||
Advanced Formatting
|
Advanced Formatting
|
||||||
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/" class="notes-link" target="_blank">
|
|
||||||
<span class="fa-solid fa-circle-question note-link-span"></span>
|
|
||||||
</a>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<div id="PygOverrides">
|
<div id="PygOverrides">
|
||||||
<div>
|
<div>
|
||||||
<h4 class="standoutHeader title_restorable">
|
<h4 class="standoutHeader title_restorable">
|
||||||
|
<div>
|
||||||
<span data-i18n="Context Template">Context Template</span>
|
<span data-i18n="Context Template">Context Template</span>
|
||||||
|
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#context-template" class="notes-link" target="_blank">
|
||||||
|
<span class="fa-solid fa-circle-question note-link-span"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<i data-newbie-hidden data-preset-manager-import="context" class="margin0 menu_button fa-solid fa-file-import" title="Import preset" data-i18n="[title]Import preset"></i>
|
<i data-newbie-hidden data-preset-manager-import="context" class="margin0 menu_button fa-solid fa-file-import" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||||
<i data-newbie-hidden data-preset-manager-export="context" class="margin0 menu_button fa-solid fa-file-export" title="Export preset" data-i18n="[title]Export preset"></i>
|
<i data-newbie-hidden data-preset-manager-export="context" class="margin0 menu_button fa-solid fa-file-export" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
"novelaipreserts": "Preajustes de NovelAI",
|
"novelaipreserts": "Preajustes de NovelAI",
|
||||||
"default": "Predeterminado",
|
"default": "Predeterminado",
|
||||||
"openaipresets": "Preajustes de OpenAI",
|
"openaipresets": "Preajustes de OpenAI",
|
||||||
"text gen webio(ooba) presets": "Preajustes de generación de texto WebUI(ooba)",
|
"text gen webio(ooba) presets": "Preajustes de Text Gen WebUI(ooba)",
|
||||||
"response legth(tokens)": "Longitud de respuesta (tokens)",
|
"response legth(tokens)": "Longitud de respuesta (tokens)",
|
||||||
"select": "Seleccionar",
|
"select": "Seleccionar",
|
||||||
"context size(tokens)": "Tamaño de contexto (tokens)",
|
"context size(tokens)": "Tamaño de contexto (tokens)",
|
||||||
@@ -13,17 +13,17 @@
|
|||||||
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Solo algunos modelos admiten tamaños de contexto mayores de 4096 tokens. Aumenta solo si sabes lo que estás haciendo.",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Solo algunos modelos admiten tamaños de contexto mayores de 4096 tokens. Aumenta solo si sabes lo que estás haciendo.",
|
||||||
"rep.pen": "Penalización de repetición",
|
"rep.pen": "Penalización de repetición",
|
||||||
"WI Entry Status:🔵 Constant🟢 Normal❌ Disabled": "Estado de entrada de WI:🔵 Constante🟢 Normal❌ Desactivado",
|
"WI Entry Status:🔵 Constant🟢 Normal❌ Disabled": "Estado de entrada de WI:🔵 Constante🟢 Normal❌ Desactivado",
|
||||||
"rep.pen range": "Rango de penalización de repetición",
|
"rep.pen range": "rango de penalización de repetición",
|
||||||
"Temperature controls the randomness in token selection": "La temperatura controla la aleatoriedad en la selección de tokens",
|
"Temperature controls the randomness in token selection": "La temperatura controla la aleatoriedad en la selección de tokens",
|
||||||
"temperature": "Temperatura",
|
"temperature": "Temperatura",
|
||||||
"Top K sets a maximum amount of top tokens that can be chosen from": "Top K establece una cantidad máxima de tokens principales que se pueden elegir",
|
"Top K sets a maximum amount of top tokens that can be chosen from": "Top K establece una cantidad máxima de tokens principales que se pueden elegir",
|
||||||
"Top P (a.k.a. nucleus sampling)": "Top P (también conocido como muestreo de núcleo)",
|
"Top P (a.k.a. nucleus sampling)": "Top P (también conocido como muestreo de núcleo)",
|
||||||
"Typical P Sampling prioritizes tokens based on their deviation from the average entropy of the set": "El muestreo P típico prioriza tokens según su desviación de la entropía promedio del conjunto",
|
"Typical P Sampling prioritizes tokens based on their deviation from the average entropy of the set": "El Muestreo P Típico prioriza tokens según su desviación de la entropía promedio del conjunto",
|
||||||
"Min P sets a base minimum probability": "Min P establece una probabilidad mínima base",
|
"Min P sets a base minimum probability": "Min P establece una probabilidad mínima base",
|
||||||
"Top A sets a threshold for token selection based on the square of the highest token probability": "Top A establece un umbral para la selección de tokens basado en el cuadrado de la probabilidad de token más alta",
|
"Top A sets a threshold for token selection based on the square of the highest token probability": "Top A establece un umbral para la selección de tokens basado en el cuadrado de la probabilidad de token más alta",
|
||||||
"Tail-Free Sampling (TFS)": "Muestreo sin cola (TFS)",
|
"Tail-Free Sampling (TFS)": "Muestreo sin cola (TFS)",
|
||||||
"Epsilon cutoff sets a probability floor below which tokens are excluded from being sampled": "El corte epsilon establece un límite de probabilidad por debajo del cual se excluyen los tokens de ser muestreados",
|
"Epsilon cutoff sets a probability floor below which tokens are excluded from being sampled": "El corte Epsilon establece un límite de probabilidad por debajo del cual se excluyen los tokens de ser muestreados",
|
||||||
"Scale Temperature dynamically per token, based on the variation of probabilities": "Escalas de temperatura dinámicamente por token, basado en la variación de probabilidades",
|
"Scale Temperature dynamically per token, based on the variation of probabilities": "Escala la Temperatura dinámicamente por token, basado en la variación de probabilidades",
|
||||||
"Minimum Temp": "Temperatura mínima",
|
"Minimum Temp": "Temperatura mínima",
|
||||||
"Maximum Temp": "Temperatura máxima",
|
"Maximum Temp": "Temperatura máxima",
|
||||||
"Exponent": "Exponente",
|
"Exponent": "Exponente",
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
"Variability parameter for Mirostat outputs": "Parámetro de variabilidad para las salidas de Mirostat",
|
"Variability parameter for Mirostat outputs": "Parámetro de variabilidad para las salidas de Mirostat",
|
||||||
"Learning rate of Mirostat": "Tasa de aprendizaje de Mirostat",
|
"Learning rate of Mirostat": "Tasa de aprendizaje de Mirostat",
|
||||||
"Strength of the Contrastive Search regularization term. Set to 0 to disable CS": "Fuerza del término de regularización de la Búsqueda Contrastiva. Establece en 0 para deshabilitar CS.",
|
"Strength of the Contrastive Search regularization term. Set to 0 to disable CS": "Fuerza del término de regularización de la Búsqueda Contrastiva. Establece en 0 para deshabilitar CS.",
|
||||||
"Temperature Last": "Última temperatura",
|
"Temperature Last": "Temperatura de Último",
|
||||||
"Use the temperature sampler last": "Usar el muestreador de temperatura al final",
|
"Use the temperature sampler last": "Usar el muestreador de temperatura al final",
|
||||||
"LLaMA / Mistral / Yi models only": "Solo modelos LLaMA / Mistral / Yi",
|
"LLaMA / Mistral / Yi models only": "Solo modelos LLaMA / Mistral / Yi",
|
||||||
"Example: some text [42, 69, 1337]": "Ejemplo: algún texto [42, 69, 1337]",
|
"Example: some text [42, 69, 1337]": "Ejemplo: algún texto [42, 69, 1337]",
|
||||||
"Classifier Free Guidance. More helpful tip coming soon": "Guía libre de clasificadores. Pronto llegará un consejo más útil",
|
"Classifier Free Guidance. More helpful tip coming soon": "Guía Libre de Clasificadores. Pronto llegará un consejo más útil",
|
||||||
"Scale": "Escala",
|
"Scale": "Escala",
|
||||||
"GBNF Grammar": "Gramática GBNF",
|
"GBNF Grammar": "Gramática GBNF",
|
||||||
"Usage Stats": "Estadísticas de uso",
|
"Usage Stats": "Estadísticas de uso",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"Add BOS Token": "Agregar token BOS",
|
"Add BOS Token": "Agregar token BOS",
|
||||||
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative": "Agrega el token BOS al principio de las indicaciones. Desactivar esto puede hacer que las respuestas sean más creativas",
|
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative": "Agrega el token BOS al principio de las indicaciones. Desactivar esto puede hacer que las respuestas sean más creativas",
|
||||||
"Ban EOS Token": "Prohibir token EOS",
|
"Ban EOS Token": "Prohibir token EOS",
|
||||||
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibir el token eos. Esto obliga al modelo a nunca terminar la generación prematuramente",
|
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibir el token EOS. Esto obliga al modelo a nunca terminar la generación prematuramente",
|
||||||
"Skip Special Tokens": "Omitir tokens especiales",
|
"Skip Special Tokens": "Omitir tokens especiales",
|
||||||
"Beam search": "Búsqueda de haz",
|
"Beam search": "Búsqueda de haz",
|
||||||
"Number of Beams": "Número de haces",
|
"Number of Beams": "Número de haces",
|
||||||
@@ -83,9 +83,9 @@
|
|||||||
"Contrastive search": "Búsqueda contrastiva",
|
"Contrastive search": "Búsqueda contrastiva",
|
||||||
"Penalty Alpha": "Alfa de penalización",
|
"Penalty Alpha": "Alfa de penalización",
|
||||||
"Seed": "Semilla",
|
"Seed": "Semilla",
|
||||||
"Epsilon Cutoff": "Corte epsilon",
|
"Epsilon Cutoff": "Corte Epsilon",
|
||||||
"Eta Cutoff": "Corte eta",
|
"Eta Cutoff": "Corte Eta",
|
||||||
"Negative Prompt": "Indicación negativa",
|
"Negative Prompt": "Indicaciónes negativas",
|
||||||
"Mirostat (mode=1 is only for llama.cpp)": "Mirostat (modo=1 es solo para llama.cpp)",
|
"Mirostat (mode=1 is only for llama.cpp)": "Mirostat (modo=1 es solo para llama.cpp)",
|
||||||
"Mirostat is a thermostat for output perplexity": "Mirostat es un termostato para la perplejidad de salida",
|
"Mirostat is a thermostat for output perplexity": "Mirostat es un termostato para la perplejidad de salida",
|
||||||
"Add text here that would make the AI generate things you don't want in your outputs.": "Agrega aquí texto que haría que la IA genere cosas que no quieres en tus salidas.",
|
"Add text here that would make the AI generate things you don't want in your outputs.": "Agrega aquí texto que haría que la IA genere cosas que no quieres en tus salidas.",
|
||||||
@@ -102,32 +102,32 @@
|
|||||||
"NSFW Encouraged": "NSFW Alentado",
|
"NSFW Encouraged": "NSFW Alentado",
|
||||||
"Tell the AI that NSFW is allowed.": "Indica a la IA que se permite contenido NSFW.",
|
"Tell the AI that NSFW is allowed.": "Indica a la IA que se permite contenido NSFW.",
|
||||||
"NSFW Prioritized": "NSFW Priorizado",
|
"NSFW Prioritized": "NSFW Priorizado",
|
||||||
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El texto de la indicación NSFW va primero en la indicación para enfatizar su efecto.",
|
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El texto de las indicaciones NSFW va primero en la indicación para enfatizar su efecto.",
|
||||||
"Streaming": "Transmisión",
|
"Streaming": "Transmisión (Streaming)",
|
||||||
"Dynamic Temperature": "Temperatura dinámica",
|
"Dynamic Temperature": "Temperatura dinámica",
|
||||||
"Restore current preset": "Restaurar la configuración actual",
|
"Restore current preset": "Restaurar el preajuste actual",
|
||||||
"Neutralize Samplers": "Neutralizar los muestreadores",
|
"Neutralize Samplers": "Neutralizar muestreadores",
|
||||||
"Text Completion presets": "Preajustes de completado de texto",
|
"Text Completion presets": "Preajustes de Completado de Texto",
|
||||||
"Documentation on sampling parameters": "Documentación sobre parámetros de muestreo",
|
"Documentation on sampling parameters": "Documentación sobre parámetros de muestreo",
|
||||||
"Set all samplers to their neutral/disabled state.": "Establecer todos los muestreadores en su estado neutral/desactivado.",
|
"Set all samplers to their neutral/disabled state.": "Establecer todos los muestreadores en su estado neutral/desactivado.",
|
||||||
"Only enable this if your model supports context sizes greater than 4096 tokens": "Habilita esto solo si tu modelo admite tamaños de contexto mayores de 4096 tokens",
|
"Only enable this if your model supports context sizes greater than 4096 tokens": "Habilita esto solo si tu modelo admite tamaños de contexto mayores de 4096 tokens",
|
||||||
"Display the response bit by bit as it is generated": "Mostrar la respuesta poco a poco según se genera",
|
"Display the response bit by bit as it is generated": "Mostrar la respuesta poco a poco según se genera",
|
||||||
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Generar solo una línea por solicitud (solo KoboldAI, ignorado por KoboldCpp).",
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Generar solo una línea por solicitud (solo KoboldAI, ignorado por KoboldCpp).",
|
||||||
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Prohibir el token Fin-de-secuencia (EOS) (con KoboldCpp, y posiblemente también otros tokens con KoboldAI).",
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Prohibir el token Fin-de-Secuencia (EOS) (con KoboldCpp, y posiblemente también otros tokens con KoboldAI).",
|
||||||
"Good for story writing, but should not be used for chat and instruct mode.": "Bueno para escribir historias, pero no debería usarse para el modo de chat e instrucción.",
|
"Good for story writing, but should not be used for chat and instruct mode.": "Bueno para escribir historias, pero no debería usarse para el modo de chat e instrucción.",
|
||||||
"Enhance Definitions": "Mejorar Definiciones",
|
"Enhance Definitions": "Mejorar Definiciones",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Utilizar la base de conocimientos de OAI para mejorar las definiciones de figuras públicas y personajes ficticios conocidos",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Utilizar la base de conocimientos de OAI para mejorar las definiciones de figuras públicas y personajes ficticios conocidos",
|
||||||
"Wrap in Quotes": "Envolver entre comillas",
|
"Wrap in Quotes": "Envolver entre comillas",
|
||||||
"Wrap entire user message in quotes before sending.": "Envolver todo el mensaje del usuario entre comillas antes de enviarlo.",
|
"Wrap entire user message in quotes before sending.": "Envolver todo el mensaje del usuario entre comillas antes de enviarlo.",
|
||||||
"Leave off if you use quotes manually for speech.": "Omite esto si usas comillas manualmente para el discurso.",
|
"Leave off if you use quotes manually for speech.": "Omite esto si usas comillas manualmente para diálogo.",
|
||||||
"Main prompt": "Indicación principal",
|
"Main prompt": "Indicaciónes principales",
|
||||||
"The main prompt used to set the model behavior": "La indicación principal utilizada para establecer el comportamiento del modelo",
|
"The main prompt used to set the model behavior": "Las indicaciónes principales utilizadas para establecer el comportamiento del modelo",
|
||||||
"NSFW prompt": "Indicación NSFW",
|
"NSFW prompt": "Indicaciónes NSFW",
|
||||||
"Prompt that is used when the NSFW toggle is on": "Indicación que se utiliza cuando el interruptor NSFW está activado",
|
"Prompt that is used when the NSFW toggle is on": "Indicaciónes que se utilizan cuando el interruptor NSFW está activado",
|
||||||
"Jailbreak prompt": "Indicación de jailbreak",
|
"Jailbreak prompt": "Indicaciónes de jailbreak",
|
||||||
"Prompt that is used when the Jailbreak toggle is on": "Indicación que se utiliza cuando el interruptor Jailbreak está activado",
|
"Prompt that is used when the Jailbreak toggle is on": "Indicaciónes que se utilizan cuando el interruptor Jailbreak está activado",
|
||||||
"Impersonation prompt": "Indicación de suplantación de identidad",
|
"Impersonation prompt": "Indicaciónes de Suplantación",
|
||||||
"Prompt that is used for Impersonation function": "Indicación que se utiliza para la función de suplantación de identidad",
|
"Prompt that is used for Impersonation function": "Indicación que se utiliza para la función de Suplantación",
|
||||||
"Logit Bias": "Sesgo de logit",
|
"Logit Bias": "Sesgo de logit",
|
||||||
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o reforzar el uso de ciertas palabras",
|
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o reforzar el uso de ciertas palabras",
|
||||||
"View / Edit bias preset": "Ver / Editar preajuste de sesgo",
|
"View / Edit bias preset": "Ver / Editar preajuste de sesgo",
|
||||||
@@ -136,17 +136,17 @@
|
|||||||
"Message to send when auto-jailbreak is on.": "Mensaje para enviar cuando el auto-jailbreak está activado.",
|
"Message to send when auto-jailbreak is on.": "Mensaje para enviar cuando el auto-jailbreak está activado.",
|
||||||
"Jailbreak confirmation reply": "Respuesta de confirmación de jailbreak",
|
"Jailbreak confirmation reply": "Respuesta de confirmación de jailbreak",
|
||||||
"Bot must send this back to confirm jailbreak": "El bot debe enviar esto de vuelta para confirmar el jailbreak",
|
"Bot must send this back to confirm jailbreak": "El bot debe enviar esto de vuelta para confirmar el jailbreak",
|
||||||
"Character Note": "Nota del personaje",
|
"Character Note": "Nota de personaje",
|
||||||
"Influences bot behavior in its responses": "Influye en el comportamiento del bot en sus respuestas",
|
"Influences bot behavior in its responses": "Influye en el comportamiento del bot en sus respuestas",
|
||||||
"Connect": "Conectar",
|
"Connect": "Conectar",
|
||||||
"Test Message": "Mensaje de prueba",
|
"Test Message": "Mensaje de prueba",
|
||||||
"API": "API",
|
"API": "API",
|
||||||
"KoboldAI": "KoboldAI",
|
"KoboldAI": "KoboldAI",
|
||||||
"Use Horde": "Usar Horda",
|
"Use Horde": "Usar Horde",
|
||||||
"API url": "URL de la API",
|
"API url": "URL de la API",
|
||||||
"PygmalionAI/aphrodite-engine": "PygmalionAI/aphrodite-engine (Modo envolvente para API de OpenAI)",
|
"PygmalionAI/aphrodite-engine": "PygmalionAI/aphrodite-engine (Modo envolvente para API de OpenAI)",
|
||||||
"Register a Horde account for faster queue times": "Registra una cuenta de la Horda para tiempos de espera más rápidos",
|
"Register a Horde account for faster queue times": "Registra una cuenta de Horde para tiempos de espera más rápidos",
|
||||||
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir con tus ciclos de GPU inactivos a la Horda",
|
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir con tus ciclos de GPU inactivos a Horde",
|
||||||
"Adjust context size to worker capabilities": "Ajusta el tamaño del contexto a las capacidades del trabajador",
|
"Adjust context size to worker capabilities": "Ajusta el tamaño del contexto a las capacidades del trabajador",
|
||||||
"Adjust response length to worker capabilities": "Ajusta la longitud de la respuesta a las capacidades del trabajador",
|
"Adjust response length to worker capabilities": "Ajusta la longitud de la respuesta a las capacidades del trabajador",
|
||||||
"API key": "Clave API",
|
"API key": "Clave API",
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
"For privacy reasons": "Por razones de privacidad, la clave API se oculta después de actualizar la página",
|
"For privacy reasons": "Por razones de privacidad, la clave API se oculta después de actualizar la página",
|
||||||
"Models": "Modelos",
|
"Models": "Modelos",
|
||||||
"Hold Control / Command key to select multiple models.": "Mantén presionada la tecla Control / Comando para seleccionar varios modelos.",
|
"Hold Control / Command key to select multiple models.": "Mantén presionada la tecla Control / Comando para seleccionar varios modelos.",
|
||||||
"Horde models not loaded": "Modelos de la Horda no cargados",
|
"Horde models not loaded": "Modelos de Horde no cargados",
|
||||||
"Not connected...": "No conectado...",
|
"Not connected...": "No conectado...",
|
||||||
"Novel API key": "Clave API de Novel",
|
"Novel API key": "Clave API de Novel",
|
||||||
"Follow": "Seguir",
|
"Follow": "Seguir",
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
"OpenAI Model": "Modelo de OpenAI",
|
"OpenAI Model": "Modelo de OpenAI",
|
||||||
"Claude API Key": "Clave API de Claude",
|
"Claude API Key": "Clave API de Claude",
|
||||||
"Get your key from": "Obtén tu clave desde",
|
"Get your key from": "Obtén tu clave desde",
|
||||||
"Anthropic's developer console": "consola de desarrolladores de Anthropic",
|
"Anthropic's developer console": "la consola de desarrolladores de Anthropic",
|
||||||
"Slack and Poe cookies will not work here, do not bother trying.": "Las cookies de Slack y Poe no funcionarán aquí, no te molestes en intentarlo.",
|
"Slack and Poe cookies will not work here, do not bother trying.": "Las cookies de Slack y Poe no funcionarán aquí, no te molestes en intentarlo.",
|
||||||
"Claude Model": "Modelo de Claude",
|
"Claude Model": "Modelo de Claude",
|
||||||
"Scale API Key": "Clave API de Scale",
|
"Scale API Key": "Clave API de Scale",
|
||||||
@@ -214,72 +214,72 @@
|
|||||||
"OpenRouter API Key": "Clave API de OpenRouter",
|
"OpenRouter API Key": "Clave API de OpenRouter",
|
||||||
"Connect to the API": "Conectar a la API",
|
"Connect to the API": "Conectar a la API",
|
||||||
"OpenRouter Model": "Modelo de OpenRouter",
|
"OpenRouter Model": "Modelo de OpenRouter",
|
||||||
"View Remaining Credits": "Ver créditos restantes",
|
"View Remaining Credits": "Ver Créditos Restantes",
|
||||||
"Click Authorize below or get the key from": "Haz clic en Autorizar a continuación o obtén la clave desde",
|
"Click Authorize below or get the key from": "Haz clic en Autorizar a continuación o obtén la clave desde",
|
||||||
"Auto-connect to Last Server": "Conexión automática al último servidor",
|
"Auto-connect to Last Server": "Conexión automática al último servidor",
|
||||||
"View hidden API keys": "Ver claves API ocultas",
|
"View hidden API keys": "Ver claves API ocultas",
|
||||||
"Advanced Formatting": "Formato avanzado",
|
"Advanced Formatting": "Formato avanzado",
|
||||||
"Context Template": "Plantilla de contexto",
|
"Context Template": "Plantilla de Contexto",
|
||||||
"AutoFormat Overrides": "Anulaciones de AutoFormato",
|
"AutoFormat Overrides": "Anulaciones de AutoFormato",
|
||||||
"Disable description formatting": "Desactivar formato de descripción",
|
"Disable description formatting": "Desactivar formato de descripción",
|
||||||
"Disable personality formatting": "Desactivar formato de personalidad",
|
"Disable personality formatting": "Desactivar formato de personalidad",
|
||||||
"Disable scenario formatting": "Desactivar formato de escenario",
|
"Disable scenario formatting": "Desactivar formato de escenario",
|
||||||
"Disable example chats formatting": "Desactivar formato de chats de ejemplo",
|
"Disable example chats formatting": "Desactivar formato de chats de ejemplo",
|
||||||
"Disable chat start formatting": "Desactivar formato de inicio de chat",
|
"Disable chat start formatting": "Desactivar formato de inicio de chat",
|
||||||
"Custom Chat Separator": "Separador de chat personalizado",
|
"Custom Chat Separator": "Separador de Chat Personalizado",
|
||||||
"Replace Macro in Custom Stopping Strings": "Reemplazar macro en cadenas de detención personalizadas",
|
"Replace Macro in Custom Stopping Strings": "Reemplazar macro en Cadenas de Detención Personalizadas",
|
||||||
"Strip Example Messages from Prompt": "Eliminar mensajes de ejemplo de la solicitud",
|
"Strip Example Messages from Prompt": "Eliminar Mensajes de Ejemplo de las Indicaciones",
|
||||||
"Story String": "Cadena de historia",
|
"Story String": "Cadena de historia",
|
||||||
"Example Separator": "Separador de ejemplo",
|
"Example Separator": "Separador de ejemplo",
|
||||||
"Chat Start": "Inicio de chat",
|
"Chat Start": "Inicio de chat",
|
||||||
"Activation Regex": "Regex de activación",
|
"Activation Regex": "Regex de activación",
|
||||||
"Instruct Mode": "Modo de instrucción",
|
"Instruct Mode": "Modo Instrucción",
|
||||||
"Wrap Sequences with Newline": "Envolver secuencias con nueva línea",
|
"Wrap Sequences with Newline": "Envolver Secuencias con Nueva línea",
|
||||||
"Include Names": "Incluir nombres",
|
"Include Names": "Incluir Nombres",
|
||||||
"Force for Groups and Personas": "Forzar para grupos y personas",
|
"Force for Groups and Personas": "Forzar para Grupos y Personas",
|
||||||
"System Prompt": "Solicitud del sistema",
|
"System Prompt": "Indicaciones del Sistema",
|
||||||
"Instruct Mode Sequences": "Secuencias en modo de instrucción",
|
"Instruct Mode Sequences": "Secuencias en Modo Instrucción",
|
||||||
"Input Sequence": "Secuencia de entrada",
|
"Input Sequence": "Secuencia de Entrada",
|
||||||
"Output Sequence": "Secuencia de salida",
|
"Output Sequence": "Secuencia de Salida",
|
||||||
"First Output Sequence": "Primera secuencia de salida",
|
"First Output Sequence": "Primera Secuencia de Salida",
|
||||||
"Last Output Sequence": "Última secuencia de salida",
|
"Last Output Sequence": "Última Secuencia de Salida",
|
||||||
"System Sequence Prefix": "Prefijo de secuencia del sistema",
|
"System Sequence Prefix": "Prefijo de Secuencia del Sistema",
|
||||||
"System Sequence Suffix": "Sufijo de secuencia del sistema",
|
"System Sequence Suffix": "Sufijo de Secuencia del Sistema",
|
||||||
"Stop Sequence": "Secuencia de parada",
|
"Stop Sequence": "Secuencia de Parada",
|
||||||
"Context Formatting": "Formato de contexto",
|
"Context Formatting": "Formato de Contexto",
|
||||||
"(Saved to Context Template)": "(Guardado en plantilla de contexto)",
|
"(Saved to Context Template)": "(Guardado en Plantilla de Contexto)",
|
||||||
"Tokenizer": "Tokenizador",
|
"Tokenizer": "Tokenizador",
|
||||||
"None / Estimated": "Ninguno / Estimado",
|
"None / Estimated": "Ninguno / Estimado",
|
||||||
"Sentencepiece (LLaMA)": "Sentencepiece (LLaMA)",
|
"Sentencepiece (LLaMA)": "Sentencepiece (LLaMA)",
|
||||||
"Token Padding": "Relleno de token",
|
"Token Padding": "Relleno de token",
|
||||||
"Save preset as": "Guardar preajuste como",
|
"Save preset as": "Guardar preajuste como",
|
||||||
"Always add character's name to prompt": "Siempre agregar el nombre del personaje a la solicitud",
|
"Always add character's name to prompt": "Siempre agregar el nombre del personaje a las indicaciones",
|
||||||
"Use as Stop Strings": "Usar como cadenas de parada",
|
"Use as Stop Strings": "Usar como Cadenas de Parada",
|
||||||
"Bind to Context": "Vincular al contexto",
|
"Bind to Context": "Vincular al Contexto",
|
||||||
"Generate only one line per request": "Generar solo una línea por solicitud",
|
"Generate only one line per request": "Generar solo una línea por solicitud",
|
||||||
"Misc. Settings": "Configuraciones misceláneas",
|
"Misc. Settings": "Configuraciones Misceláneas",
|
||||||
"Auto-Continue": "Autocontinuar",
|
"Auto-Continue": "Autocontinuar",
|
||||||
"Collapse Consecutive Newlines": "Colapsar nuevas líneas consecutivas",
|
"Collapse Consecutive Newlines": "Colapsar Nuevas líneas Consecutivas",
|
||||||
"Allow for Chat Completion APIs": "Permitir APIs de finalización de chat",
|
"Allow for Chat Completion APIs": "Permitir para APIs de Completado de Chat",
|
||||||
"Target length (tokens)": "Longitud objetivo (tokens)",
|
"Target length (tokens)": "Longitud objetivo (tokens)",
|
||||||
"Keep Example Messages in Prompt": "Mantener mensajes de ejemplo en la solicitud",
|
"Keep Example Messages in Prompt": "Mantener Mensajes de Ejemplo en las indicaciones",
|
||||||
"Remove Empty New Lines from Output": "Eliminar nuevas líneas vacías de la salida",
|
"Remove Empty New Lines from Output": "Eliminar Nuevas líneas vacías de la salida",
|
||||||
"Disabled for all models": "Desactivado para todos los modelos",
|
"Disabled for all models": "Desactivado para todos los modelos",
|
||||||
"Automatic (based on model name)": "Automático (basado en el nombre del modelo)",
|
"Automatic (based on model name)": "Automático (basado en el nombre del modelo)",
|
||||||
"Enabled for all models": "Activado para todos los modelos",
|
"Enabled for all models": "Activado para todos los modelos",
|
||||||
"Anchors Order": "Orden de anclajes",
|
"Anchors Order": "Orden de Anclajes",
|
||||||
"Character then Style": "Personaje luego estilo",
|
"Character then Style": "Personaje luego estilo",
|
||||||
"Style then Character": "Estilo luego personaje",
|
"Style then Character": "Estilo luego personaje",
|
||||||
"Character Anchor": "Anclaje de personaje",
|
"Character Anchor": "Anclaje de personaje",
|
||||||
"Style Anchor": "Anclaje de estilo",
|
"Style Anchor": "Anclaje de estilo",
|
||||||
"World Info": "Información del mundo",
|
"World Info": "Información de Mundo (WI)",
|
||||||
"Scan Depth": "Profundidad de escaneo",
|
"Scan Depth": "Profundidad de escaneo",
|
||||||
"Case-Sensitive": "Sensible a mayúsculas y minúsculas",
|
"Case-Sensitive": "Sensible a mayúsculas y minúsculas",
|
||||||
"Match Whole Words": "Coincidir con palabras completas",
|
"Match Whole Words": "Coincidir con palabras completas",
|
||||||
"Use global setting": "Usar configuración global",
|
"Use global setting": "Usar configuración global",
|
||||||
"Yes": "Sí",
|
"Yes": "Sí",
|
||||||
"No": "No",
|
"No": "No",
|
||||||
"Context %": "Contexto %",
|
"Context %": "% de Contexto",
|
||||||
"Budget Cap": "Límite de presupuesto",
|
"Budget Cap": "Límite de presupuesto",
|
||||||
"(0 = disabled)": "(0 = desactivado)",
|
"(0 = disabled)": "(0 = desactivado)",
|
||||||
"depth": "profundidad",
|
"depth": "profundidad",
|
||||||
@@ -289,29 +289,29 @@
|
|||||||
"None": "Ninguno",
|
"None": "Ninguno",
|
||||||
"User Settings": "Configuraciones de usuario",
|
"User Settings": "Configuraciones de usuario",
|
||||||
"UI Mode": "Modo de IU",
|
"UI Mode": "Modo de IU",
|
||||||
"UI Language": "Idioma",
|
"UI Language": "Idioma de la UI",
|
||||||
"MovingUI Preset": "Preajuste de MovingUI",
|
"MovingUI Preset": "Preajuste de MovingUI",
|
||||||
"UI Customization": "Personalización de la IU",
|
"UI Customization": "Personalización de la IU",
|
||||||
"Avatar Style": "Estilo de avatar",
|
"Avatar Style": "Estilo de Avatar",
|
||||||
"Circle": "Círculo",
|
"Circle": "Círculo",
|
||||||
"Rectangle": "Rectángulo",
|
"Rectangle": "Rectángulo",
|
||||||
"Square": "Cuadrado",
|
"Square": "Cuadrado",
|
||||||
"Chat Style": "Estilo de chat",
|
"Chat Style": "Estilo de Chat",
|
||||||
"Default": "Predeterminado",
|
"Default": "Predeterminado",
|
||||||
"Bubbles": "Burbujas",
|
"Bubbles": "Burbujas",
|
||||||
"No Blur Effect": "Sin efecto de desenfoque",
|
"No Blur Effect": "Sin efecto de desenfoque",
|
||||||
"No Text Shadows": "Sin sombras de texto",
|
"No Text Shadows": "Sin sombras de texto",
|
||||||
"Waifu Mode": "Modo Waifu",
|
"Waifu Mode": "Modo Waifu",
|
||||||
"Message Timer": "Temporizador de mensajes",
|
"Message Timer": "Temporizador de mensajes",
|
||||||
"Model Icon": "Ícono del modelo",
|
"Model Icon": "Ícono del Modelo",
|
||||||
"# of messages (0 = disabled)": "# de mensajes (0 = desactivado)",
|
"# of messages (0 = disabled)": "# de mensajes (0 = desactivado)",
|
||||||
"Advanced Character Search": "Búsqueda avanzada de personajes",
|
"Advanced Character Search": "Búsqueda Avanzada de Personajes",
|
||||||
"Allow {{char}}: in bot messages": "Permitir {{char}}: en mensajes de bot",
|
"Allow {{char}}: in bot messages": "Permitir {{char}}: en mensajes de bot",
|
||||||
"Allow {{user}}: in bot messages": "Permitir {{user}}: en mensajes de bot",
|
"Allow {{user}}: in bot messages": "Permitir {{user}}: en mensajes de bot",
|
||||||
"Show tags in responses": "Mostrar etiquetas en respuestas",
|
"Show tags in responses": "Mostrar etiquetas en respuestas",
|
||||||
"Aux List Field": "Campo de lista auxiliar",
|
"Aux List Field": "Campo de lista auxiliar",
|
||||||
"Lorebook Import Dialog": "Diálogo de importación de libro de historia",
|
"Lorebook Import Dialog": "Diálogo de Importación de Libro de Historia",
|
||||||
"MUI Preset": "Preset MUI",
|
"MUI Preset": "Preajuste MUI",
|
||||||
"If set in the advanced character definitions, this field will be displayed in the characters list.": "Si se establece en las definiciones avanzadas de personajes, este campo se mostrará en la lista de personajes.",
|
"If set in the advanced character definitions, this field will be displayed in the characters list.": "Si se establece en las definiciones avanzadas de personajes, este campo se mostrará en la lista de personajes.",
|
||||||
"Relaxed API URLS": "URLS de API relajadas",
|
"Relaxed API URLS": "URLS de API relajadas",
|
||||||
"Custom CSS": "CSS personalizado",
|
"Custom CSS": "CSS personalizado",
|
||||||
@@ -322,7 +322,7 @@
|
|||||||
"Relax message trim in Groups": "Relajar recorte de mensajes en Grupos",
|
"Relax message trim in Groups": "Relajar recorte de mensajes en Grupos",
|
||||||
"Characters Hotswap": "Cambio rápido de personajes",
|
"Characters Hotswap": "Cambio rápido de personajes",
|
||||||
"Request token probabilities": "Solicitar probabilidades de tokens",
|
"Request token probabilities": "Solicitar probabilidades de tokens",
|
||||||
"Movable UI Panels": "Paneles de UI móviles",
|
"Movable UI Panels": "Paneles de UI Móviles",
|
||||||
"Reset Panels": "Restablecer paneles",
|
"Reset Panels": "Restablecer paneles",
|
||||||
"UI Colors": "Colores de UI",
|
"UI Colors": "Colores de UI",
|
||||||
"Main Text": "Texto principal",
|
"Main Text": "Texto principal",
|
||||||
@@ -331,44 +331,44 @@
|
|||||||
"Shadow Color": "Color de sombra",
|
"Shadow Color": "Color de sombra",
|
||||||
"FastUI BG": "Fondo de FastUI",
|
"FastUI BG": "Fondo de FastUI",
|
||||||
"Blur Tint": "Tinte de desenfoque",
|
"Blur Tint": "Tinte de desenfoque",
|
||||||
"Font Scale": "Escala de fuente",
|
"Font Scale": "Tamaño de fuente",
|
||||||
"Blur Strength": "Fuerza de desenfoque",
|
"Blur Strength": "Fuerza de desenfoque",
|
||||||
"Text Shadow Width": "Ancho de sombra de texto",
|
"Text Shadow Width": "Ancho de sombra de texto",
|
||||||
"UI Theme Preset": "Preset de tema de UI",
|
"UI Theme Preset": "Preajuste de tema de UI",
|
||||||
"Power User Options": "Opciones avanzadas de usuario",
|
"Power User Options": "Opciones avanzadas de usuario",
|
||||||
"Swipes": "Deslizamientos",
|
"Swipes": "Deslizamientos",
|
||||||
"Miscellaneous": "Varios",
|
"Miscellaneous": "Varios",
|
||||||
"Theme Toggles": "Conmutadores de tema",
|
"Theme Toggles": "Conmutadores de tema",
|
||||||
"Background Sound Only": "Solo sonido de fondo",
|
"Background Sound Only": "Solo Sonido de Fondo",
|
||||||
"Auto-load Last Chat": "Cargar automáticamente el último chat",
|
"Auto-load Last Chat": "Cargar automáticamente el último chat",
|
||||||
"Auto-save Message Edits": "Guardar automáticamente las ediciones de mensajes",
|
"Auto-save Message Edits": "Guardar automáticamente las Ediciones de Mensajes",
|
||||||
"Auto-fix Markdown": "Auto-corregir Markdown",
|
"Auto-fix Markdown": "Auto-corregir Markdown",
|
||||||
"Allow : in bot messages": "Permitir : en mensajes de bot",
|
"Allow : in bot messages": "Permitir : en mensajes de bot",
|
||||||
"Auto-scroll Chat": "Chat de desplazamiento automático",
|
"Auto-scroll Chat": "Desplazamiento de Chat Automático",
|
||||||
"Render Formulas": "Renderizar fórmulas",
|
"Render Formulas": "Renderizar fórmulas",
|
||||||
"Send on Enter": "Enviar al presionar Enter",
|
"Send on Enter": "Enviar al presionar Enter",
|
||||||
"Always disabled": "Siempre desactivado",
|
"Always disabled": "Siempre desactivado",
|
||||||
"Automatic (desktop)": "Automático (escritorio)",
|
"Automatic (desktop)": "Automático (escritorio)",
|
||||||
"Always enabled": "Siempre activado",
|
"Always enabled": "Siempre activado",
|
||||||
"Debug Menu": "Menú de depuración",
|
"Debug Menu": "Menú de depuración",
|
||||||
"Restore User Input": "Restaurar entrada de usuario",
|
"Restore User Input": "Restaurar Entrada de Usuario",
|
||||||
"Character Handling": "Manipulación de personajes",
|
"Character Handling": "Manipulación de personajes",
|
||||||
"Example Messages Behavior": "Comportamiento de mensajes de ejemplo",
|
"Example Messages Behavior": "Comportamiento de mensajes de ejemplo",
|
||||||
"Gradual push-out": "Empuje gradual",
|
"Gradual push-out": "Expulsión gradual",
|
||||||
"Chat/Message Handling": "Manipulación de chat/mensaje",
|
"Chat/Message Handling": "Manipulación de Chat/Mensaje",
|
||||||
"Always include examples": "Siempre incluir ejemplos",
|
"Always include examples": "Siempre incluir ejemplos",
|
||||||
"Never include examples": "Nunca incluir ejemplos",
|
"Never include examples": "Nunca incluir ejemplos",
|
||||||
"Forbid External Media": "Prohibir medios externos",
|
"Forbid External Media": "Prohibir Medios Externos",
|
||||||
"System Backgrounds": "Fondos del sistema",
|
"System Backgrounds": "Fondos del Sistema",
|
||||||
"Name": "Nombre",
|
"Name": "Nombre",
|
||||||
"Your Avatar": "Tu avatar",
|
"Your Avatar": "Tu avatar",
|
||||||
"Extensions API:": "API de extensiones:",
|
"Extensions API:": "API de Extensiones:",
|
||||||
"SillyTavern-extras": "Extras de SillyTavern",
|
"SillyTavern-extras": "Extras de SillyTavern",
|
||||||
"Auto-connect": "Conexión automática",
|
"Auto-connect": "Conexión automática",
|
||||||
"Active extensions": "Extensiones activas",
|
"Active extensions": "Extensiones Activas",
|
||||||
"Extension settings": "Configuraciones de extensión",
|
"Extension settings": "Configuraciones de Extensión",
|
||||||
"Description": "Descripción",
|
"Description": "Descripción",
|
||||||
"First message": "Primer mensaje",
|
"First message": "Primer Mensaje",
|
||||||
"Group Controls": "Controles de grupo",
|
"Group Controls": "Controles de grupo",
|
||||||
"Group reply strategy": "Estrategia de respuesta de grupo",
|
"Group reply strategy": "Estrategia de respuesta de grupo",
|
||||||
"Natural order": "Orden natural",
|
"Natural order": "Orden natural",
|
||||||
@@ -387,19 +387,19 @@
|
|||||||
"Circumstances and context of the dialogue": "Circunstancias y contexto del diálogo",
|
"Circumstances and context of the dialogue": "Circunstancias y contexto del diálogo",
|
||||||
"Talkativeness": "Habladuría",
|
"Talkativeness": "Habladuría",
|
||||||
"How often the chracter speaks in": "Con qué frecuencia habla el personaje en",
|
"How often the chracter speaks in": "Con qué frecuencia habla el personaje en",
|
||||||
"group chats!": "chats de grupo!",
|
"group chats!": "chats grupales!",
|
||||||
"Shy": "Tímido",
|
"Shy": "Tímido",
|
||||||
"Normal": "Normal",
|
"Normal": "Normal",
|
||||||
"Chatty": "Charlatán",
|
"Chatty": "Parlanchín",
|
||||||
"Examples of dialogue": "Ejemplos de diálogo",
|
"Examples of dialogue": "Ejemplos de diálogo",
|
||||||
"Forms a personality more clearly": "Forma una personalidad más clara",
|
"Forms a personality more clearly": "Forma una personalidad más clara",
|
||||||
"Save": "Guardar",
|
"Save": "Guardar",
|
||||||
"World Info Editor": "Editor de información del mundo",
|
"World Info Editor": "Editor de Información de Mundo (WI)",
|
||||||
"New summary": "Nuevo resumen",
|
"New summary": "Nuevo resumen",
|
||||||
"Export": "Exportar",
|
"Export": "Exportar",
|
||||||
"Delete World": "Eliminar mundo",
|
"Delete World": "Eliminar mundo",
|
||||||
"Chat History": "Historial de chat",
|
"Chat History": "Historial de chat",
|
||||||
"Group Chat Scenario Override": "Anulación de escenario de chat grupal",
|
"Group Chat Scenario Override": "Anulación de escenario de Chat Grupal",
|
||||||
"All group members will use the following scenario text instead of what is specified in their character cards.": "Todos los miembros del grupo usarán el siguiente texto de escenario en lugar de lo que se especifica en sus tarjetas de personaje.",
|
"All group members will use the following scenario text instead of what is specified in their character cards.": "Todos los miembros del grupo usarán el siguiente texto de escenario en lugar de lo que se especifica en sus tarjetas de personaje.",
|
||||||
"Keywords": "Palabras clave",
|
"Keywords": "Palabras clave",
|
||||||
"Separate with commas": "Separar con comas",
|
"Separate with commas": "Separar con comas",
|
||||||
@@ -424,60 +424,60 @@
|
|||||||
"Start new chat": "Iniciar nuevo chat",
|
"Start new chat": "Iniciar nuevo chat",
|
||||||
"View past chats": "Ver chats anteriores",
|
"View past chats": "Ver chats anteriores",
|
||||||
"Delete messages": "Eliminar mensajes",
|
"Delete messages": "Eliminar mensajes",
|
||||||
"Impersonate": "Hacerse pasar por",
|
"Impersonate": "Suplantar",
|
||||||
"Regenerate": "Regenerar",
|
"Regenerate": "Regenerar",
|
||||||
"PNG": "PNG",
|
"PNG": "PNG",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
"presets": "ajustes preestablecidos",
|
"presets": "preajustes",
|
||||||
"Message Sound": "Sonido de mensaje",
|
"Message Sound": "Sonido de mensaje",
|
||||||
"Author's Note": "Nota del autor",
|
"Author's Note": "Nota del autor",
|
||||||
"Send Jailbreak": "Enviar Jailbreak",
|
"Send Jailbreak": "Enviar Jailbreak",
|
||||||
"Replace empty message": "Reemplazar mensaje vacío",
|
"Replace empty message": "Reemplazar mensaje vacío",
|
||||||
"Send this text instead of nothing when the text box is empty.": "Enviar este texto en lugar de nada cuando el cuadro de texto está vacío.",
|
"Send this text instead of nothing when the text box is empty.": "Enviar este texto en lugar de nada cuando el cuadro de texto está vacío.",
|
||||||
"NSFW avoidance prompt": "Indicación de evitación de NSFW",
|
"NSFW avoidance prompt": "Indicaciones de evitación de NSFW",
|
||||||
"Prompt that is used when the NSFW toggle is off": "Indicación que se usa cuando el interruptor de NSFW está apagado",
|
"Prompt that is used when the NSFW toggle is off": "Indicaciones que se usa cuando el interruptor de NSFW está apagado",
|
||||||
"Advanced prompt bits": "Bits de indicación avanzada",
|
"Advanced prompt bits": "Bits de Indicaciones Avanzadas",
|
||||||
"World Info format": "Formato de información del mundo",
|
"World Info format": "Formato de Información de Mundo (WI)",
|
||||||
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "Envuelve las entradas de información del mundo activadas antes de insertarlas en la indicación. Use {0} para marcar un lugar donde se inserta el contenido.",
|
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "Envuelve las entradas de Información de Mundo (WI) activadas antes de insertarlas en las indicaciones. Use {0} para marcar un lugar donde se inserta el contenido.",
|
||||||
"Unrestricted maximum value for the context slider": "Valor máximo sin restricciones para el control deslizante de contexto",
|
"Unrestricted maximum value for the context slider": "Valor máximo sin restricciones para el control deslizante de contexto",
|
||||||
"Chat Completion Source": "Fuente de completado de chat",
|
"Chat Completion Source": "Fuente de Completado de Chat",
|
||||||
"Avoid sending sensitive information to the Horde.": "Evite enviar información sensible a la Horda.",
|
"Avoid sending sensitive information to the Horde.": "Evite enviar información sensible a Horde.",
|
||||||
"Review the Privacy statement": "Revise la declaración de privacidad",
|
"Review the Privacy statement": "Revise la declaración de privacidad",
|
||||||
"Learn how to contribute your idel GPU cycles to the Horde": "Aprende cómo contribuir con tus ciclos de GPU inactivos a la Horda",
|
"Learn how to contribute your idel GPU cycles to the Horde": "Aprende cómo contribuir con tus ciclos de GPU inactivos a Horde",
|
||||||
"Trusted workers only": "Solo trabajadores de confianza",
|
"Trusted workers only": "Solo trabajadores de confianza",
|
||||||
"For privacy reasons, your API key will be hidden after you reload the page.": "Por razones de privacidad, su clave de API se ocultará después de que vuelva a cargar la página.",
|
"For privacy reasons, your API key will be hidden after you reload the page.": "Por razones de privacidad, su clave de API se ocultará después de que vuelva a cargar la página.",
|
||||||
"-- Horde models not loaded --": "-- Modelos de la Horda no cargados --",
|
"-- Horde models not loaded --": "-- Modelos de Horde no cargados --",
|
||||||
"Example: http://127.0.0.1:5000/api ": "Ejemplo: http://127.0.0.1:5000/api",
|
"Example: http://127.0.0.1:5000/api ": "Ejemplo: http://127.0.0.1:5000/api",
|
||||||
"No connection...": "Sin conexión...",
|
"No connection...": "Sin conexión...",
|
||||||
"Get your NovelAI API Key": "Obtenga su clave de API de NovelAI",
|
"Get your NovelAI API Key": "Obtenga su Clave de API de NovelAI",
|
||||||
"KoboldAI Horde": "Horda de KoboldAI",
|
"KoboldAI Horde": "Horde de KoboldAI",
|
||||||
"Text Gen WebUI (ooba)": "Text Gen WebUI (ooba)",
|
"Text Gen WebUI (ooba)": "Text Gen WebUI (ooba)",
|
||||||
"NovelAI": "NovelAI",
|
"NovelAI": "NovelAI",
|
||||||
"Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale)": "Completado de chat (OpenAI, Claude, Window/OpenRouter, Scale)",
|
"Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale)": "Completado de Chat (OpenAI, Claude, Window/OpenRouter, Scale)",
|
||||||
"OpenAI API key": "Clave de API de OpenAI",
|
"OpenAI API key": "Clave de API de OpenAI",
|
||||||
"Trim spaces": "Recortar espacios",
|
"Trim spaces": "Recortar espacios",
|
||||||
"Trim Incomplete Sentences": "Recortar oraciones incompletas",
|
"Trim Incomplete Sentences": "Recortar Oraciones Incompletas",
|
||||||
"Include Newline": "Incluir nueva línea",
|
"Include Newline": "Incluir Nueva línea",
|
||||||
"Non-markdown strings": "Cadenas no Markdown",
|
"Non-markdown strings": "Cadenas no Markdown",
|
||||||
"Replace Macro in Sequences": "Reemplazar macro en secuencias",
|
"Replace Macro in Sequences": "Reemplazar Macro en Secuencias",
|
||||||
"Presets": "Ajustes preestablecidos",
|
"Presets": "Preajustes",
|
||||||
"Separator": "Separador",
|
"Separator": "Separador",
|
||||||
"Start Reply With": "Iniciar respuesta con",
|
"Start Reply With": "Iniciar Respuesta con",
|
||||||
"Show reply prefix in chat": "Mostrar prefijo de respuesta en el chat",
|
"Show reply prefix in chat": "Mostrar prefijo de respuesta en el chat",
|
||||||
"Worlds/Lorebooks": "Mundos/Libros de historia",
|
"Worlds/Lorebooks": "Mundos/Libros de Historia",
|
||||||
"Active World(s)": "Mundo(s) activo(s)",
|
"Active World(s)": "Mundo(s) Activo(s)",
|
||||||
"Activation Settings": "Configuraciones de activación",
|
"Activation Settings": "Configuraciones de activación",
|
||||||
"Character Lore Insertion Strategy": "Estrategia de inserción de lore de personajes",
|
"Character Lore Insertion Strategy": "Estrategia de Inserción de Historia de Dersonajes",
|
||||||
"Sorted Evenly": "Ordenado uniformemente",
|
"Sorted Evenly": "Ordenado uniformemente",
|
||||||
"Active World(s) for all chats": "Mundo(s) activo(s) para todos los chats",
|
"Active World(s) for all chats": "Mundo(s) Activo(s) para todos los chats",
|
||||||
"-- World Info not found --": "-- Información del mundo no encontrada --",
|
"-- World Info not found --": "-- Información de Mundo (WI) no encontrada --",
|
||||||
"--- Pick to Edit ---": "--- Seleccionar para editar ---",
|
"--- Pick to Edit ---": "--- Seleccionar para editar ---",
|
||||||
"or": "o",
|
"or": "o",
|
||||||
"New": "Nuevo",
|
"New": "Nuevo",
|
||||||
"Priority": "Prioridad",
|
"Priority": "Prioridad",
|
||||||
"Custom": "Personalizado",
|
"Custom": "Personalizado",
|
||||||
"Title A-Z": "Título de la A a la Z",
|
"Title A-Z": "Título de A a Z",
|
||||||
"Title Z-A": "Título de la Z a la A",
|
"Title Z-A": "Título de Z a A",
|
||||||
"Tokens ↗": "Tokens ↗",
|
"Tokens ↗": "Tokens ↗",
|
||||||
"Tokens ↘": "Tokens ↘",
|
"Tokens ↘": "Tokens ↘",
|
||||||
"Depth ↗": "Profundidad ↗",
|
"Depth ↗": "Profundidad ↗",
|
||||||
@@ -486,26 +486,26 @@
|
|||||||
"Order ↘": "Orden ↘",
|
"Order ↘": "Orden ↘",
|
||||||
"UID ↗": "UID ↗",
|
"UID ↗": "UID ↗",
|
||||||
"UID ↘": "UID ↘",
|
"UID ↘": "UID ↘",
|
||||||
"Trigger% ↗": "Desencadenar% ↗",
|
"Trigger% ↗": "Activador% ↗",
|
||||||
"Trigger% ↘": "Desencadenar% ↘",
|
"Trigger% ↘": "Activador% ↘",
|
||||||
"Order:": "Orden:",
|
"Order:": "Orden:",
|
||||||
"Depth:": "Profundidad:",
|
"Depth:": "Profundidad:",
|
||||||
"Character Lore First": "Lore del personaje primero",
|
"Character Lore First": "Historia de Personaje Primero",
|
||||||
"Global Lore First": "Lore global primero",
|
"Global Lore First": "Historia Global Primero",
|
||||||
"Recursive Scan": "Exploración recursiva",
|
"Recursive Scan": "Escaneo Recursiva",
|
||||||
"Case Sensitive": "Sensible a mayúsculas y minúsculas",
|
"Case Sensitive": "Sensible a mayúsculas y minúsculas",
|
||||||
"Match whole words": "Coincidir palabras completas",
|
"Match whole words": "Coincidir palabras completas",
|
||||||
"Alert On Overflow": "Alerta en desbordamiento",
|
"Alert On Overflow": "Alerta en Desbordamiento",
|
||||||
"World/Lore Editor": "Editor de mundo/Lore",
|
"World/Lore Editor": "Editor de Mundo/Historia",
|
||||||
"--- None ---": "--- Ninguno ---",
|
"--- None ---": "--- Ninguno ---",
|
||||||
"Comma separated (ignored if empty)": "Separado por comas (ignorado si está vacío)",
|
"Comma separated (ignored if empty)": "Separado por comas (ignorado si está vacío)",
|
||||||
"Use Probability": "Usar Probabilidad",
|
"Use Probability": "Usar Probabilidad",
|
||||||
"Exclude from recursion": "Excluir de la recursión",
|
"Exclude from recursion": "Excluir de la recursión",
|
||||||
"Entry Title/Memo": "Título/Memo",
|
"Entry Title/Memo": "Título/Memo",
|
||||||
"Position:": "Posición:",
|
"Position:": "Posición:",
|
||||||
"T_Position": "↑Char: antes de definiciones de caracteres\n↓Char: después de definiciones de caracteres\n↑AN: antes de notas del autor\n↓AN: después de notas del autor\n@D: en profundidad",
|
"T_Position": "↑Char: antes de definiciones de personajes\n↓Char: después de definiciones de personajes\n↑AN: antes de notas del autor\n↓AN: después de notas del autor\n@D: en profundidad",
|
||||||
"Before Char Defs": "Antes de Definiciones de Caracteres",
|
"Before Char Defs": "Antes de Def. de Personaje",
|
||||||
"After Char Defs": "Después de Definiciones de Caracteres",
|
"After Char Defs": "Después de Def. de Personaje",
|
||||||
"Before AN": "Antes de AN",
|
"Before AN": "Antes de AN",
|
||||||
"After AN": "Después de AN",
|
"After AN": "Después de AN",
|
||||||
"at Depth": "en Profundidad",
|
"at Depth": "en Profundidad",
|
||||||
@@ -521,7 +521,7 @@
|
|||||||
"Chat Background": "Fondo de Chat",
|
"Chat Background": "Fondo de Chat",
|
||||||
"UI Background": "Fondo de IU",
|
"UI Background": "Fondo de IU",
|
||||||
"Mad Lab Mode": "Modo Laboratorio Loco",
|
"Mad Lab Mode": "Modo Laboratorio Loco",
|
||||||
"Show Message Token Count": "Mostrar Conteo de Tokens de Mensaje",
|
"Show Message Token Count": "Mostrar Conteo de Tokens en Mensaje",
|
||||||
"Compact Input Area (Mobile)": "Área de Entrada Compacta (Móvil)",
|
"Compact Input Area (Mobile)": "Área de Entrada Compacta (Móvil)",
|
||||||
"Zen Sliders": "Deslizadores Zen",
|
"Zen Sliders": "Deslizadores Zen",
|
||||||
"UI Border": "Borde de IU",
|
"UI Border": "Borde de IU",
|
||||||
@@ -534,9 +534,9 @@
|
|||||||
"Streaming FPS": "FPS de Transmisión",
|
"Streaming FPS": "FPS de Transmisión",
|
||||||
"Gestures": "Gestos",
|
"Gestures": "Gestos",
|
||||||
"Message IDs": "IDs de Mensaje",
|
"Message IDs": "IDs de Mensaje",
|
||||||
"Prefer Character Card Prompt": "Preferir Tarjeta de Personaje con Indicación",
|
"Prefer Character Card Prompt": "Preferir Indicaciones en Tarjeta de Personaje",
|
||||||
"Prefer Character Card Jailbreak": "Preferir Jailbreak de Tarjeta de Personaje",
|
"Prefer Character Card Jailbreak": "Preferir Jailbreak en Tarjeta de Personaje",
|
||||||
"Press Send to continue": "Presione Enviar para continuar",
|
"Press Send to continue": "Presionar Enviar para continuar",
|
||||||
"Quick 'Continue' button": "Botón 'Continuar' Rápido",
|
"Quick 'Continue' button": "Botón 'Continuar' Rápido",
|
||||||
"Log prompts to console": "Registrar indicaciones en la consola",
|
"Log prompts to console": "Registrar indicaciones en la consola",
|
||||||
"Never resize avatars": "Nunca redimensionar avatares",
|
"Never resize avatars": "Nunca redimensionar avatares",
|
||||||
@@ -569,11 +569,11 @@
|
|||||||
"Show the number of tokens in each message in the chat log": "Mostrar el número de tokens en cada mensaje en el registro de chat",
|
"Show the number of tokens in each message in the chat log": "Mostrar el número de tokens en cada mensaje en el registro de chat",
|
||||||
"Single-row message input area. Mobile only, no effect on PC": "Área de entrada de mensaje de una sola fila. Solo móvil, sin efecto en PC",
|
"Single-row message input area. Mobile only, no effect on PC": "Área de entrada de mensaje de una sola fila. Solo móvil, sin efecto en PC",
|
||||||
"In the Character Management panel, show quick selection buttons for favorited characters": "En el panel de Gestión de Personajes, mostrar botones de selección rápida para personajes favoritos",
|
"In the Character Management panel, show quick selection buttons for favorited characters": "En el panel de Gestión de Personajes, mostrar botones de selección rápida para personajes favoritos",
|
||||||
"Show tagged character folders in the character list": "Mostrar carpetas de personajes etiquetadas en la lista de personajes",
|
"Show tagged character folders in the character list": "Mostrar carpetas de personajes etiquetados en la lista de personajes",
|
||||||
"Play a sound when a message generation finishes": "Reproducir un sonido cuando finaliza la generación de un mensaje",
|
"Play a sound when a message generation finishes": "Reproducir un sonido cuando finaliza la generación de un mensaje",
|
||||||
"Only play a sound when ST's browser tab is unfocused": "Solo reproducir un sonido cuando la pestaña del navegador de ST no está enfocada",
|
"Only play a sound when ST's browser tab is unfocused": "Solo reproducir un sonido cuando la pestaña del navegador de ST no está enfocada",
|
||||||
"Reduce the formatting requirements on API URLs": "Reducir los requisitos de formato en las URL de API",
|
"Reduce the formatting requirements on API URLs": "Reducir los requisitos de formato en las URL de API",
|
||||||
"Ask to import the World Info/Lorebook for every new character with embedded lorebook. If unchecked, a brief message will be shown instead": "Pedir importar la Información Mundial/Libro de Leyendas para cada nuevo personaje con un lorebook incrustado. Si no está marcado, se mostrará un mensaje breve en su lugar",
|
"Ask to import the World Info/Lorebook for every new character with embedded lorebook. If unchecked, a brief message will be shown instead": "Pedir importar Información de Mundo (WI)/Libro de Historia para cada nuevo personaje con un Libro de Historia incrustado. Si no está marcado, se mostrará un mensaje breve en su lugar",
|
||||||
"Restore unsaved user input on page refresh": "Restaurar la entrada de usuario no guardada al actualizar la página",
|
"Restore unsaved user input on page refresh": "Restaurar la entrada de usuario no guardada al actualizar la página",
|
||||||
"Allow repositioning certain UI elements by dragging them. PC only, no effect on mobile": "Permitir reposicionar ciertos elementos de IU arrastrándolos. Solo PC, sin efecto en móviles",
|
"Allow repositioning certain UI elements by dragging them. PC only, no effect on mobile": "Permitir reposicionar ciertos elementos de IU arrastrándolos. Solo PC, sin efecto en móviles",
|
||||||
"MovingUI preset. Predefined/saved draggable positions": "Preconfiguración MovingUI. Posiciones arrastrables predefinidas/guardadas",
|
"MovingUI preset. Predefined/saved draggable positions": "Preconfiguración MovingUI. Posiciones arrastrables predefinidas/guardadas",
|
||||||
@@ -581,7 +581,7 @@
|
|||||||
"Apply a custom CSS style to all of the ST GUI": "Aplicar un estilo CSS personalizado a toda la GUI de ST",
|
"Apply a custom CSS style to all of the ST GUI": "Aplicar un estilo CSS personalizado a toda la GUI de ST",
|
||||||
"Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "Usar coincidencia difusa y buscar personajes en la lista por todos los campos de datos, no solo por una subcadena de nombre",
|
"Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "Usar coincidencia difusa y buscar personajes en la lista por todos los campos de datos, no solo por una subcadena de nombre",
|
||||||
"If checked and the character card contains a prompt override (System Prompt), use that instead": "Si está marcado y la tarjeta de personaje contiene una anulación de indicación (Indicación del sistema), usar eso en su lugar",
|
"If checked and the character card contains a prompt override (System Prompt), use that instead": "Si está marcado y la tarjeta de personaje contiene una anulación de indicación (Indicación del sistema), usar eso en su lugar",
|
||||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Si está marcado y la tarjeta de personaje contiene una anulación de jailbreak (Instrucción de Historial de Publicaciones), usar eso en su lugar",
|
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "Si está marcado y la tarjeta de personaje contiene una anulación de jailbreak (Instrucciones Post Historial), usar eso en su lugar",
|
||||||
"Avoid cropping and resizing imported character images. When off, crop/resize to 400x600": "Evitar recortar y redimensionar imágenes de personajes importadas. Cuando esté desactivado, recortar/redimensionar a 400x600",
|
"Avoid cropping and resizing imported character images. When off, crop/resize to 400x600": "Evitar recortar y redimensionar imágenes de personajes importadas. Cuando esté desactivado, recortar/redimensionar a 400x600",
|
||||||
"Show actual file names on the disk, in the characters list display only": "Mostrar nombres de archivo reales en el disco, solo en la visualización de la lista de personajes",
|
"Show actual file names on the disk, in the characters list display only": "Mostrar nombres de archivo reales en el disco, solo en la visualización de la lista de personajes",
|
||||||
"Prompt to import embedded card tags on character import. Otherwise embedded tags are ignored": "Solicitar importar etiquetas de tarjeta incrustadas al importar un personaje. De lo contrario, las etiquetas incrustadas se ignoran",
|
"Prompt to import embedded card tags on character import. Otherwise embedded tags are ignored": "Solicitar importar etiquetas de tarjeta incrustadas al importar un personaje. De lo contrario, las etiquetas incrustadas se ignoran",
|
||||||
@@ -590,7 +590,7 @@
|
|||||||
"Show arrow buttons on the last in-chat message to generate alternative AI responses. Both PC and mobile": "Mostrar botones de flecha en el último mensaje del chat para generar respuestas alternativas de la IA. Tanto PC como móvil",
|
"Show arrow buttons on the last in-chat message to generate alternative AI responses. Both PC and mobile": "Mostrar botones de flecha en el último mensaje del chat para generar respuestas alternativas de la IA. Tanto PC como móvil",
|
||||||
"Allow using swiping gestures on the last in-chat message to trigger swipe generation. Mobile only, no effect on PC": "Permitir el uso de gestos de deslizamiento en el último mensaje del chat para activar la generación de deslizamiento. Solo móvil, sin efecto en PC",
|
"Allow using swiping gestures on the last in-chat message to trigger swipe generation. Mobile only, no effect on PC": "Permitir el uso de gestos de deslizamiento en el último mensaje del chat para activar la generación de deslizamiento. Solo móvil, sin efecto en PC",
|
||||||
"Save edits to messages without confirmation as you type": "Guardar ediciones en mensajes sin confirmación mientras escribe",
|
"Save edits to messages without confirmation as you type": "Guardar ediciones en mensajes sin confirmación mientras escribe",
|
||||||
"Render LaTeX and AsciiMath equation notation in chat messages. Powered by KaTeX": "Renderizar notación de ecuaciones LaTeX y AsciiMath en mensajes de chat. Alimentado por KaTeX",
|
"Render LaTeX and AsciiMath equation notation in chat messages. Powered by KaTeX": "Renderizar notación de ecuaciones LaTeX y AsciiMath en mensajes de chat. Impulsado por KaTeX",
|
||||||
"Disalow embedded media from other domains in chat messages": "No permitir medios incrustados de otros dominios en mensajes de chat",
|
"Disalow embedded media from other domains in chat messages": "No permitir medios incrustados de otros dominios en mensajes de chat",
|
||||||
"Skip encoding and characters in message text, allowing a subset of HTML markup as well as Markdown": "Omitir la codificación de los caracteres en el texto del mensaje, permitiendo un subconjunto de marcado HTML, así como Markdown",
|
"Skip encoding and characters in message text, allowing a subset of HTML markup as well as Markdown": "Omitir la codificación de los caracteres en el texto del mensaje, permitiendo un subconjunto de marcado HTML, así como Markdown",
|
||||||
"Allow AI messages in groups to contain lines spoken by other group members": "Permitir que los mensajes de IA en grupos contengan líneas habladas por otros miembros del grupo",
|
"Allow AI messages in groups to contain lines spoken by other group members": "Permitir que los mensajes de IA en grupos contengan líneas habladas por otros miembros del grupo",
|
||||||
@@ -599,7 +599,7 @@
|
|||||||
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Habilitar la función de deslizamiento automático. La configuración en esta sección solo tiene efecto cuando el deslizamiento automático está habilitado",
|
"Enable the auto-swipe function. Settings in this section only have an effect when auto-swipe is enabled": "Habilitar la función de deslizamiento automático. La configuración en esta sección solo tiene efecto cuando el deslizamiento automático está habilitado",
|
||||||
"If the generated message is shorter than this, trigger an auto-swipe": "Si el mensaje generado es más corto que esto, activar un deslizamiento automático",
|
"If the generated message is shorter than this, trigger an auto-swipe": "Si el mensaje generado es más corto que esto, activar un deslizamiento automático",
|
||||||
"Reload and redraw the currently open chat": "Recargar y volver a dibujar el chat abierto actualmente",
|
"Reload and redraw the currently open chat": "Recargar y volver a dibujar el chat abierto actualmente",
|
||||||
"Auto-Expand Message Actions": "Expansión Automática de Acciones de Mensaje",
|
"Auto-Expand Message Actions": "Expandir Automáticamente de Acciones de Mensaje",
|
||||||
"Not Connected": "No Conectado",
|
"Not Connected": "No Conectado",
|
||||||
"Persona Management": "Gestión de Personas",
|
"Persona Management": "Gestión de Personas",
|
||||||
"Persona Description": "Descripción de Persona",
|
"Persona Description": "Descripción de Persona",
|
||||||
@@ -609,16 +609,16 @@
|
|||||||
"In Story String / Chat Completion: Before Character Card": "En la Cadena de Historia / Completado de Chat: Antes de la Tarjeta de Personaje",
|
"In Story String / Chat Completion: Before Character Card": "En la Cadena de Historia / Completado de Chat: Antes de la Tarjeta de Personaje",
|
||||||
"In Story String / Chat Completion: After Character Card": "En la Cadena de Historia / Completado de Chat: Después de la Tarjeta de Personaje",
|
"In Story String / Chat Completion: After Character Card": "En la Cadena de Historia / Completado de Chat: Después de la Tarjeta de Personaje",
|
||||||
"In Story String / Prompt Manager": "En la Cadena de Historia / Administrador de Indicaciones",
|
"In Story String / Prompt Manager": "En la Cadena de Historia / Administrador de Indicaciones",
|
||||||
"Top of Author's Note": "Parte Superior de la Nota del Autor",
|
"Top of Author's Note": "Parte Superior de la Nota de Autor",
|
||||||
"Bottom of Author's Note": "Parte Inferior de la Nota del Autor",
|
"Bottom of Author's Note": "Parte Inferior de la Nota de Autor",
|
||||||
"How do I use this?": "¿Cómo uso esto?",
|
"How do I use this?": "¿Cómo uso esto?",
|
||||||
"More...": "Más...",
|
"More...": "Más...",
|
||||||
"Link to World Info": "Enlace a Información del Mundo",
|
"Link to World Info": "Enlazar a Información de Mundo (WI)",
|
||||||
"Import Card Lore": "Importar Lore de Tarjeta",
|
"Import Card Lore": "Importar Historia de Tarjeta",
|
||||||
"Scenario Override": "Anulación de Escenario",
|
"Scenario Override": "Anulación de Escenario",
|
||||||
"Rename": "Renombrar",
|
"Rename": "Renombrar",
|
||||||
"Character Description": "Descripción del Personaje",
|
"Character Description": "Descripción del Personaje",
|
||||||
"Creator's Notes": "Notas del Creador",
|
"Creator's Notes": "Nota del Creador",
|
||||||
"A-Z": "A-Z",
|
"A-Z": "A-Z",
|
||||||
"Z-A": "Z-A",
|
"Z-A": "Z-A",
|
||||||
"Newest": "Más Reciente",
|
"Newest": "Más Reciente",
|
||||||
@@ -628,11 +628,11 @@
|
|||||||
"Most chats": "Más Chats",
|
"Most chats": "Más Chats",
|
||||||
"Least chats": "Menos Chats",
|
"Least chats": "Menos Chats",
|
||||||
"Back": "Volver",
|
"Back": "Volver",
|
||||||
"Prompt Overrides (For OpenAI/Claude/Scale APIs, Window/OpenRouter, and Instruct mode)": "Sustituciones de Indicaciones (Para APIs de OpenAI/Claude/Scale, Ventana/OpenRouter y Modo Instrucción)",
|
"Prompt Overrides (For OpenAI/Claude/Scale APIs, Window/OpenRouter, and Instruct mode)": "Anulaciones de Indicaciones (Para APIs de OpenAI/Claude/Scale, Window/OpenRouter y Modo Instrucción)",
|
||||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserte {{original}} en cualquiera de las casillas para incluir la indicación predeterminada respectiva de la configuración del sistema.",
|
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserte {{original}} en cualquiera de las casillas para incluir las indicaciones predeterminadas respectivas de la configuración del sistema.",
|
||||||
"Main Prompt": "Indicación Principal",
|
"Main Prompt": "Indicaciones Principales",
|
||||||
"Jailbreak": "Jailbreak",
|
"Jailbreak": "Jailbreak",
|
||||||
"Creator's Metadata (Not sent with the AI prompt)": "Metadatos del Creador (No enviados con la indicación de la IA)",
|
"Creator's Metadata (Not sent with the AI prompt)": "Metadatos del Creador (No enviados con las indicaciones de la IA)",
|
||||||
"Everything here is optional": "Todo aquí es opcional",
|
"Everything here is optional": "Todo aquí es opcional",
|
||||||
"Created by": "Creado por",
|
"Created by": "Creado por",
|
||||||
"Character Version": "Versión del Personaje",
|
"Character Version": "Versión del Personaje",
|
||||||
@@ -641,11 +641,11 @@
|
|||||||
"Important to set the character's writing style.": "Importante para establecer el estilo de escritura del personaje.",
|
"Important to set the character's writing style.": "Importante para establecer el estilo de escritura del personaje.",
|
||||||
"ATTENTION!": "¡ATENCIÓN!",
|
"ATTENTION!": "¡ATENCIÓN!",
|
||||||
"Samplers Order": "Orden de Muestreadores",
|
"Samplers Order": "Orden de Muestreadores",
|
||||||
"Samplers will be applied in a top-down order. Use with caution.": "Los Muestreadores se aplicarán en un orden de arriba hacia abajo. Úselo con precaución.",
|
"Samplers will be applied in a top-down order. Use with caution.": "Los Muestreadores se aplicarán en un orden de arriba hacia abajo. Úsalo con precaución.",
|
||||||
"Repetition Penalty": "Penalización por Repetición",
|
"Repetition Penalty": "Penalización por Repetición",
|
||||||
"Rep. Pen. Range.": "Rango de Pen. Rep.",
|
"Rep. Pen. Range.": "Rango de Pen. Rep.",
|
||||||
"Rep. Pen. Freq.": "Frec. Pen. Rep.",
|
"Rep. Pen. Freq.": "Frec. de Pen. Rep.",
|
||||||
"Rep. Pen. Presence": "Presencia Pen. Rep.",
|
"Rep. Pen. Presence": "Presencia de Pen. Rep.",
|
||||||
"Enter it in the box below:": "Introdúzcalo en la casilla de abajo:",
|
"Enter it in the box below:": "Introdúzcalo en la casilla de abajo:",
|
||||||
"separate with commas w/o space between": "separe con comas sin espacio entre ellas",
|
"separate with commas w/o space between": "separe con comas sin espacio entre ellas",
|
||||||
"Document": "Documento",
|
"Document": "Documento",
|
||||||
@@ -658,7 +658,7 @@
|
|||||||
"Editing:": "Editando:",
|
"Editing:": "Editando:",
|
||||||
"AI reply prefix": "Prefijo de Respuesta de IA",
|
"AI reply prefix": "Prefijo de Respuesta de IA",
|
||||||
"Custom Stopping Strings": "Cadenas de Detención Personalizadas",
|
"Custom Stopping Strings": "Cadenas de Detención Personalizadas",
|
||||||
"JSON serialized array of strings": "Arreglo serializado JSON de cadenas",
|
"JSON serialized array of strings": "Arreglo de cadenas serializado en JSON",
|
||||||
"words you dont want generated separated by comma ','": "palabras que no desea generar separadas por coma ','",
|
"words you dont want generated separated by comma ','": "palabras que no desea generar separadas por coma ','",
|
||||||
"Extensions URL": "URL de Extensiones",
|
"Extensions URL": "URL de Extensiones",
|
||||||
"API Key": "Clave de API",
|
"API Key": "Clave de API",
|
||||||
@@ -670,10 +670,10 @@
|
|||||||
"Chat Name (Optional)": "Nombre del Chat (Opcional)",
|
"Chat Name (Optional)": "Nombre del Chat (Opcional)",
|
||||||
"Filter...": "Filtrar...",
|
"Filter...": "Filtrar...",
|
||||||
"Search...": "Buscar...",
|
"Search...": "Buscar...",
|
||||||
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "Cualquier contenido aquí reemplazará la Indicación Principal predeterminada utilizada para este personaje. (v2 especificación: system_prompt)",
|
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "Cualquier contenido aquí reemplazará las Indicaciones Principales predeterminada utilizada para este personaje. (especificación v2: system_prompt)",
|
||||||
"Any contents here will replace the default Jailbreak Prompt used for this character. (v2 spec: post_history_instructions)": "Cualquier contenido aquí reemplazará la Indicación de Desbloqueo predeterminada utilizada para este personaje. (v2 especificación: post_history_instructions)",
|
"Any contents here will replace the default Jailbreak Prompt used for this character. (v2 spec: post_history_instructions)": "Cualquier contenido aquí reemplazará las Indicaciones de Jailbreak predeterminada utilizada para este personaje. (especificación v2: post_history_instructions)",
|
||||||
"(Botmaker's name / Contact Info)": "(Nombre del creador del bot / Información de contacto)",
|
"(Botmaker's name / Contact Info)": "(Nombre del creador del bot / Información de contacto)",
|
||||||
"(If you want to track character versions)": "(Si desea rastrear las versiones de los personajes)",
|
"(If you want to track character versions)": "(Si desea rastrear versiones de personajes)",
|
||||||
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "(Describa el bot, dé consejos de uso o enumere los modelos de chat en los que se ha probado. Esto se mostrará en la lista de personajes.)",
|
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "(Describa el bot, dé consejos de uso o enumere los modelos de chat en los que se ha probado. Esto se mostrará en la lista de personajes.)",
|
||||||
"(Write a comma-separated list of tags)": "(Escriba una lista de etiquetas separadas por comas)",
|
"(Write a comma-separated list of tags)": "(Escriba una lista de etiquetas separadas por comas)",
|
||||||
"(A brief description of the personality)": "(Una breve descripción de la personalidad)",
|
"(A brief description of the personality)": "(Una breve descripción de la personalidad)",
|
||||||
@@ -694,19 +694,19 @@
|
|||||||
"Not connected to API!": "¡No conectado a la API!",
|
"Not connected to API!": "¡No conectado a la API!",
|
||||||
"AI Response Configuration": "Configuración de Respuesta de IA",
|
"AI Response Configuration": "Configuración de Respuesta de IA",
|
||||||
"AI Configuration panel will stay open": "El panel de Configuración de IA permanecerá abierto",
|
"AI Configuration panel will stay open": "El panel de Configuración de IA permanecerá abierto",
|
||||||
"Update current preset": "Actualizar la configuración actual",
|
"Update current preset": "Actualizar el preajuste actual",
|
||||||
"Create new preset": "Crear nueva configuración",
|
"Create new preset": "Crear nuevo preajuste",
|
||||||
"Import preset": "Importar configuración",
|
"Import preset": "Importar preajuste",
|
||||||
"Export preset": "Exportar configuración",
|
"Export preset": "Exportar preajuste",
|
||||||
"Delete the preset": "Eliminar la configuración",
|
"Delete the preset": "Eliminar el preajuste",
|
||||||
"Auto-select this preset for Instruct Mode": "Auto-seleccionar esta configuración para el Modo Instrucción",
|
"Auto-select this preset for Instruct Mode": "Auto-seleccionar este preajuste para el Modo Instrucción",
|
||||||
"Auto-select this preset on API connection": "Auto-seleccionar esta configuración en la conexión de la API",
|
"Auto-select this preset on API connection": "Auto-seleccionar este preajuste en la conexión de la API",
|
||||||
"NSFW block goes first in the resulting prompt": "El bloque NSFW va primero en la indicación resultante",
|
"NSFW block goes first in the resulting prompt": "El bloque NSFW va primero en la indicación resultante",
|
||||||
"Enables OpenAI completion streaming": "Permite la transmisión de completado de OpenAI",
|
"Enables OpenAI completion streaming": "Permite streaming de completado de OpenAI",
|
||||||
"Wrap user messages in quotes before sending": "Envolver los mensajes de usuario entre comillas antes de enviarlos",
|
"Wrap user messages in quotes before sending": "Envolver los mensajes de usuario entre comillas antes de enviarlos",
|
||||||
"Restore default prompt": "Restaurar la indicación predeterminada",
|
"Restore default prompt": "Restaurar las indicaciones predeterminada",
|
||||||
"New preset": "Nueva configuración",
|
"New preset": "Nuevo preajuste",
|
||||||
"Delete preset": "Eliminar configuración",
|
"Delete preset": "Eliminar preajuste",
|
||||||
"Restore default jailbreak": "Restaurar el jailbreak predeterminado",
|
"Restore default jailbreak": "Restaurar el jailbreak predeterminado",
|
||||||
"Restore default reply": "Restaurar la respuesta predeterminada",
|
"Restore default reply": "Restaurar la respuesta predeterminada",
|
||||||
"Restore default note": "Restaurar la nota predeterminada",
|
"Restore default note": "Restaurar la nota predeterminada",
|
||||||
@@ -715,21 +715,21 @@
|
|||||||
"Clear your API key": "Borrar tu clave de API",
|
"Clear your API key": "Borrar tu clave de API",
|
||||||
"Refresh models": "Actualizar modelos",
|
"Refresh models": "Actualizar modelos",
|
||||||
"Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "Obtenga su token de API de OpenRouter utilizando el flujo OAuth. Será redirigido a openrouter.ai",
|
"Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "Obtenga su token de API de OpenRouter utilizando el flujo OAuth. Será redirigido a openrouter.ai",
|
||||||
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica su conexión de API enviando un breve mensaje de prueba. ¡Tenga en cuenta que se le acreditará por ello!",
|
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica su conexión de API enviando un breve mensaje de prueba. ¡Tenga en cuenta que se le cobrará por ello!",
|
||||||
"Create New": "Crear Nuevo",
|
"Create New": "Crear Nuevo",
|
||||||
"Edit": "Editar",
|
"Edit": "Editar",
|
||||||
"Locked = World Editor will stay open": "Bloqueado = El Editor de Mundo permanecerá abierto",
|
"Locked = World Editor will stay open": "Bloqueado = El Editor de Mundo permanecerá abierto",
|
||||||
"Entries can activate other entries by mentioning their keywords": "Las entradas pueden activar otras entradas mencionando sus palabras clave",
|
"Entries can activate other entries by mentioning their keywords": "Las entradas pueden activar otras entradas mencionando sus palabras clave",
|
||||||
"Lookup for the entry keys in the context will respect the case": "La búsqueda de las claves de entrada en el contexto respetará el caso",
|
"Lookup for the entry keys in the context will respect the case": "La búsqueda de las claves de entrada en el contexto respetará mayúsculas y minúsculas",
|
||||||
"If the entry key consists of only one word, it would not be matched as part of other words": "Si la clave de entrada consiste en solo una palabra, no se emparejará como parte de otras palabras",
|
"If the entry key consists of only one word, it would not be matched as part of other words": "Si la clave de entrada consiste en solo una palabra, no se emparejará como parte de otras palabras",
|
||||||
"Open all Entries": "Abrir Todas las Entradas",
|
"Open all Entries": "Abrir Todas las Entradas",
|
||||||
"Close all Entries": "Cerrar Todas las Entradas",
|
"Close all Entries": "Cerrar Todas las Entradas",
|
||||||
"Create": "Crear",
|
"Create": "Crear",
|
||||||
"Import World Info": "Importar Información del Mundo",
|
"Import World Info": "Importar Información de Mundo (WI)",
|
||||||
"Export World Info": "Exportar Información del Mundo",
|
"Export World Info": "Exportar Información de Mundo (WI)",
|
||||||
"Delete World Info": "Eliminar Información del Mundo",
|
"Delete World Info": "Eliminar Información de Mundo (WI)",
|
||||||
"Duplicate World Info": "Duplicar Información del Mundo",
|
"Duplicate World Info": "Duplicar Información de Mundo (WI)",
|
||||||
"Rename World Info": "Renombrar Información del Mundo",
|
"Rename World Info": "Renombrar Información de Mundo (WI)",
|
||||||
"Refresh": "Actualizar",
|
"Refresh": "Actualizar",
|
||||||
"Primary Keywords": "Palabras Clave Primarias",
|
"Primary Keywords": "Palabras Clave Primarias",
|
||||||
"Logic": "Lógica",
|
"Logic": "Lógica",
|
||||||
@@ -752,13 +752,13 @@
|
|||||||
"Character Management": "Gestión de Personajes",
|
"Character Management": "Gestión de Personajes",
|
||||||
"Locked = Character Management panel will stay open": "Bloqueado = El panel de Gestión de Personajes permanecerá abierto",
|
"Locked = Character Management panel will stay open": "Bloqueado = El panel de Gestión de Personajes permanecerá abierto",
|
||||||
"Select/Create Characters": "Seleccionar/Crear Personajes",
|
"Select/Create Characters": "Seleccionar/Crear Personajes",
|
||||||
"Token counts may be inaccurate and provided just for reference.": "Las cuentas de tokens pueden ser inexactas y se proporcionan solo como referencia.",
|
"Token counts may be inaccurate and provided just for reference.": "El conteo de tokens pueden ser inexacto y se proporcionan solo como referencia.",
|
||||||
"Click to select a new avatar for this character": "Haga clic para seleccionar un nuevo avatar para este personaje",
|
"Click to select a new avatar for this character": "Haga clic para seleccionar un nuevo avatar para este personaje",
|
||||||
"Example: [{{user}} is a 28-year-old Romanian cat girl.]": "Ejemplo: [{{user}} es una chica gata rumana de 28 años.]",
|
"Example: [{{user}} is a 28-year-old Romanian cat girl.]": "Ejemplo: [{{user}} es una chica gata rumana de 28 años.]",
|
||||||
"Toggle grid view": "Alternar vista de cuadrícula",
|
"Toggle grid view": "Alternar vista de cuadrícula",
|
||||||
"Add to Favorites": "Agregar a Favoritos",
|
"Add to Favorites": "Agregar a Favoritos",
|
||||||
"Advanced Definition": "Definición Avanzada",
|
"Advanced Definition": "Definición Avanzada",
|
||||||
"Character Lore": "Trasfondo del personaje",
|
"Character Lore": "Historia (Trasfondo) del personaje",
|
||||||
"Export and Download": "Exportar y descargar",
|
"Export and Download": "Exportar y descargar",
|
||||||
"Duplicate Character": "Duplicar personaje",
|
"Duplicate Character": "Duplicar personaje",
|
||||||
"Create Character": "Crear personaje",
|
"Create Character": "Crear personaje",
|
||||||
@@ -769,21 +769,21 @@
|
|||||||
"Click to select a new avatar for this group": "Haz clic para seleccionar un nuevo avatar para este grupo",
|
"Click to select a new avatar for this group": "Haz clic para seleccionar un nuevo avatar para este grupo",
|
||||||
"Set a group chat scenario": "Establecer un escenario de chat grupal",
|
"Set a group chat scenario": "Establecer un escenario de chat grupal",
|
||||||
"Restore collage avatar": "Restaurar avatar de collage",
|
"Restore collage avatar": "Restaurar avatar de collage",
|
||||||
"Create New Character": "Crear nuevo personaje",
|
"Create New Character": "Crear Nuevo Personaje",
|
||||||
"Import Character from File": "Importar personaje desde archivo",
|
"Import Character from File": "Importar Personaje desde Archivo",
|
||||||
"Import content from external URL": "Importar contenido desde URL externa",
|
"Import content from external URL": "Importar contenido desde URL externa",
|
||||||
"Create New Chat Group": "Crear nuevo grupo de chat",
|
"Create New Chat Group": "Crear Nuevo Grupo de Chat",
|
||||||
"Characters sorting order": "Orden de clasificación de personajes",
|
"Characters sorting order": "Orden de clasificación de personajes",
|
||||||
"Add chat injection": "Agregar inyección de chat",
|
"Add chat injection": "Agregar inyección de chat",
|
||||||
"Remove injection": "Eliminar inyección",
|
"Remove injection": "Eliminar inyección",
|
||||||
"Remove": "Eliminar",
|
"Remove": "Eliminar",
|
||||||
"Select a World Info file for": "Seleccionar un archivo de Información Mundial para",
|
"Select a World Info file for": "Seleccionar un archivo de Información de Mundo (WI) para",
|
||||||
"Primary Lorebook": "Libro de historias primario",
|
"Primary Lorebook": "Libro de Historia primario",
|
||||||
"A selected World Info will be bound to this character as its own Lorebook.": "Una Información Mundial seleccionada se vinculará a este personaje como su propio Libro de historias.",
|
"A selected World Info will be bound to this character as its own Lorebook.": "Una Información de Mundo (WI) seleccionada se vinculará a este personaje como su propio Libro de Historia.",
|
||||||
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "Al generar una respuesta de IA, se combinará con las entradas de un selector global de Información Mundial.",
|
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "Al generar una respuesta de IA, se combinará con las entradas de un selector global de Información Mundial.",
|
||||||
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "Exportar un personaje también exportaría el archivo de Libro de historias seleccionado incrustado en los datos JSON.",
|
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "Exportar un personaje también exportaría el archivo de Libro de Historia seleccionado incrustado en los datos JSON.",
|
||||||
"Additional Lorebooks": "Libros de historias adicionales",
|
"Additional Lorebooks": "Libros de Historia Adicionales",
|
||||||
"Associate one or more auxillary Lorebooks with this character.": "Asociar uno o más Libros de historias auxiliares con este personaje.",
|
"Associate one or more auxillary Lorebooks with this character.": "Asociar uno o más Libros de Historia auxiliares con este personaje.",
|
||||||
"NOTE: These choices are optional and won't be preserved on character export!": "NOTA: ¡Estas opciones son opcionales y no se conservarán al exportar el personaje!",
|
"NOTE: These choices are optional and won't be preserved on character export!": "NOTA: ¡Estas opciones son opcionales y no se conservarán al exportar el personaje!",
|
||||||
"Rename chat file": "Renombrar archivo de chat",
|
"Rename chat file": "Renombrar archivo de chat",
|
||||||
"Export JSONL chat file": "Exportar archivo de chat JSONL",
|
"Export JSONL chat file": "Exportar archivo de chat JSONL",
|
||||||
@@ -815,19 +815,19 @@
|
|||||||
"Abort request": "Cancelar solicitud",
|
"Abort request": "Cancelar solicitud",
|
||||||
"Send a message": "Enviar un mensaje",
|
"Send a message": "Enviar un mensaje",
|
||||||
"Ask AI to write your message for you": "Pídele a la IA que escriba tu mensaje por ti",
|
"Ask AI to write your message for you": "Pídele a la IA que escriba tu mensaje por ti",
|
||||||
"Continue the last message": "Continuar con el último mensaje",
|
"Continue the last message": "Continuar el último mensaje",
|
||||||
"Bind user name to that avatar": "Vincular nombre de usuario a ese avatar",
|
"Bind user name to that avatar": "Vincular nombre de usuario a ese avatar",
|
||||||
"Select this as default persona for the new chats.": "Seleccionar esto como persona predeterminada para los nuevos chats.",
|
"Select this as default persona for the new chats.": "Seleccionar esta persona como predeterminada para los nuevos chats.",
|
||||||
"Change persona image": "Cambiar imagen de persona",
|
"Change persona image": "Cambiar imagen de persona",
|
||||||
"Delete persona": "Eliminar persona",
|
"Delete persona": "Eliminar persona",
|
||||||
"Reduced Motion": "Movimiento reducido",
|
"Reduced Motion": "Movimiento reducido",
|
||||||
"Auto-select": "Auto-seleccionar",
|
"Auto-select": "Auto-seleccionar",
|
||||||
"Automatically select a background based on the chat context": "Seleccionar automáticamente un fondo basado en el contexto del chat",
|
"Automatically select a background based on the chat context": "Seleccionar automáticamente un fondo basado en el contexto del chat",
|
||||||
"Filter": "Filtro",
|
"Filter": "Filtro",
|
||||||
"Exclude message from prompts": "Excluir mensaje de indicaciones",
|
"Exclude message from prompts": "Excluir mensaje de las indicaciones",
|
||||||
"Include message in prompts": "Incluir mensaje en indicaciones",
|
"Include message in prompts": "Incluir mensaje en las indicaciones",
|
||||||
"Create checkpoint": "Crear punto de control",
|
"Create checkpoint": "Crear punto de control",
|
||||||
"Create Branch": "Crear rama",
|
"Create Branch": "Crear Rama",
|
||||||
"Embed file or image": "Insertar archivo o imagen",
|
"Embed file or image": "Insertar archivo o imagen",
|
||||||
"UI Theme": "Tema de interfaz de usuario",
|
"UI Theme": "Tema de interfaz de usuario",
|
||||||
"This message is invisible for the AI": "Este mensaje es invisible para la IA",
|
"This message is invisible for the AI": "Este mensaje es invisible para la IA",
|
||||||
@@ -837,7 +837,7 @@
|
|||||||
"Max Tokens Second": "Máximo de tokens por segundo",
|
"Max Tokens Second": "Máximo de tokens por segundo",
|
||||||
"CFG": "CFG",
|
"CFG": "CFG",
|
||||||
"No items": "Sin elementos",
|
"No items": "Sin elementos",
|
||||||
"Extras API key (optional)": "Clave API de extras (opcional)",
|
"Extras API key (optional)": "Clave API de Extras (opcional)",
|
||||||
"Notify on extension updates": "Notificar sobre actualizaciones de extensión",
|
"Notify on extension updates": "Notificar sobre actualizaciones de extensión",
|
||||||
"Toggle character grid view": "Alternar vista de cuadrícula de personajes",
|
"Toggle character grid view": "Alternar vista de cuadrícula de personajes",
|
||||||
"Bulk edit characters": "Editar personajes masivamente",
|
"Bulk edit characters": "Editar personajes masivamente",
|
||||||
@@ -854,7 +854,7 @@
|
|||||||
"Most tokens": "Más tokens",
|
"Most tokens": "Más tokens",
|
||||||
"Least tokens": "Menos tokens",
|
"Least tokens": "Menos tokens",
|
||||||
"Random": "Aleatorio",
|
"Random": "Aleatorio",
|
||||||
"Skip Example Dialogues Formatting": "Omitir formato de diálogos de ejemplo",
|
"Skip Example Dialogues Formatting": "Omitir Formato de Diálogos de Ejemplo",
|
||||||
"Import a theme file": "Importar un archivo de tema",
|
"Import a theme file": "Importar un archivo de tema",
|
||||||
"Export a theme file": "Exportar un archivo de tema",
|
"Export a theme file": "Exportar un archivo de tema",
|
||||||
"Unlocked Context Size": "Tamaño de contexto desbloqueado",
|
"Unlocked Context Size": "Tamaño de contexto desbloqueado",
|
||||||
@@ -866,33 +866,33 @@
|
|||||||
"Utility Prompts": "Indicaciones de utilidad",
|
"Utility Prompts": "Indicaciones de utilidad",
|
||||||
"Add character names": "Agregar nombres de personajes",
|
"Add character names": "Agregar nombres de personajes",
|
||||||
"Send names in the message objects. Helps the model to associate messages with characters.": "Enviar nombres en los objetos de mensaje. Ayuda al modelo a asociar mensajes con personajes.",
|
"Send names in the message objects. Helps the model to associate messages with characters.": "Enviar nombres en los objetos de mensaje. Ayuda al modelo a asociar mensajes con personajes.",
|
||||||
"Continue prefill": "Continuar con prefiltro",
|
"Continue prefill": "Continuar con prellenado",
|
||||||
"Continue sends the last message as assistant role instead of system message with instruction.": "Continuar envía el último mensaje como rol de asistente en lugar de mensaje del sistema con instrucciones.",
|
"Continue sends the last message as assistant role instead of system message with instruction.": "Continuar envía el último mensaje como rol de asistente en lugar de mensaje del sistema con instrucciones.",
|
||||||
"Squash system messages": "Aplastar mensajes del sistema",
|
"Squash system messages": "Aplastar mensajes del sistema",
|
||||||
"Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensajes del sistema consecutivos en uno solo (excluyendo diálogos de ejemplo). Puede mejorar la coherencia para algunos modelos.",
|
"Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensajes del sistema consecutivos en uno solo (excluyendo diálogos de ejemplo). Puede mejorar la coherencia para algunos modelos.",
|
||||||
"Send inline images": "Enviar imágenes en línea",
|
"Send inline images": "Enviar imágenes en línea",
|
||||||
"Assistant Prefill": "Prefiltro de asistente",
|
"Assistant Prefill": "Prellenado de Asistente",
|
||||||
"Start Claude's answer with...": "Iniciar la respuesta de Claude con...",
|
"Start Claude's answer with...": "Iniciar la respuesta de Claude con...",
|
||||||
"Use system prompt (Claude 2.1+ only)": "Usar indicación del sistema (solo Claude 2.1+)",
|
"Use system prompt (Claude 2.1+ only)": "Usar indicación del sistema (solo para Claude 2.1+)",
|
||||||
"Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar la indicación del sistema para los modelos admitidos. Si está desactivado, el mensaje del usuario se agrega al principio de la indicación.",
|
"Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar la indicación del sistema para los modelos admitidos. Si está desactivado, el mensaje del usuario se agrega al principio de las indicaciónes.",
|
||||||
"Prompts": "Indicaciones",
|
"Prompts": "Indicaciones",
|
||||||
"Total Tokens:": "Tokens totales:",
|
"Total Tokens:": "Tokens totales:",
|
||||||
"Insert prompt": "Insertar indicación",
|
"Insert prompt": "Insertar indicaciones",
|
||||||
"Delete prompt": "Eliminar indicación",
|
"Delete prompt": "Eliminar indicaciones",
|
||||||
"Import a prompt list": "Importar una lista de indicaciones",
|
"Import a prompt list": "Importar una lista de indicaciones",
|
||||||
"Export this prompt list": "Exportar esta lista de indicaciones",
|
"Export this prompt list": "Exportar esta lista de indicaciones",
|
||||||
"Reset current character": "Restablecer personaje actual",
|
"Reset current character": "Restablecer personaje actual",
|
||||||
"New prompt": "Nueva indicación",
|
"New prompt": "Nuevas indicaciones",
|
||||||
"Tokens": "Tokens",
|
"Tokens": "Tokens",
|
||||||
"Want to update?": "¿Quieres actualizar?",
|
"Want to update?": "¿Quieres actualizar?",
|
||||||
"How to start chatting?": "¿Cómo empezar a chatear?",
|
"How to start chatting?": "¿Cómo empezar a chatear?",
|
||||||
"Click": "Haz clic ",
|
"Click": "Haz clic ",
|
||||||
"and select a": "y selecciona un",
|
"and select a": "y selecciona una",
|
||||||
"Chat API": " API de chat",
|
"Chat API": " API de chat",
|
||||||
"and pick a character": "y elige un personaje",
|
"and pick a character": "y elige un personaje",
|
||||||
"in the chat bar": "en la barra de chat",
|
"in the chat bar": "en la barra de chat",
|
||||||
"Confused or lost?": "¿Confundido o perdido?",
|
"Confused or lost?": "¿Confundido o perdido?",
|
||||||
"click these icons!": "¡haz clic en estos iconos!",
|
"click these icons!": "¡Haz clic en estos iconos!",
|
||||||
"SillyTavern Documentation Site": "Sitio de documentación de SillyTavern",
|
"SillyTavern Documentation Site": "Sitio de documentación de SillyTavern",
|
||||||
"Extras Installation Guide": "Guía de instalación de extras",
|
"Extras Installation Guide": "Guía de instalación de extras",
|
||||||
"Still have questions?": "¿Todavía tienes preguntas?",
|
"Still have questions?": "¿Todavía tienes preguntas?",
|
||||||
@@ -909,10 +909,10 @@
|
|||||||
"Medium": "Medio",
|
"Medium": "Medio",
|
||||||
"Aggressive": "Agresivo",
|
"Aggressive": "Agresivo",
|
||||||
"Very aggressive": "Muy agresivo",
|
"Very aggressive": "Muy agresivo",
|
||||||
"Eta cutoff is the main parameter of the special Eta Sampling technique. In units of 1e-4; a reasonable value is 3. Set to 0 to disable. See the paper Truncation Sampling as Language Model Desmoothing by Hewitt et al. (2022) for details.": "El corte de Eta es el parámetro principal de la técnica especial de Muestreo Eta. En unidades de 1e-4; un valor razonable es 3. Establecer en 0 para desactivar. Consulte el documento Truncation Sampling as Language Model Desmoothing de Hewitt et al. (2022) para más detalles.",
|
"Eta cutoff is the main parameter of the special Eta Sampling technique. In units of 1e-4; a reasonable value is 3. Set to 0 to disable. See the paper Truncation Sampling as Language Model Desmoothing by Hewitt et al. (2022) for details.": "El Corte de Eta es el parámetro principal de la técnica especial de Muestreo Eta. En unidades de 1e-4; un valor razonable es 3. Establecer en 0 para desactivar. Consulte el documento Truncation Sampling as Language Model Desmoothing de Hewitt et al. (2022) para más detalles.",
|
||||||
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende cómo contribuir con tus ciclos de GPU inactivos a la Horda",
|
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende cómo contribuir con tus ciclos de GPU inactivos a Horde",
|
||||||
"Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.": "Usa el tokenizador apropiado para los modelos de Google a través de su API. Procesamiento de indicaciones más lento, pero ofrece un recuento de tokens mucho más preciso.",
|
"Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.": "Usa el tokenizador apropiado para los modelos de Google a través de su API. Procesamiento de indicaciones más lento, pero ofrece un recuento de tokens mucho más preciso.",
|
||||||
"Load koboldcpp order": "Cargar orden koboldcpp",
|
"Load koboldcpp order": "Cargar orden de koboldcpp",
|
||||||
"Use Google Tokenizer": "Usar Tokenizador de Google"
|
"Use Google Tokenizer": "Usar Tokenizador de Google"
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ const MODULE_NAME = 'expressions';
|
|||||||
const UPDATE_INTERVAL = 2000;
|
const UPDATE_INTERVAL = 2000;
|
||||||
const STREAMING_UPDATE_INTERVAL = 6000;
|
const STREAMING_UPDATE_INTERVAL = 6000;
|
||||||
const TALKINGCHECK_UPDATE_INTERVAL = 500;
|
const TALKINGCHECK_UPDATE_INTERVAL = 500;
|
||||||
const FALLBACK_EXPRESSION = 'joy';
|
const DEFAULT_FALLBACK_EXPRESSION = 'joy';
|
||||||
const DEFAULT_EXPRESSIONS = [
|
const DEFAULT_EXPRESSIONS = [
|
||||||
'talkinghead',
|
'talkinghead',
|
||||||
'admiration',
|
'admiration',
|
||||||
@@ -58,6 +58,14 @@ function isTalkingHeadEnabled() {
|
|||||||
return extension_settings.expressions.talkinghead && !extension_settings.expressions.local;
|
return extension_settings.expressions.talkinghead && !extension_settings.expressions.local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fallback expression if explicitly chosen, otherwise the default one
|
||||||
|
* @returns {string} expression name
|
||||||
|
*/
|
||||||
|
function getFallbackExpression() {
|
||||||
|
return extension_settings.expressions.fallback_expression ?? DEFAULT_FALLBACK_EXPRESSION;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles Talkinghead mode on/off.
|
* Toggles Talkinghead mode on/off.
|
||||||
*
|
*
|
||||||
@@ -157,7 +165,8 @@ async function visualNovelSetCharacterSprites(container, name, expression) {
|
|||||||
|
|
||||||
const sprites = spriteCache[spriteFolderName];
|
const sprites = spriteCache[spriteFolderName];
|
||||||
const expressionImage = container.find(`.expression-holder[data-avatar="${avatar}"]`);
|
const expressionImage = container.find(`.expression-holder[data-avatar="${avatar}"]`);
|
||||||
const defaultSpritePath = sprites.find(x => x.label === FALLBACK_EXPRESSION)?.path;
|
const defaultExpression = getFallbackExpression();
|
||||||
|
const defaultSpritePath = sprites.find(x => x.label === defaultExpression)?.path;
|
||||||
const noSprites = sprites.length === 0;
|
const noSprites = sprites.length === 0;
|
||||||
|
|
||||||
if (expressionImage.length > 0) {
|
if (expressionImage.length > 0) {
|
||||||
@@ -568,7 +577,7 @@ function handleImageChange() {
|
|||||||
// This preserves the same expression Talkinghead had at the moment it was switched off.
|
// This preserves the same expression Talkinghead had at the moment it was switched off.
|
||||||
const charName = getContext().name2;
|
const charName = getContext().name2;
|
||||||
const last = lastExpression[charName];
|
const last = lastExpression[charName];
|
||||||
const targetExpression = last ? last : FALLBACK_EXPRESSION;
|
const targetExpression = last ? last : getFallbackExpression();
|
||||||
setExpression(charName, targetExpression, true);
|
setExpression(charName, targetExpression, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -691,8 +700,8 @@ async function moduleWorker() {
|
|||||||
const force = !!context.groupId;
|
const force = !!context.groupId;
|
||||||
|
|
||||||
// Character won't be angry on you for swiping
|
// Character won't be angry on you for swiping
|
||||||
if (currentLastMessage.mes == '...' && expressionsList.includes(FALLBACK_EXPRESSION)) {
|
if (currentLastMessage.mes == '...' && expressionsList.includes(getFallbackExpression())) {
|
||||||
expression = FALLBACK_EXPRESSION;
|
expression = getFallbackExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendExpressionCall(spriteFolderName, expression, force, vnMode);
|
await sendExpressionCall(spriteFolderName, expression, force, vnMode);
|
||||||
@@ -885,6 +894,22 @@ async function setSpriteSetCommand(_, folder) {
|
|||||||
moduleWorker();
|
moduleWorker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function classifyCommand(_, text) {
|
||||||
|
if (!text) {
|
||||||
|
console.log('No text provided');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modules.includes('classify') && !extension_settings.expressions.local) {
|
||||||
|
toastr.warning('Text classification is disabled or not available');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = getExpressionLabel(text);
|
||||||
|
console.debug(`Classification result for "${text}": ${label}`);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
async function setSpriteSlashCommand(_, spriteId) {
|
async function setSpriteSlashCommand(_, spriteId) {
|
||||||
if (!spriteId) {
|
if (!spriteId) {
|
||||||
console.log('No sprite id provided');
|
console.log('No sprite id provided');
|
||||||
@@ -949,7 +974,7 @@ function sampleClassifyText(text) {
|
|||||||
async function getExpressionLabel(text) {
|
async function getExpressionLabel(text) {
|
||||||
// Return if text is undefined, saving a costly fetch request
|
// Return if text is undefined, saving a costly fetch request
|
||||||
if ((!modules.includes('classify') && !extension_settings.expressions.local) || !text) {
|
if ((!modules.includes('classify') && !extension_settings.expressions.local) || !text) {
|
||||||
return FALLBACK_EXPRESSION;
|
return getFallbackExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
text = sampleClassifyText(text);
|
text = sampleClassifyText(text);
|
||||||
@@ -988,7 +1013,7 @@ async function getExpressionLabel(text) {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return FALLBACK_EXPRESSION;
|
return getFallbackExpression();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,6 +1117,11 @@ async function getSpritesList(name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function renderAdditionalExpressionSettings() {
|
||||||
|
renderCustomExpressions();
|
||||||
|
await renderFallbackExpressionPicker();
|
||||||
|
}
|
||||||
|
|
||||||
function renderCustomExpressions() {
|
function renderCustomExpressions() {
|
||||||
if (!Array.isArray(extension_settings.expressions.custom)) {
|
if (!Array.isArray(extension_settings.expressions.custom)) {
|
||||||
extension_settings.expressions.custom = [];
|
extension_settings.expressions.custom = [];
|
||||||
@@ -1112,6 +1142,23 @@ function renderCustomExpressions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function renderFallbackExpressionPicker() {
|
||||||
|
const expressions = await getExpressionsList();
|
||||||
|
|
||||||
|
const defaultPicker = $('#expression_fallback');
|
||||||
|
defaultPicker.empty();
|
||||||
|
|
||||||
|
const fallbackExpression = getFallbackExpression();
|
||||||
|
|
||||||
|
for (const expression of expressions) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = expression;
|
||||||
|
option.text = expression;
|
||||||
|
option.selected = expression == fallbackExpression;
|
||||||
|
defaultPicker.append(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getExpressionsList() {
|
async function getExpressionsList() {
|
||||||
// Return cached list if available
|
// Return cached list if available
|
||||||
if (Array.isArray(expressionsList)) {
|
if (Array.isArray(expressionsList)) {
|
||||||
@@ -1349,7 +1396,7 @@ async function onClickExpressionAddCustom() {
|
|||||||
|
|
||||||
// Add custom expression into settings
|
// Add custom expression into settings
|
||||||
extension_settings.expressions.custom.push(expressionName);
|
extension_settings.expressions.custom.push(expressionName);
|
||||||
renderCustomExpressions();
|
await renderAdditionalExpressionSettings();
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
|
||||||
// Force refresh sprites list
|
// Force refresh sprites list
|
||||||
@@ -1376,7 +1423,11 @@ async function onClickExpressionRemoveCustom() {
|
|||||||
// Remove custom expression from settings
|
// Remove custom expression from settings
|
||||||
const index = extension_settings.expressions.custom.indexOf(selectedExpression);
|
const index = extension_settings.expressions.custom.indexOf(selectedExpression);
|
||||||
extension_settings.expressions.custom.splice(index, 1);
|
extension_settings.expressions.custom.splice(index, 1);
|
||||||
renderCustomExpressions();
|
if (selectedExpression == getFallbackExpression()) {
|
||||||
|
toastr.warning(`Deleted custom expression '${selectedExpression}' that was also selected as the fallback expression.\nFallback expression has been reset to '${DEFAULT_FALLBACK_EXPRESSION}'.`);
|
||||||
|
extension_settings.expressions.fallback_expression = DEFAULT_FALLBACK_EXPRESSION;
|
||||||
|
}
|
||||||
|
await renderAdditionalExpressionSettings();
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
|
||||||
// Force refresh sprites list
|
// Force refresh sprites list
|
||||||
@@ -1385,6 +1436,14 @@ async function onClickExpressionRemoveCustom() {
|
|||||||
moduleWorker();
|
moduleWorker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onExpressionFallbackChanged() {
|
||||||
|
const expression = this.value;
|
||||||
|
if (expression) {
|
||||||
|
extension_settings.expressions.fallback_expression = expression;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleFileUpload(url, formData) {
|
async function handleFileUpload(url, formData) {
|
||||||
try {
|
try {
|
||||||
const data = await jQuery.ajax({
|
const data = await jQuery.ajax({
|
||||||
@@ -1632,7 +1691,7 @@ async function fetchImagesNoCache() {
|
|||||||
return await Promise.allSettled(promises);
|
return await Promise.allSettled(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
(function () {
|
(async function () {
|
||||||
function addExpressionImage() {
|
function addExpressionImage() {
|
||||||
const html = `
|
const html = `
|
||||||
<div id="expression-wrapper">
|
<div id="expression-wrapper">
|
||||||
@@ -1652,7 +1711,7 @@ async function fetchImagesNoCache() {
|
|||||||
element.hide();
|
element.hide();
|
||||||
$('body').append(element);
|
$('body').append(element);
|
||||||
}
|
}
|
||||||
function addSettings() {
|
async function addSettings() {
|
||||||
$('#extensions_settings').append(renderExtensionTemplate(MODULE_NAME, 'settings'));
|
$('#extensions_settings').append(renderExtensionTemplate(MODULE_NAME, 'settings'));
|
||||||
$('#expression_override_button').on('click', onClickExpressionOverrideButton);
|
$('#expression_override_button').on('click', onClickExpressionOverrideButton);
|
||||||
$('#expressions_show_default').on('input', onExpressionsShowDefaultInput);
|
$('#expressions_show_default').on('input', onExpressionsShowDefaultInput);
|
||||||
@@ -1680,10 +1739,11 @@ async function fetchImagesNoCache() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
renderCustomExpressions();
|
await renderAdditionalExpressionSettings();
|
||||||
|
|
||||||
$('#expression_custom_add').on('click', onClickExpressionAddCustom);
|
$('#expression_custom_add').on('click', onClickExpressionAddCustom);
|
||||||
$('#expression_custom_remove').on('click', onClickExpressionRemoveCustom);
|
$('#expression_custom_remove').on('click', onClickExpressionRemoveCustom);
|
||||||
|
$('#expression_fallback').on('change', onExpressionFallbackChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause Talkinghead to save resources when the ST tab is not visible or the window is minimized.
|
// Pause Talkinghead to save resources when the ST tab is not visible or the window is minimized.
|
||||||
@@ -1716,7 +1776,7 @@ async function fetchImagesNoCache() {
|
|||||||
|
|
||||||
addExpressionImage();
|
addExpressionImage();
|
||||||
addVisualNovelMode();
|
addVisualNovelMode();
|
||||||
addSettings();
|
await addSettings();
|
||||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
||||||
const updateFunction = wrapper.update.bind(wrapper);
|
const updateFunction = wrapper.update.bind(wrapper);
|
||||||
setInterval(updateFunction, UPDATE_INTERVAL);
|
setInterval(updateFunction, UPDATE_INTERVAL);
|
||||||
@@ -1758,5 +1818,6 @@ async function fetchImagesNoCache() {
|
|||||||
registerSlashCommand('sprite', setSpriteSlashCommand, ['emote'], '<span class="monospace">(spriteId)</span> – force sets the sprite for the current character', true, true);
|
registerSlashCommand('sprite', setSpriteSlashCommand, ['emote'], '<span class="monospace">(spriteId)</span> – force sets the sprite for the current character', true, true);
|
||||||
registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '<span class="monospace">(optional folder)</span> – sets an override sprite folder for the current character. If the name starts with a slash or a backslash, selects a sub-folder in the character-named folder. Empty value to reset to default.', true, true);
|
registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '<span class="monospace">(optional folder)</span> – sets an override sprite folder for the current character. If the name starts with a slash or a backslash, selects a sub-folder in the character-named folder. Empty value to reset to default.', true, true);
|
||||||
registerSlashCommand('lastsprite', (_, value) => lastExpression[value.trim()] ?? '', [], '<span class="monospace">(charName)</span> – Returns the last set sprite / expression for the named character.', true, true);
|
registerSlashCommand('lastsprite', (_, value) => lastExpression[value.trim()] ?? '', [], '<span class="monospace">(charName)</span> – Returns the last set sprite / expression for the named character.', true, true);
|
||||||
registerSlashCommand('th', toggleTalkingHeadCommand, ['talkinghead'], '– Character Expressions: toggles <i>Image Type - talkinghead (extras)</i> on/off.');
|
registerSlashCommand('th', toggleTalkingHeadCommand, ['talkinghead'], '– Character Expressions: toggles <i>Image Type - talkinghead (extras)</i> on/off.', true, true);
|
||||||
|
registerSlashCommand('classify', classifyCommand, [], '<span class="monospace">(text)</span> – performs an emotion classification of the given text and returns a label.', true, true);
|
||||||
})();
|
})();
|
||||||
|
@@ -18,6 +18,11 @@
|
|||||||
<input id="image_type_toggle" type="checkbox">
|
<input id="image_type_toggle" type="checkbox">
|
||||||
<span>Image Type - talkinghead (extras)</span>
|
<span>Image Type - talkinghead (extras)</span>
|
||||||
</label>
|
</label>
|
||||||
|
<div class="expression_fallback_block m-b-1 m-t-1">
|
||||||
|
<label for="expression_fallback">Default / Fallback Expression</label>
|
||||||
|
<small>Set the default and fallback expression being used when no matching expression is found.</small>
|
||||||
|
<select id="expression_fallback" class="flex1 margin0" data-i18n="Fallback Expression" placeholder="Fallback Expression"></select>
|
||||||
|
</div>
|
||||||
<div class="expression_custom_block m-b-1 m-t-1">
|
<div class="expression_custom_block m-b-1 m-t-1">
|
||||||
<label for="expression_custom">Custom Expressions</label>
|
<label for="expression_custom">Custom Expressions</label>
|
||||||
<small>Can be set manually or with an <tt>/emote</tt> slash command.</small>
|
<small>Can be set manually or with an <tt>/emote</tt> slash command.</small>
|
||||||
|
@@ -2524,7 +2524,7 @@ async function generateComfyImage(prompt, negativePrompt) {
|
|||||||
}
|
}
|
||||||
let workflow = (await workflowResponse.json()).replace('"%prompt%"', JSON.stringify(prompt));
|
let workflow = (await workflowResponse.json()).replace('"%prompt%"', JSON.stringify(prompt));
|
||||||
workflow = workflow.replace('"%negative_prompt%"', JSON.stringify(negativePrompt));
|
workflow = workflow.replace('"%negative_prompt%"', JSON.stringify(negativePrompt));
|
||||||
workflow = workflow.replace('"%seed%"', JSON.stringify(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)));
|
workflow = workflow.replaceAll('"%seed%"', JSON.stringify(Math.round(Math.random() * Number.MAX_SAFE_INTEGER)));
|
||||||
placeholders.forEach(ph => {
|
placeholders.forEach(ph => {
|
||||||
workflow = workflow.replace(`"%${ph}%"`, JSON.stringify(extension_settings.sd[ph]));
|
workflow = workflow.replace(`"%${ph}%"`, JSON.stringify(extension_settings.sd[ph]));
|
||||||
});
|
});
|
||||||
|
@@ -465,6 +465,7 @@ async function processAudioJobQueue() {
|
|||||||
playAudioData(currentAudioJob);
|
playAudioData(currentAudioJob);
|
||||||
talkingAnimation(true);
|
talkingAnimation(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toastr.error(error.toString());
|
||||||
console.error(error);
|
console.error(error);
|
||||||
audioQueueProcessorReady = true;
|
audioQueueProcessorReady = true;
|
||||||
}
|
}
|
||||||
@@ -581,8 +582,9 @@ async function processTtsQueue() {
|
|||||||
toastr.error(`Specified voice for ${char} was not found. Check the TTS extension settings.`);
|
toastr.error(`Specified voice for ${char} was not found. Check the TTS extension settings.`);
|
||||||
throw `Unable to attain voiceId for ${char}`;
|
throw `Unable to attain voiceId for ${char}`;
|
||||||
}
|
}
|
||||||
tts(text, voiceId, char);
|
await tts(text, voiceId, char);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
toastr.error(error.toString());
|
||||||
console.error(error);
|
console.error(error);
|
||||||
currentTtsJob = null;
|
currentTtsJob = null;
|
||||||
}
|
}
|
||||||
@@ -654,6 +656,7 @@ function onRefreshClick() {
|
|||||||
initVoiceMap();
|
initVoiceMap();
|
||||||
updateVoiceMap();
|
updateVoiceMap();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
toastr.error(error.toString());
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setTtsStatus(error, false);
|
setTtsStatus(error, false);
|
||||||
});
|
});
|
||||||
|
@@ -378,10 +378,10 @@ export function getGroupCharacterCards(groupId, characterId) {
|
|||||||
mesExamplesArray.push(baseChatReplace(character.mes_example.trim(), name1, character.name));
|
mesExamplesArray.push(baseChatReplace(character.mes_example.trim(), name1, character.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
const description = descriptions.join('\n');
|
const description = descriptions.filter(x => x.length).join('\n');
|
||||||
const personality = personalities.join('\n');
|
const personality = personalities.filter(x => x.length).join('\n');
|
||||||
const scenario = scenarioOverride?.trim() || scenarios.join('\n');
|
const scenario = scenarioOverride?.trim() || scenarios.filter(x => x.length).join('\n');
|
||||||
const mesExamples = mesExamplesArray.join('\n');
|
const mesExamples = mesExamplesArray.filter(x => x.length).join('\n');
|
||||||
|
|
||||||
return { description, personality, scenario, mesExamples };
|
return { description, personality, scenario, mesExamples };
|
||||||
}
|
}
|
||||||
|
@@ -419,10 +419,13 @@ export function formatInstructModeExamples(mesExamplesArray, name1, name2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const example of blockExamples) {
|
for (const example of blockExamples) {
|
||||||
|
// If force group/persona names is set, we should override the include names for the user placeholder
|
||||||
|
const includeThisName = includeNames || (power_user.instruct.names_force_groups && example.name == 'example_user');
|
||||||
|
|
||||||
const prefix = example.name == 'example_user' ? inputPrefix : outputPrefix;
|
const prefix = example.name == 'example_user' ? inputPrefix : outputPrefix;
|
||||||
const suffix = example.name == 'example_user' ? inputSuffix : outputSuffix;
|
const suffix = example.name == 'example_user' ? inputSuffix : outputSuffix;
|
||||||
const name = example.name == 'example_user' ? name1 : name2;
|
const name = example.name == 'example_user' ? name1 : name2;
|
||||||
const messageContent = includeNames ? `${name}: ${example.content}` : example.content;
|
const messageContent = includeThisName ? `${name}: ${example.content}` : example.content;
|
||||||
const formattedMessage = [prefix, messageContent + suffix].filter(x => x).join(separator);
|
const formattedMessage = [prefix, messageContent + suffix].filter(x => x).join(separator);
|
||||||
formattedExamples.push(formattedMessage);
|
formattedExamples.push(formattedMessage);
|
||||||
}
|
}
|
||||||
|
@@ -7,122 +7,103 @@ import { replaceVariableMacros } from './variables.js';
|
|||||||
// Register any macro that you want to leave in the compiled story string
|
// Register any macro that you want to leave in the compiled story string
|
||||||
Handlebars.registerHelper('trim', () => '{{trim}}');
|
Handlebars.registerHelper('trim', () => '{{trim}}');
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the ID of the last message in the chat.
|
|
||||||
* @returns {string} The ID of the last message in the chat.
|
|
||||||
*/
|
|
||||||
function getLastMessageId() {
|
|
||||||
const index = chat?.length - 1;
|
|
||||||
|
|
||||||
if (!isNaN(index) && index >= 0) {
|
/**
|
||||||
return String(index);
|
* Returns the ID of the last message in the chat
|
||||||
|
*
|
||||||
|
* Optionally can only choose specific messages, if a filter is provided.
|
||||||
|
*
|
||||||
|
* @param {object} param0 - Optional arguments
|
||||||
|
* @param {boolean} [param0.exclude_swipe_in_propress=true] - Whether a message that is currently being swiped should be ignored
|
||||||
|
* @param {function(object):boolean} [param0.filter] - A filter applied to the search, ignoring all messages that don't match the criteria. For example to only find user messages, etc.
|
||||||
|
* @returns {number|null} The message id, or null if none was found
|
||||||
|
*/
|
||||||
|
export function getLastMessageId({ exclude_swipe_in_propress = true, filter = null } = {}) {
|
||||||
|
for (let i = chat?.length - 1; i >= 0; i--) {
|
||||||
|
let message = chat[i];
|
||||||
|
|
||||||
|
// If ignoring swipes and the message is being swiped, continue
|
||||||
|
// We can check if a message is being swiped by checking whether the current swipe id is not in the list of finished swipes yet
|
||||||
|
if (exclude_swipe_in_propress && message.swipes && message.swipe_id >= message.swipes.length) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
// Check if no filter is provided, or if the message passes the filter
|
||||||
|
if (!filter || filter(message)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the first message included in the context.
|
* Returns the ID of the first message included in the context
|
||||||
* @returns {string} The ID of the first message in the context.
|
*
|
||||||
|
* @returns {number|null} The ID of the first message in the context
|
||||||
*/
|
*/
|
||||||
function getFirstIncludedMessageId() {
|
function getFirstIncludedMessageId() {
|
||||||
const index = document.querySelector('.lastInContext')?.getAttribute('mesid');
|
const index = Number(document.querySelector('.lastInContext')?.getAttribute('mesid'));
|
||||||
|
|
||||||
if (!isNaN(index) && index >= 0) {
|
if (!isNaN(index) && index >= 0) {
|
||||||
return String(index);
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last message in the chat.
|
* Returns the last message in the chat
|
||||||
* @returns {string} The last message in the chat.
|
*
|
||||||
|
* @returns {string} The last message in the chat
|
||||||
*/
|
*/
|
||||||
function getLastMessage() {
|
function getLastMessage() {
|
||||||
const index = chat?.length - 1;
|
const mid = getLastMessageId();
|
||||||
|
return chat[mid]?.mes ?? '';
|
||||||
if (!isNaN(index) && index >= 0) {
|
|
||||||
return chat[index].mes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last message from the user.
|
* Returns the last message from the user
|
||||||
* @returns {string} The last message from the user.
|
*
|
||||||
|
* @returns {string} The last message from the user
|
||||||
*/
|
*/
|
||||||
function getLastUserMessage() {
|
function getLastUserMessage() {
|
||||||
if (!Array.isArray(chat) || chat.length === 0) {
|
const mid = getLastMessageId({ filter: m => m.is_user && !m.is_system });
|
||||||
return '';
|
return chat[mid]?.mes ?? '';
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = chat.length - 1; i >= 0; i--) {
|
|
||||||
if (chat[i].is_user && !chat[i].is_system) {
|
|
||||||
return chat[i].mes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last message from the bot.
|
* Returns the last message from the bot
|
||||||
* @returns {string} The last message from the bot.
|
*
|
||||||
|
* @returns {string} The last message from the bot
|
||||||
*/
|
*/
|
||||||
function getLastCharMessage() {
|
function getLastCharMessage() {
|
||||||
if (!Array.isArray(chat) || chat.length === 0) {
|
const mid = getLastMessageId({ filter: m => !m.is_user && !m.is_system });
|
||||||
return '';
|
return chat[mid]?.mes ?? '';
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = chat.length - 1; i >= 0; i--) {
|
|
||||||
if (!chat[i].is_user && !chat[i].is_system) {
|
|
||||||
return chat[i].mes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the last swipe.
|
* Returns the 1-based ID (number) of the last swipe
|
||||||
* @returns {string} The 1-based ID of the last swipe
|
*
|
||||||
|
* @returns {number|null} The 1-based ID of the last swipe
|
||||||
*/
|
*/
|
||||||
function getLastSwipeId() {
|
function getLastSwipeId() {
|
||||||
const index = chat?.length - 1;
|
// For swipe macro, we are accepting using the message that is currently being swiped
|
||||||
|
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
|
||||||
if (!isNaN(index) && index >= 0) {
|
const swipes = chat[mid]?.swipes;
|
||||||
const swipes = chat[index].swipes;
|
return swipes?.length;
|
||||||
|
|
||||||
if (!Array.isArray(swipes) || swipes.length === 0) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(swipes.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the current swipe.
|
* Returns the 1-based ID (number) of the current swipe
|
||||||
* @returns {string} The 1-based ID of the current swipe.
|
*
|
||||||
|
* @returns {number|null} The 1-based ID of the current swipe
|
||||||
*/
|
*/
|
||||||
function getCurrentSwipeId() {
|
function getCurrentSwipeId() {
|
||||||
const index = chat?.length - 1;
|
// For swipe macro, we are accepting using the message that is currently being swiped
|
||||||
|
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
|
||||||
if (!isNaN(index) && index >= 0) {
|
const swipeId = chat[mid]?.swipe_id;
|
||||||
const swipeId = chat[index].swipe_id;
|
return swipeId ? swipeId + 1 : null;
|
||||||
|
|
||||||
if (swipeId === undefined || isNaN(swipeId)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(swipeId + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -292,12 +273,12 @@ export function evaluateMacros(content, env) {
|
|||||||
|
|
||||||
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
|
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
|
||||||
content = content.replace(/{{lastMessage}}/gi, () => getLastMessage());
|
content = content.replace(/{{lastMessage}}/gi, () => getLastMessage());
|
||||||
content = content.replace(/{{lastMessageId}}/gi, () => getLastMessageId());
|
content = content.replace(/{{lastMessageId}}/gi, () => String(getLastMessageId() ?? ''));
|
||||||
content = content.replace(/{{lastUserMessage}}/gi, () => getLastUserMessage());
|
content = content.replace(/{{lastUserMessage}}/gi, () => getLastUserMessage());
|
||||||
content = content.replace(/{{lastCharMessage}}/gi, () => getLastCharMessage());
|
content = content.replace(/{{lastCharMessage}}/gi, () => getLastCharMessage());
|
||||||
content = content.replace(/{{firstIncludedMessageId}}/gi, () => getFirstIncludedMessageId());
|
content = content.replace(/{{firstIncludedMessageId}}/gi, () => String(getFirstIncludedMessageId() ?? ''));
|
||||||
content = content.replace(/{{lastSwipeId}}/gi, () => getLastSwipeId());
|
content = content.replace(/{{lastSwipeId}}/gi, () => String(getLastSwipeId() ?? ''));
|
||||||
content = content.replace(/{{currentSwipeId}}/gi, () => getCurrentSwipeId());
|
content = content.replace(/{{currentSwipeId}}/gi, () => String(getCurrentSwipeId() ?? ''));
|
||||||
|
|
||||||
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');
|
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');
|
||||||
|
|
||||||
|
@@ -118,6 +118,7 @@ const TAG_FOLDER_DEFAULT_TYPE = 'NONE';
|
|||||||
* @property {function} [action] - An optional function that gets executed when this tag is an actionable tag and is clicked on.
|
* @property {function} [action] - An optional function that gets executed when this tag is an actionable tag and is clicked on.
|
||||||
* @property {string} [class] - An optional css class added to the control representing this tag when printed. Used for custom tags in the filters.
|
* @property {string} [class] - An optional css class added to the control representing this tag when printed. Used for custom tags in the filters.
|
||||||
* @property {string} [icon] - An optional css class of an icon representing this tag when printed. This will replace the tag name with the icon. Used for custom tags in the filters.
|
* @property {string} [icon] - An optional css class of an icon representing this tag when printed. This will replace the tag name with the icon. Used for custom tags in the filters.
|
||||||
|
* @property {string} [title] - An optional title for the tooltip of this tag. If there is no tooltip specified, and "icon" is chosen, the tooltip will be the "name" property.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,10 +129,17 @@ let tags = [];
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A map representing the key of an entity (character avatar, group id, etc) with a corresponding array of tags this entity has assigned. The array might not exist if no tags were assigned yet.
|
* A map representing the key of an entity (character avatar, group id, etc) with a corresponding array of tags this entity has assigned. The array might not exist if no tags were assigned yet.
|
||||||
* @type {Object.<string, string[]?>}
|
* @type {{[identifier: string]: string[]?}}
|
||||||
*/
|
*/
|
||||||
let tag_map = {};
|
let tag_map = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache of all cut-off tag lists that got expanded until the last reload. They will be printed expanded again.
|
||||||
|
* It contains the key of the entity.
|
||||||
|
* @type {string[]} ids
|
||||||
|
*/
|
||||||
|
let expanded_tags_cache = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the basic filter for the current state of the tags and their selection on an entity list.
|
* Applies the basic filter for the current state of the tags and their selection on an entity list.
|
||||||
* @param {Array<Object>} entities List of entities for display, consisting of tags, characters and groups.
|
* @param {Array<Object>} entities List of entities for display, consisting of tags, characters and groups.
|
||||||
@@ -388,7 +396,7 @@ function getTagKey() {
|
|||||||
* Robust method to find a valid tag key for any entity.
|
* Robust method to find a valid tag key for any entity.
|
||||||
*
|
*
|
||||||
* @param {object|number|string} entityOrKey An entity with id property (character, group, tag), or directly an id or tag key.
|
* @param {object|number|string} entityOrKey An entity with id property (character, group, tag), or directly an id or tag key.
|
||||||
* @returns {string} The tag key that can be found.
|
* @returns {string|undefined} The tag key that can be found.
|
||||||
*/
|
*/
|
||||||
export function getTagKeyForEntity(entityOrKey) {
|
export function getTagKeyForEntity(entityOrKey) {
|
||||||
let x = entityOrKey;
|
let x = entityOrKey;
|
||||||
@@ -419,6 +427,33 @@ export function getTagKeyForEntity(entityOrKey) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for a tag key based on an entity for a given element.
|
||||||
|
* It checks the given element and upwards parents for a set character id (chid) or group id (grid), and if there is any, returns its unique entity key.
|
||||||
|
*
|
||||||
|
* @param {JQuery<HTMLElement>|string} element - The element to search the entity id on
|
||||||
|
* @returns {string|undefined} The tag key that can be found.
|
||||||
|
*/
|
||||||
|
export function getTagKeyForEntityElement(element) {
|
||||||
|
if (typeof element === 'string') {
|
||||||
|
element = $(element);
|
||||||
|
}
|
||||||
|
// Start with the given element and traverse up the DOM tree
|
||||||
|
while (element.length && element.parent().length) {
|
||||||
|
const grid = element.attr('grid');
|
||||||
|
const chid = element.attr('chid');
|
||||||
|
if (grid || chid) {
|
||||||
|
const id = grid || chid;
|
||||||
|
return getTagKeyForEntity(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move up to the parent element
|
||||||
|
element = element.parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function addTagToMap(tagId, characterId = null) {
|
function addTagToMap(tagId, characterId = null) {
|
||||||
const key = characterId !== null && characterId !== undefined ? getTagKeyForEntity(characterId) : getTagKey();
|
const key = characterId !== null && characterId !== undefined ? getTagKeyForEntity(characterId) : getTagKey();
|
||||||
|
|
||||||
@@ -617,15 +652,16 @@ function createNewTag(tagName) {
|
|||||||
/**
|
/**
|
||||||
* Prints the list of tags
|
* Prints the list of tags
|
||||||
*
|
*
|
||||||
* @param {JQuery<HTMLElement>} element - The container element where the tags are to be printed.
|
* @param {JQuery<HTMLElement>|string} element - The container element where the tags are to be printed. (Optionally can also be a string selector for the element, which will then be resolved)
|
||||||
* @param {PrintTagListOptions} [options] - Optional parameters for printing the tag list.
|
* @param {PrintTagListOptions} [options] - Optional parameters for printing the tag list.
|
||||||
*/
|
*/
|
||||||
function printTagList(element, { tags = undefined, addTag = undefined, forEntityOrKey = undefined, empty = true, tagActionSelector = undefined, tagOptions = {} } = {}) {
|
function printTagList(element, { tags = undefined, addTag = undefined, forEntityOrKey = undefined, empty = true, tagActionSelector = undefined, tagOptions = {} } = {}) {
|
||||||
|
const $element = (typeof element === 'string') ? $(element) : element;
|
||||||
const key = forEntityOrKey !== undefined ? getTagKeyForEntity(forEntityOrKey) : getTagKey();
|
const key = forEntityOrKey !== undefined ? getTagKeyForEntity(forEntityOrKey) : getTagKey();
|
||||||
let printableTags = tags ? (typeof tags === 'function' ? tags() : tags) : getTagsList(key);
|
let printableTags = tags ? (typeof tags === 'function' ? tags() : tags) : getTagsList(key);
|
||||||
|
|
||||||
if (empty === 'always' || (empty && (printableTags?.length > 0 || key))) {
|
if (empty === 'always' || (empty && (printableTags?.length > 0 || key))) {
|
||||||
$(element).empty();
|
$element.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addTag && (tagOptions.skipExistsCheck || !printableTags.some(x => x.id === addTag.id))) {
|
if (addTag && (tagOptions.skipExistsCheck || !printableTags.some(x => x.id === addTag.id))) {
|
||||||
@@ -637,6 +673,16 @@ function printTagList(element, { tags = undefined, addTag = undefined, forEntity
|
|||||||
|
|
||||||
const customAction = typeof tagActionSelector === 'function' ? tagActionSelector : null;
|
const customAction = typeof tagActionSelector === 'function' ? tagActionSelector : null;
|
||||||
|
|
||||||
|
// Well, lets check if the tag list was expanded. Based on either a css class, or when any expand was clicked yet, then we search whether this element id matches
|
||||||
|
const expanded = $element.hasClass('tags-expanded') || (expanded_tags_cache.length && expanded_tags_cache.indexOf(key ?? getTagKeyForEntityElement(element)) >= 0);
|
||||||
|
|
||||||
|
// We prepare some stuff. No matter which list we have, there is a maximum value of tags we are going to display
|
||||||
|
const TAGS_LIMIT = 50;
|
||||||
|
const MAX_TAGS = !expanded ? TAGS_LIMIT : Number.MAX_SAFE_INTEGER;
|
||||||
|
let totalPrinted = 0;
|
||||||
|
let hiddenTags = 0;
|
||||||
|
const filterActive = (/** @type {Tag} */ tag) => tag.filter_state && !isFilterState(tag.filter_state, FILTER_STATES.UNDEFINED);
|
||||||
|
|
||||||
for (const tag of printableTags) {
|
for (const tag of printableTags) {
|
||||||
// If we have a custom action selector, we override that tag options for each tag
|
// If we have a custom action selector, we override that tag options for each tag
|
||||||
if (customAction) {
|
if (customAction) {
|
||||||
@@ -648,7 +694,40 @@ function printTagList(element, { tags = undefined, addTag = undefined, forEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appendTagToList(element, tag, tagOptions);
|
// Check if we should print this tag
|
||||||
|
if (totalPrinted++ < MAX_TAGS || filterActive(tag)) {
|
||||||
|
appendTagToList($element, tag, tagOptions);
|
||||||
|
} else {
|
||||||
|
hiddenTags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After the loop, check if we need to add the placeholder.
|
||||||
|
// The placehold if clicked expands the tags and remembers either via class or cache array which was expanded, so it'll stay expanded until the next reload.
|
||||||
|
if (hiddenTags > 0) {
|
||||||
|
const id = 'placeholder_' + uuidv4();
|
||||||
|
|
||||||
|
// Add click event
|
||||||
|
const showHiddenTags = (_, event) => {
|
||||||
|
const elementKey = key ?? getTagKeyForEntityElement($element);
|
||||||
|
console.log(`Hidden tags shown for element ${elementKey}`);
|
||||||
|
|
||||||
|
// Mark the current char/group as expanded if we were in any. This will be kept in memory until reload
|
||||||
|
$element.addClass('tags-expanded');
|
||||||
|
expanded_tags_cache.push(elementKey);
|
||||||
|
|
||||||
|
// Do not bubble further, we are just expanding
|
||||||
|
event.stopPropagation();
|
||||||
|
printTagList($element, { tags: tags, addTag: addTag, forEntityOrKey: forEntityOrKey, empty: empty, tagActionSelector: tagActionSelector, tagOptions: tagOptions });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Print the placeholder object with its styling and action to show the remaining tags
|
||||||
|
/** @type {Tag} */
|
||||||
|
const placeholderTag = { id: id, name: '...', title: `${hiddenTags} tags not displayed.\n\nClick to expand remaining tags.`, color: 'transparent', action: showHiddenTags, class: 'placeholder-expander' };
|
||||||
|
// It should never be marked as a removable tag, because it's just an expander action
|
||||||
|
/** @type {TagOptions} */
|
||||||
|
const placeholderTagOptions = { ...tagOptions, removable: false };
|
||||||
|
appendTagToList($element, placeholderTag, placeholderTagOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,13 +761,19 @@ function appendTagToList(listElement, tag, { removable = false, selectable = fal
|
|||||||
if (tag.class) {
|
if (tag.class) {
|
||||||
tagElement.addClass(tag.class);
|
tagElement.addClass(tag.class);
|
||||||
}
|
}
|
||||||
|
if (tag.title) {
|
||||||
|
tagElement.attr('title', tag.title);
|
||||||
|
}
|
||||||
if (tag.icon) {
|
if (tag.icon) {
|
||||||
tagElement.find('.tag_name').text('').attr('title', tag.name).addClass(tag.icon);
|
tagElement.find('.tag_name').text('').attr('title', `${tag.name} ${tag.title || ''}`.trim()).addClass(tag.icon);
|
||||||
|
tagElement.addClass('actionable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We could have multiple ways of actions passed in. The manual arguments have precendence in front of a specified tag action
|
||||||
|
const clickableAction = action ?? tag.action;
|
||||||
|
|
||||||
// If this is a tag for a general list and its either selectable or actionable, lets mark its current state
|
// If this is a tag for a general list and its either selectable or actionable, lets mark its current state
|
||||||
if ((selectable || action) && isGeneralList) {
|
if ((selectable || clickableAction) && isGeneralList) {
|
||||||
toggleTagThreeState(tagElement, { stateOverride: tag.filter_state ?? DEFAULT_FILTER_STATE });
|
toggleTagThreeState(tagElement, { stateOverride: tag.filter_state ?? DEFAULT_FILTER_STATE });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,14 +781,11 @@ function appendTagToList(listElement, tag, { removable = false, selectable = fal
|
|||||||
tagElement.on('click', () => onTagFilterClick.bind(tagElement)(listElement));
|
tagElement.on('click', () => onTagFilterClick.bind(tagElement)(listElement));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action) {
|
if (clickableAction) {
|
||||||
const filter = getFilterHelper($(listElement));
|
const filter = getFilterHelper($(listElement));
|
||||||
tagElement.on('click', () => action.bind(tagElement)(filter));
|
tagElement.on('click', (e) => clickableAction.bind(tagElement)(filter, e));
|
||||||
tagElement.addClass('actionable');
|
tagElement.addClass('clickable-action');
|
||||||
}
|
}
|
||||||
/*if (action && tag.id === 2) {
|
|
||||||
tagElement.addClass('innerActionable hidden');
|
|
||||||
}*/
|
|
||||||
|
|
||||||
$(listElement).append(tagElement);
|
$(listElement).append(tagElement);
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ const { readAllChunks, extractFileFromZipBuffer, forwardFetchResponse } = requir
|
|||||||
const { jsonParser } = require('../express-common');
|
const { jsonParser } = require('../express-common');
|
||||||
|
|
||||||
const API_NOVELAI = 'https://api.novelai.net';
|
const API_NOVELAI = 'https://api.novelai.net';
|
||||||
|
const IMAGE_NOVELAI = 'https://image.novelai.net';
|
||||||
|
|
||||||
// Ban bracket generation, plus defaults
|
// Ban bracket generation, plus defaults
|
||||||
const badWordsList = [
|
const badWordsList = [
|
||||||
@@ -238,7 +239,7 @@ router.post('/generate-image', jsonParser, async (request, response) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('NAI Diffusion request:', request.body);
|
console.log('NAI Diffusion request:', request.body);
|
||||||
const generateUrl = `${API_NOVELAI}/ai/generate-image`;
|
const generateUrl = `${IMAGE_NOVELAI}/ai/generate-image`;
|
||||||
const generateResult = await fetch(generateUrl, {
|
const generateResult = await fetch(generateUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
Reference in New Issue
Block a user