mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into parser-enum-stuff
This commit is contained in:
60
.github/readme.md
vendored
60
.github/readme.md
vendored
@ -144,12 +144,14 @@ A full list of included extensions and tutorials on how to use them can be found
|
|||||||
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 SillyTavern Launcher
|
## Installing via SillyTavern Launcher
|
||||||
1. Install [Git for Windows](https://gitforwindows.org/)
|
1. On your keyboard: press **`WINDOWS + R`** to open Run dialog box. Then, run the following command to install git:
|
||||||
2. Open Windows Explorer (`Win+E`) and make or choose a folder where you wanna install the launcher to
|
```shell
|
||||||
3. Open a Command Prompt inside that folder by clicking in the 'Address Bar' at the top, typing `cmd`, and pressing Enter.
|
cmd /c winget install -e --id Git.Git
|
||||||
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
|
2. On your keyboard: press **`WINDOWS + E`** to open File Explorer, then navigate to the folder where you want to install the launcher. Once in the desired folder, type `cmd` into the address bar and press enter. Then, run the following command:
|
||||||
6. After installation double-click on `launcher.bat`
|
```shell
|
||||||
|
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher && start installer.bat
|
||||||
|
```
|
||||||
|
|
||||||
## Installing via GitHub Desktop
|
## 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/))
|
(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/))
|
||||||
@ -183,18 +185,40 @@ For MacOS / Linux all of these will be done in a Terminal.
|
|||||||
|
|
||||||
### For Linux users
|
### For Linux users
|
||||||
1. Open your favorite terminal and install git
|
1. Open your favorite terminal and install git
|
||||||
2. Download Sillytavern Launcher with: `git clone https://github.com/SillyTavern/SillyTavern-Launcher.git`
|
2. Git clone the Sillytavern-Launcher with:
|
||||||
3. Navigate to the SillyTavern-Launcher with: `cd SillyTavern-Launcher`
|
```shell
|
||||||
4. Start the install launcher with: `chmod +x install.sh && ./install.sh` and choose what you wanna install
|
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||||
5. After installation start the launcher with: `chmod +x launcher.sh && ./launcher.sh`
|
```
|
||||||
|
3. Start the installer.sh with:
|
||||||
|
```shell
|
||||||
|
chmod +x install.sh && ./install.sh
|
||||||
|
```
|
||||||
|
4. After installation start the launcher.sh with:
|
||||||
|
```shell
|
||||||
|
chmod +x launcher.sh && ./launcher.sh
|
||||||
|
```
|
||||||
|
|
||||||
### For Mac users
|
### 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)"`
|
1. Open a terminal and install brew with:
|
||||||
2. Then install git with: `brew install git`
|
```shell
|
||||||
3. Download Sillytavern Launcher with: `git clone https://github.com/SillyTavern/SillyTavern-Launcher.git`
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
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
|
2. Install git with:
|
||||||
6. After installation start the launcher with: `chmod +x launcher.sh && ./launcher.sh`
|
```shell
|
||||||
|
brew install git
|
||||||
|
```
|
||||||
|
3. Git clone the Sillytavern-Launcher with:
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/SillyTavern/SillyTavern-Launcher.git && cd SillyTavern-Launcher
|
||||||
|
```
|
||||||
|
4. Start the installer.sh with:
|
||||||
|
```shell
|
||||||
|
chmod +x install.sh && ./install.sh
|
||||||
|
```
|
||||||
|
5. After installation start the launcher.sh with:
|
||||||
|
```shell
|
||||||
|
chmod +x launcher.sh && ./launcher.sh
|
||||||
|
```
|
||||||
|
|
||||||
## 🐋 Installing via Docker
|
## 🐋 Installing via Docker
|
||||||
|
|
||||||
@ -244,7 +268,7 @@ You will need two mandatory directory mappings and a port mapping to allow Silly
|
|||||||
|
|
||||||
## API keys management
|
## API keys management
|
||||||
|
|
||||||
SillyTavern saves your API keys to a `secrets.json` file in the server directory.
|
SillyTavern saves your API keys to a `secrets.json` file in the user data directory (`/data/default-user/secrets.json` is the default path).
|
||||||
|
|
||||||
By default, they will not be exposed to a frontend after you enter them and reload the page.
|
By default, they will not be exposed to a frontend after you enter them and reload the page.
|
||||||
|
|
||||||
@ -259,7 +283,7 @@ Most often this is for people who want to use SillyTavern on their mobile phones
|
|||||||
|
|
||||||
However, it can be used to allow remote connections from anywhere as well.
|
However, it can be used to allow remote connections from anywhere as well.
|
||||||
|
|
||||||
**IMPORTANT: SillyTavern is a single-user program, so anyone who logs in will be able to see all characters and chats, and be able to change any settings inside the UI.**
|
**IMPORTANT: Refer to the official guide if you want to configure SillyTavern user accounts with (optional) password protection: [Users](https://docs.sillytavern.app/installation/st-1.12.0-migration-guide/#users).**
|
||||||
|
|
||||||
### 1. Managing whitelisted IPs
|
### 1. Managing whitelisted IPs
|
||||||
|
|
||||||
|
7
package-lock.json
generated
7
package-lock.json
generated
@ -48,7 +48,7 @@
|
|||||||
"vectra": "^0.2.2",
|
"vectra": "^0.2.2",
|
||||||
"wavefile": "^11.0.0",
|
"wavefile": "^11.0.0",
|
||||||
"write-file-atomic": "^5.0.1",
|
"write-file-atomic": "^5.0.1",
|
||||||
"ws": "^8.13.0",
|
"ws": "^8.17.1",
|
||||||
"yaml": "^2.3.4",
|
"yaml": "^2.3.4",
|
||||||
"yargs": "^17.7.1",
|
"yargs": "^17.7.1",
|
||||||
"yauzl": "^2.10.0"
|
"yauzl": "^2.10.0"
|
||||||
@ -4659,8 +4659,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.13.0",
|
"version": "8.17.1",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
"vectra": "^0.2.2",
|
"vectra": "^0.2.2",
|
||||||
"wavefile": "^11.0.0",
|
"wavefile": "^11.0.0",
|
||||||
"write-file-atomic": "^5.0.1",
|
"write-file-atomic": "^5.0.1",
|
||||||
"ws": "^8.13.0",
|
"ws": "^8.17.1",
|
||||||
"yaml": "^2.3.4",
|
"yaml": "^2.3.4",
|
||||||
"yargs": "^17.7.1",
|
"yargs": "^17.7.1",
|
||||||
"yauzl": "^2.10.0"
|
"yauzl": "^2.10.0"
|
||||||
|
@ -625,7 +625,7 @@ export class QuickReply {
|
|||||||
this.editorExecuteErrors.innerHTML = '';
|
this.editorExecuteErrors.innerHTML = '';
|
||||||
this.editorExecuteResult.innerHTML = '';
|
this.editorExecuteResult.innerHTML = '';
|
||||||
if (this.editorExecuteHide.checked) {
|
if (this.editorExecuteHide.checked) {
|
||||||
this.editorPopup.dom.classList.add('qr--hide');
|
this.editorPopup.dlg.classList.add('qr--hide');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// this.editorExecutePromise = this.execute({}, true);
|
// this.editorExecutePromise = this.execute({}, true);
|
||||||
@ -694,7 +694,7 @@ export class QuickReply {
|
|||||||
}
|
}
|
||||||
this.editorExecutePromise = null;
|
this.editorExecutePromise = null;
|
||||||
this.editorExecuteBtn.classList.remove('qr--busy');
|
this.editorExecuteBtn.classList.remove('qr--busy');
|
||||||
this.editorPopup.dom.classList.remove('qr--hide');
|
this.editorPopup.dlg.classList.remove('qr--hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEditorProgress(done, total) {
|
updateEditorProgress(done, total) {
|
||||||
|
@ -507,3 +507,6 @@
|
|||||||
.popup.qr--hide {
|
.popup.qr--hide {
|
||||||
opacity: 0 !important;
|
opacity: 0 !important;
|
||||||
}
|
}
|
||||||
|
.popup.qr--hide::backdrop {
|
||||||
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
|
@ -529,4 +529,7 @@
|
|||||||
|
|
||||||
.popup.qr--hide {
|
.popup.qr--hide {
|
||||||
opacity: 0 !important;
|
opacity: 0 !important;
|
||||||
|
&::backdrop {
|
||||||
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ import { SlashCommand } from './slash-commands/SlashCommand.js';
|
|||||||
import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js';
|
import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js';
|
||||||
import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js';
|
import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js';
|
||||||
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||||
import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js';
|
import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js';
|
||||||
export {
|
export {
|
||||||
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
||||||
@ -1450,6 +1451,7 @@ async function trimTokensCallback(arg, value) {
|
|||||||
|
|
||||||
async function buttonsCallback(args, text) {
|
async function buttonsCallback(args, text) {
|
||||||
try {
|
try {
|
||||||
|
/** @type {string[]} */
|
||||||
const buttons = JSON.parse(resolveVariable(args?.labels));
|
const buttons = JSON.parse(resolveVariable(args?.labels));
|
||||||
|
|
||||||
if (!Array.isArray(buttons) || !buttons.length) {
|
if (!Array.isArray(buttons) || !buttons.length) {
|
||||||
@ -1457,18 +1459,24 @@ async function buttonsCallback(args, text) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map custom buttons to results. Start at 2 because 1 and 0 are reserved for ok and cancel
|
||||||
|
const resultToButtonMap = new Map(buttons.map((button, index) => [index + 2, button]));
|
||||||
|
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const safeValue = DOMPurify.sanitize(text || '');
|
const safeValue = DOMPurify.sanitize(text || '');
|
||||||
|
|
||||||
|
/** @type {Popup} */
|
||||||
|
let popup;
|
||||||
|
|
||||||
const buttonContainer = document.createElement('div');
|
const buttonContainer = document.createElement('div');
|
||||||
buttonContainer.classList.add('flex-container', 'flexFlowColumn', 'wide100p', 'm-t-1');
|
buttonContainer.classList.add('flex-container', 'flexFlowColumn', 'wide100p', 'm-t-1');
|
||||||
|
|
||||||
for (const button of buttons) {
|
for (const [result, button] of resultToButtonMap) {
|
||||||
const buttonElement = document.createElement('div');
|
const buttonElement = document.createElement('div');
|
||||||
buttonElement.classList.add('menu_button', 'wide100p');
|
buttonElement.classList.add('menu_button', 'result-control', 'wide100p');
|
||||||
|
buttonElement.dataset.result = String(result);
|
||||||
buttonElement.addEventListener('click', () => {
|
buttonElement.addEventListener('click', () => {
|
||||||
resolve(button);
|
popup?.complete(result);
|
||||||
$('#dialogue_popup_ok').trigger('click');
|
|
||||||
});
|
});
|
||||||
buttonElement.innerText = button;
|
buttonElement.innerText = button;
|
||||||
buttonContainer.appendChild(buttonElement);
|
buttonContainer.appendChild(buttonElement);
|
||||||
@ -1477,8 +1485,10 @@ async function buttonsCallback(args, text) {
|
|||||||
const popupContainer = document.createElement('div');
|
const popupContainer = document.createElement('div');
|
||||||
popupContainer.innerHTML = safeValue;
|
popupContainer.innerHTML = safeValue;
|
||||||
popupContainer.appendChild(buttonContainer);
|
popupContainer.appendChild(buttonContainer);
|
||||||
callPopup(popupContainer, 'text', '', { okButton: 'Cancel' })
|
|
||||||
.then(() => resolve(''))
|
popup = new Popup(popupContainer, POPUP_TYPE.TEXT, '', { okButton: 'Cancel' });
|
||||||
|
popup.show()
|
||||||
|
.then((result => resolve(typeof result === 'number' ? resultToButtonMap.get(result) ?? '' : '')))
|
||||||
.catch(() => resolve(''));
|
.catch(() => resolve(''));
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
@ -1494,7 +1504,7 @@ async function popupCallback(args, value) {
|
|||||||
okButton: args?.okButton !== undefined && typeof args?.okButton === 'string' ? args.okButton : 'Ok',
|
okButton: args?.okButton !== undefined && typeof args?.okButton === 'string' ? args.okButton : 'Ok',
|
||||||
};
|
};
|
||||||
await delay(1);
|
await delay(1);
|
||||||
await callPopup(safeValue, 'text', '', popupOptions);
|
await callGenericPopup(safeValue, POPUP_TYPE.TEXT, '', popupOptions);
|
||||||
await delay(1);
|
await delay(1);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ async function downloadJannyCharacter(uuid) {
|
|||||||
// This endpoint is being guarded behind Bot Fight Mode of Cloudflare
|
// This endpoint is being guarded behind Bot Fight Mode of Cloudflare
|
||||||
// So hosted ST on Azure/AWS/GCP/Collab might get blocked by IP
|
// So hosted ST on Azure/AWS/GCP/Collab might get blocked by IP
|
||||||
// Should work normally on self-host PC/Android
|
// Should work normally on self-host PC/Android
|
||||||
const result = await fetch('https://api.janitorai.me/api/v1/download', {
|
const result = await fetch('https://api.jannyai.com/api/v1/download', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
Reference in New Issue
Block a user