mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'main' into feature/ssl-encryption
This commit is contained in:
32
.github/workflows/npm-publish.yml
vendored
Normal file
32
.github/workflows/npm-publish.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
||||||
|
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
||||||
|
|
||||||
|
name: Node.js Package
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- run: npm ci
|
||||||
|
|
||||||
|
publish-npm:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
registry-url: https://registry.npmjs.org/
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
4
.npmignore
Normal file
4
.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules/
|
||||||
|
/uploads/
|
||||||
|
.DS_Store
|
||||||
|
/thumbnails
|
@ -233,13 +233,10 @@
|
|||||||
"# ---\n",
|
"# ---\n",
|
||||||
"# nodejs\n",
|
"# nodejs\n",
|
||||||
"%cd /\n",
|
"%cd /\n",
|
||||||
"def setupNVM():\n",
|
|
||||||
" !curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n",
|
|
||||||
"ii.addTask(\"Setup NVM\", setupNVM)\n",
|
|
||||||
"\n",
|
|
||||||
"def installNode():\n",
|
"def installNode():\n",
|
||||||
" !nvm install 19.1.0\n",
|
" !npm install -g n\n",
|
||||||
" !nvm use 19.1.0\n",
|
" !n 19\n",
|
||||||
|
" !node --version\n",
|
||||||
"ii.addTask(\"Install node\", installNode)\n",
|
"ii.addTask(\"Install node\", installNode)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
10
package-lock.json
generated
10
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "TavernAI",
|
"name": "sillytavern",
|
||||||
"version": "1.3.0",
|
"version": "1.4.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "TavernAI",
|
"name": "sillytavern",
|
||||||
"version": "1.3.0",
|
"version": "1.4.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
@ -35,7 +35,7 @@
|
|||||||
"yargs": "^17.7.1"
|
"yargs": "^17.7.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"TavernAI": "server.js"
|
"sillytavern": "server.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@dqbd/tiktoken": {
|
"node_modules/@dqbd/tiktoken": {
|
||||||
|
@ -31,10 +31,13 @@
|
|||||||
"xml2js": "^0.5.0"
|
"xml2js": "^0.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "TavernAI",
|
"name": "sillytavern",
|
||||||
"version": "1.3.0",
|
"version": "1.4.8",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"TavernAI": "server.js"
|
"sillytavern": "./server.js"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-path-concat": "off",
|
"no-path-concat": "off",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Character Descriptions</title>
|
<title>Character Descriptions</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Import Chat</title>
|
<title>Import Chat</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>Chat import</h2>
|
<h2>Chat import</h2>
|
||||||
<h3>Import chats into TavernAI</h3>
|
<h3>Import chats into SillyTavern</h3>
|
||||||
<p>To import Character.AI chats, use this tool: <a href="https://github.com/0x000011b/characterai-dumper">https://github.com/0x000011b/characterai-dumper</a>.</p>
|
<p>To import Character.AI chats, use this tool: <a href="https://github.com/0x000011b/characterai-dumper">https://github.com/0x000011b/characterai-dumper</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Example Dialogues</title>
|
<title>Example Dialogues</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Scenario</title>
|
<title>Scenario</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<h2>World Info</h2>
|
<h2>World Info</h2>
|
||||||
<h4>World Info enhances AI's understanding of the details in your world.</h4>
|
<h4>World Info enhances AI's understanding of the details in your world.</h4>
|
||||||
<p>It functions like a dynamic dictionary that only inserts relevant information from World Info entries when keywords associated with the entries are present in the message text.</p>
|
<p>It functions like a dynamic dictionary that only inserts relevant information from World Info entries when keywords associated with the entries are present in the message text.</p>
|
||||||
<p>The TavernAI engine activates and seamlessly integrates the appropriate lore into the prompt, providing background information to the AI.</p>
|
<p>SillyTavern activates and seamlessly integrates the appropriate lore into the prompt, providing background information to the AI.</p>
|
||||||
<p><i>It is important to note that while World Info helps guide the AI towards your desired lore, it does not guarantee its appearance in the generated output messages.</i></p>
|
<p><i>It is important to note that while World Info helps guide the AI towards your desired lore, it does not guarantee its appearance in the generated output messages.</i></p>
|
||||||
|
|
||||||
<h3>Pro Tips</h3>
|
<h3>Pro Tips</h3>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>Scan Depth</h2>
|
<h2>Scan Depth</h2>
|
||||||
<h4>Defines how many messages in the chat history should be scanned for World Info keys.</h4>
|
<h4>Defines how many messages in the chat history should be scanned for World Info keys.</h4>
|
||||||
<p>If set to 1, then TavernAI only scans the message you send and the most recent reply.</p>
|
<p>If set to 1, then SillyTavern only scans the message you send and the most recent reply.</p>
|
||||||
<p>This stacks up to 10 message pairs it total.</p>
|
<p>This stacks up to 10 message pairs it total.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Personality Summary</title>
|
<title>Personality Summary</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - First Message</title>
|
<title>First Message</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - KobolAI Settings</title>
|
<title>KoboldAI Settings</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>KoboldAI Settings</h2>
|
<h2>KoboldAI Settings</h2>
|
||||||
<p>Standard KoboldAI settings files are used here. To add your own settings, simply add the file .settings
|
<p>Standard KoboldAI settings files are used here. To add your own settings, simply add the file .settings
|
||||||
in TavernAI\public\KoboldAI Settings
|
in SillyTavern\public\KoboldAI Settings
|
||||||
</p>
|
</p>
|
||||||
<h3>Temperature</h3>
|
<h3>Temperature</h3>
|
||||||
<p>Value from 0.1 to 2.0. Lower value - the answers are more logical, but less creative. Higher value - the
|
<p>Value from 0.1 to 2.0. Lower value - the answers are more logical, but less creative. Higher value - the
|
||||||
@ -34,7 +34,7 @@
|
|||||||
The larger the parameter value, the longer the generation time takes.</p>
|
The larger the parameter value, the longer the generation time takes.</p>
|
||||||
<h3>Context size</h3>
|
<h3>Context size</h3>
|
||||||
<p>How much will the AI remember. Context size also affects the speed of generation.<br><br>
|
<p>How much will the AI remember. Context size also affects the speed of generation.<br><br>
|
||||||
<u>Important</u>: The setting of Context Size in TavernAI GUI overrides the setting for KoboldAI GUI
|
<u>Important</u>: The setting of Context Size in SillyTavern GUI overrides the setting for KoboldAI GUI
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Advanced Settings</h2>
|
<h2>Advanced Settings</h2>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Novel AI API Key</title>
|
<title>NovelAI API Key</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - NovelAI Settings</title>
|
<title>NovelAI Settings</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>NovelAI settings</h2>
|
<h2>NovelAI settings</h2>
|
||||||
<p>
|
<p>
|
||||||
The files with the settings are here (TavernAI\public\NovelAI Settings).<br>
|
The files with the settings are here (SillyTavern\public\NovelAI Settings).<br>
|
||||||
You can also manually add your own settings files.
|
You can also manually add your own settings files.
|
||||||
</p>
|
</p>
|
||||||
<h3>Temperature</h3>
|
<h3>Temperature</h3>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - NovelAI Models</title>
|
<title>NovelAI Models</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>TavernAI - Note - Anchors</title>
|
<title>Anchors</title>
|
||||||
<link rel="stylesheet" href="/css/notes.css">
|
<link rel="stylesheet" href="/css/notes.css">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>Message Sound</h2>
|
<h2>Message Sound</h2>
|
||||||
<p>To play your own custom sound on receiving a new message from bot, replace the following MP3 file in your TavernAI folder:</p>
|
<p>To play your own custom sound on receiving a new message from bot, replace the following MP3 file in your SillyTavern folder:</p>
|
||||||
<code>
|
<code>
|
||||||
public/sounds/message.mp3
|
public/sounds/message.mp3
|
||||||
</code>
|
</code>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
Plays at 80% volume.
|
Plays at 80% volume.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If "Background Sound Only" option is enabled, the sound plays only if TavernAI window is <b>unfocused</b>.
|
If "Background Sound Only" option is enabled, the sound plays only if SillyTavern window is <b>unfocused</b>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h2>Multigen</h2>
|
<h2>Multigen</h2>
|
||||||
<p>TavernAI tries to create faster and longer responses by chaining the generation using smaller batches.</p>
|
<p>SillyTavern tries to create faster and longer responses by chaining the generation using smaller batches.</p>
|
||||||
<h3>Default settings:</h3>
|
<h3>Default settings:</h3>
|
||||||
<p>First batch = 50 tokens</p>
|
<p>First batch = 50 tokens</p>
|
||||||
<p>Next batches = 30 tokens</p>
|
<p>Next batches = 30 tokens</p>
|
||||||
|
@ -158,15 +158,15 @@ export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// API OBJECT FOR EXTERNAL WIRING
|
// API OBJECT FOR EXTERNAL WIRING
|
||||||
window["TavernAI"] = {};
|
window["SillyTavern"] = {};
|
||||||
|
|
||||||
let converter = new showdown.Converter({ emoji: "true" });
|
let converter = new showdown.Converter({ emoji: "true" });
|
||||||
const gpt3 = new GPT3BrowserTokenizer({ type: 'gpt3' });
|
const gpt3 = new GPT3BrowserTokenizer({ type: 'gpt3' });
|
||||||
/* let bg_menu_toggle = false; */
|
/* let bg_menu_toggle = false; */
|
||||||
const systemUserName = "TavernAI";
|
const systemUserName = "SillyTavern";
|
||||||
let default_user_name = "You";
|
let default_user_name = "You";
|
||||||
let name1 = default_user_name;
|
let name1 = default_user_name;
|
||||||
let name2 = "TavernAI";
|
let name2 = "SillyTavern";
|
||||||
let chat = [];
|
let chat = [];
|
||||||
let safetychat = [
|
let safetychat = [
|
||||||
{
|
{
|
||||||
@ -248,7 +248,7 @@ const system_messages = {
|
|||||||
is_user: false,
|
is_user: false,
|
||||||
is_name: true,
|
is_name: true,
|
||||||
mes: [
|
mes: [
|
||||||
'Welcome to TavernAI! In order to begin chatting:',
|
'Welcome to SillyTavern! In order to begin chatting:',
|
||||||
'<ul>',
|
'<ul>',
|
||||||
'<li>Connect to one of the supported generation APIs</li>',
|
'<li>Connect to one of the supported generation APIs</li>',
|
||||||
'<li>Create or pick a character from the list</li>',
|
'<li>Create or pick a character from the list</li>',
|
||||||
@ -1231,6 +1231,7 @@ class StreamingProcessor {
|
|||||||
let formattedText = messageFormating(processedText, chat[messageId].name, chat[messageId].is_system, chat[messageId].force_avatar);
|
let formattedText = messageFormating(processedText, chat[messageId].name, chat[messageId].is_system, chat[messageId].force_avatar);
|
||||||
const mesText = $(`#chat .mes[mesid="${messageId}"] .mes_text`);
|
const mesText = $(`#chat .mes[mesid="${messageId}"] .mes_text`);
|
||||||
mesText.html(formattedText);
|
mesText.html(formattedText);
|
||||||
|
this.setFirstSwipe(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollChatToBottom();
|
scrollChatToBottom();
|
||||||
@ -1257,6 +1258,14 @@ class StreamingProcessor {
|
|||||||
showSwipeButtons();
|
showSwipeButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setFirstSwipe(messageId) {
|
||||||
|
if (this.type !== 'swipe' && this.type !== 'impersonate') {
|
||||||
|
if (Array.isArray(chat[messageId]['swipes']) && chat[messageId]['swipes'].length === 1 && chat[messageId]['swipe_id'] === 0) {
|
||||||
|
chat[messageId]['swipes'][0] = chat[messageId]['mes'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onStopStreaming() {
|
onStopStreaming() {
|
||||||
this.onErrorStreaming();
|
this.onErrorStreaming();
|
||||||
}
|
}
|
||||||
@ -1274,11 +1283,12 @@ class StreamingProcessor {
|
|||||||
this.isFinished = false;
|
this.isFinished = false;
|
||||||
this.generator = this.nullStreamingGeneration;
|
this.generator = this.nullStreamingGeneration;
|
||||||
this.abortController = new AbortController();
|
this.abortController = new AbortController();
|
||||||
|
this.firstMessageText = '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
async generate() {
|
async generate() {
|
||||||
if (this.messageId == -1) {
|
if (this.messageId == -1) {
|
||||||
this.messageId = this.onStartStreaming('...');
|
this.messageId = this.onStartStreaming(this.firstMessageText);
|
||||||
await delay(1); // delay for message to be rendered
|
await delay(1); // delay for message to be rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1327,6 +1337,7 @@ async function Generate(type, automatic_trigger, force_name2) {
|
|||||||
|
|
||||||
if (isStreamingEnabled()) {
|
if (isStreamingEnabled()) {
|
||||||
streamingProcessor = new StreamingProcessor(type, force_name2);
|
streamingProcessor = new StreamingProcessor(type, force_name2);
|
||||||
|
hideSwipeButtons();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
streamingProcessor = false;
|
streamingProcessor = false;
|
||||||
@ -1566,8 +1577,6 @@ async function Generate(type, automatic_trigger, force_name2) {
|
|||||||
hordeAmountGen = adjustedParams.maxLength;
|
hordeAmountGen = adjustedParams.maxLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2);
|
|
||||||
|
|
||||||
// Extension added strings
|
// Extension added strings
|
||||||
const allAnchors = getAllExtensionPrompts();
|
const allAnchors = getAllExtensionPrompts();
|
||||||
const afterScenarioAnchor = getExtensionPrompt(extension_prompt_types.AFTER_SCENARIO);
|
const afterScenarioAnchor = getExtensionPrompt(extension_prompt_types.AFTER_SCENARIO);
|
||||||
@ -1575,12 +1584,13 @@ async function Generate(type, automatic_trigger, force_name2) {
|
|||||||
|
|
||||||
/////////////////////// swipecode
|
/////////////////////// swipecode
|
||||||
if (type == 'swipe') {
|
if (type == 'swipe') {
|
||||||
|
|
||||||
console.log('pre swipe shift: ' + chat2.length);
|
console.log('pre swipe shift: ' + chat2.length);
|
||||||
console.log('shifting swipe chat2');
|
console.log('shifting swipe chat2');
|
||||||
chat2.shift();
|
chat2.shift();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2);
|
||||||
|
|
||||||
console.log('post swipe shift:' + chat2.length);
|
console.log('post swipe shift:' + chat2.length);
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
@ -3444,7 +3454,7 @@ function isHordeGenerationNotAllowed() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
window["TavernAI"].getContext = function () {
|
window["SillyTavern"].getContext = function () {
|
||||||
return {
|
return {
|
||||||
chat: chat,
|
chat: chat,
|
||||||
characters: characters,
|
characters: characters,
|
||||||
|
@ -29,7 +29,7 @@ const extension_settings = {
|
|||||||
let modules = [];
|
let modules = [];
|
||||||
let activeExtensions = new Set();
|
let activeExtensions = new Set();
|
||||||
|
|
||||||
const getContext = () => window['TavernAI'].getContext();
|
const getContext = () => window['SillyTavern'].getContext();
|
||||||
const getApiUrl = () => extension_settings.apiUrl;
|
const getApiUrl = () => extension_settings.apiUrl;
|
||||||
const defaultRequestArgs = { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } };
|
const defaultRequestArgs = { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } };
|
||||||
let connectedToApi = false;
|
let connectedToApi = false;
|
||||||
|
52
server.js
52
server.js
@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const yargs = require('yargs/yargs');
|
const yargs = require('yargs/yargs');
|
||||||
const { hideBin } = require('yargs/helpers');
|
const { hideBin } = require('yargs/helpers');
|
||||||
|
|
||||||
@ -16,6 +18,10 @@ const cliArguments = yargs(hideBin(process.argv))
|
|||||||
describe: 'Path to your private key file.'
|
describe: 'Path to your private key file.'
|
||||||
}).argv;
|
}).argv;
|
||||||
|
|
||||||
|
// change all relative paths
|
||||||
|
const process = require('process')
|
||||||
|
process.chdir(__dirname)
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const compression = require('compression');
|
const compression = require('compression');
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -48,10 +54,10 @@ const ExifReader = require('exifreader');
|
|||||||
const exif = require('piexifjs');
|
const exif = require('piexifjs');
|
||||||
const webp = require('webp-converter');
|
const webp = require('webp-converter');
|
||||||
|
|
||||||
const config = require(path.join(process.cwd(), './config.conf'));
|
const config = require(path.join(__dirname, './config.conf'));
|
||||||
const server_port = process.env.SILLY_TAVERN_PORT || config.port;
|
const server_port = process.env.SILLY_TAVERN_PORT || config.port;
|
||||||
|
|
||||||
const whitelistPath = path.join(process.cwd(), "./whitelist.txt");
|
const whitelistPath = path.join(__dirname, "./whitelist.txt");
|
||||||
let whitelist = config.whitelist;
|
let whitelist = config.whitelist;
|
||||||
|
|
||||||
if (fs.existsSync(whitelistPath)) {
|
if (fs.existsSync(whitelistPath)) {
|
||||||
@ -202,8 +208,8 @@ app.use(function (req, res, next) { //Security
|
|||||||
|
|
||||||
//clientIp = req.connection.remoteAddress.split(':').pop();
|
//clientIp = req.connection.remoteAddress.split(':').pop();
|
||||||
if (whitelistMode === true && !whitelist.includes(clientIp)) {
|
if (whitelistMode === true && !whitelist.includes(clientIp)) {
|
||||||
console.log('Forbidden: Connection attempt from ' + clientIp + '. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.conf in root of TavernAI folder.\n');
|
console.log('Forbidden: Connection attempt from ' + clientIp + '. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.conf in root of SillyTavern folder.\n');
|
||||||
return res.status(403).send('<b>Forbidden</b>: Connection attempt from <b>' + clientIp + '</b>. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.conf in root of TavernAI folder.');
|
return res.status(403).send('<b>Forbidden</b>: Connection attempt from <b>' + clientIp + '</b>. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.conf in root of SillyTavern folder.');
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -230,7 +236,7 @@ app.use((req, res, next) => {
|
|||||||
app.use(express.static(__dirname + "/public", { refresh: true }));
|
app.use(express.static(__dirname + "/public", { refresh: true }));
|
||||||
|
|
||||||
app.use('/backgrounds', (req, res) => {
|
app.use('/backgrounds', (req, res) => {
|
||||||
const filePath = decodeURIComponent(path.join(process.cwd(), 'public/backgrounds', req.url.replace(/%20/g, ' ')));
|
const filePath = decodeURIComponent(path.join(__dirname, 'public/backgrounds', req.url.replace(/%20/g, ' ')));
|
||||||
fs.readFile(filePath, (err, data) => {
|
fs.readFile(filePath, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(404).send('File not found');
|
res.status(404).send('File not found');
|
||||||
@ -242,7 +248,7 @@ app.use('/backgrounds', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.use('/characters', (req, res) => {
|
app.use('/characters', (req, res) => {
|
||||||
const filePath = decodeURIComponent(path.join(process.cwd(), charactersPath, req.url.replace(/%20/g, ' ')));
|
const filePath = decodeURIComponent(path.join(__dirname, charactersPath, req.url.replace(/%20/g, ' ')));
|
||||||
fs.readFile(filePath, (err, data) => {
|
fs.readFile(filePath, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(404).send('File not found');
|
res.status(404).send('File not found');
|
||||||
@ -2171,6 +2177,36 @@ app.post("/getstatus_openai", jsonParser, function (request, response_getstatus_
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Shamelessly stolen from Agnai
|
||||||
|
app.post("/openai_usage", jsonParser, async function (_, response) {
|
||||||
|
if (!request.body) return response.sendStatus(400);
|
||||||
|
const key = request.body.key;
|
||||||
|
const api_url = new URL(request.body.reverse_proxy || api_openai).toString();
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${key}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
date.setDate(1);
|
||||||
|
const start_date = date.toISOString().slice(0, 10);
|
||||||
|
|
||||||
|
date.setMonth(date.getMonth() + 1);
|
||||||
|
const end_date = date.toISOString().slice(0, 10);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await getAsync(
|
||||||
|
`${api_url}/dashboard/billing/usage?start_date=${start_date}&end_date=${end_date}`,
|
||||||
|
{ headers },
|
||||||
|
);
|
||||||
|
return response.send(res);
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.post("/generate_openai", jsonParser, function (request, response_generate_openai) {
|
app.post("/generate_openai", jsonParser, function (request, response_generate_openai) {
|
||||||
if (!request.body) return response_generate_openai.sendStatus(400);
|
if (!request.body) return response_generate_openai.sendStatus(400);
|
||||||
const api_url = new URL(request.body.reverse_proxy || api_openai).toString();
|
const api_url = new URL(request.body.reverse_proxy || api_openai).toString();
|
||||||
@ -2352,8 +2388,10 @@ const setupTasks = async function () {
|
|||||||
if (!is_colab) await convertWebp();
|
if (!is_colab) await convertWebp();
|
||||||
|
|
||||||
console.log('Launching...');
|
console.log('Launching...');
|
||||||
|
|
||||||
if (autorun) open(tavernUrl);
|
if (autorun) open(tavernUrl);
|
||||||
console.log('TavernAI started: ' + tavernUrl);
|
console.log('SillyTavern started: ' + tavernUrl);
|
||||||
|
|
||||||
if (fs.existsSync('public/characters/update.txt') && !is_colab) {
|
if (fs.existsSync('public/characters/update.txt') && !is_colab) {
|
||||||
convertStage1();
|
convertStage1();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user