mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Compare commits
303 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9be3645152 | ||
|
a2d8a2a447 | ||
|
0ad96b6567 | ||
|
0c36d113bf | ||
|
410599b287 | ||
|
167b2d0fe4 | ||
|
11cc27d9c9 | ||
|
24f406917d | ||
|
5f64d4be7d | ||
|
b29f63f89e | ||
|
b4c7bb1f7b | ||
|
edbde2be37 | ||
|
1798959ddc | ||
|
d249000b52 | ||
|
58ada40586 | ||
|
f1a13f3093 | ||
|
aa3574f15f | ||
|
03e513a3e4 | ||
|
beca613745 | ||
|
dcca49e848 | ||
|
22cebe3176 | ||
|
dd2d292a56 | ||
|
c79bf951b7 | ||
|
e9107870c0 | ||
|
d50124e937 | ||
|
339dcaf506 | ||
|
5cdc3d1d18 | ||
|
8dcfe57888 | ||
|
2e35cd76ec | ||
|
51d2c9feba | ||
|
864ac3927f | ||
|
cb9e334a75 | ||
|
4f67e9f38b | ||
|
b4a401805f | ||
|
f2d5196890 | ||
|
c2ba3a773a | ||
|
3edc456fe7 | ||
|
5dbe2ebf29 | ||
|
6369ca6483 | ||
|
2b40fc7e76 | ||
|
52537904f7 | ||
|
1bf6d6d9f2 | ||
|
43dae79018 | ||
|
141850eda5 | ||
|
affdbb561f | ||
|
8f118f140f | ||
|
5b68a438f3 | ||
|
3f9cb7d575 | ||
|
85d1a008dd | ||
|
f0b20b67de | ||
|
e082138c18 | ||
|
9a647b96df | ||
|
3995238d77 | ||
|
bd9c4d28ca | ||
|
6f79f75f71 | ||
|
731ebc2eda | ||
|
635df947c5 | ||
|
63b34d9851 | ||
|
f9ae7ea949 | ||
|
df85218fa7 | ||
|
a4fe78f8ba | ||
|
4bc2d7f6ac | ||
|
5b2fff07b8 | ||
|
0517f1bbbc | ||
|
f49f9c1f96 | ||
|
f9cb6d783e | ||
|
600c9c6251 | ||
|
348805af74 | ||
|
57b299a9cd | ||
|
a662677f06 | ||
|
5fa158a37f | ||
|
c49f898886 | ||
|
81921bcd77 | ||
|
18fa925855 | ||
|
04a5d9694e | ||
|
6296cb8218 | ||
|
a4ab898933 | ||
|
ed8f5ddc33 | ||
|
65402eaa23 | ||
|
7e116f8b1f | ||
|
999c1b1105 | ||
|
0b535e98b8 | ||
|
4ecf2b9f2d | ||
|
5012237eb3 | ||
|
8d121bf38f | ||
|
d0650e6910 | ||
|
1e251c09e3 | ||
|
08a1eaad62 | ||
|
b4e29bf157 | ||
|
97d75aef73 | ||
|
25c461bd3f | ||
|
ca73a3a7b7 | ||
|
3816d7b202 | ||
|
008fcece04 | ||
|
70fa93f0c9 | ||
|
703965aec8 | ||
|
6fe4232f75 | ||
|
51e0c9130a | ||
|
85de505553 | ||
|
1d38109dcf | ||
|
6f0f420063 | ||
|
63ecca1fe2 | ||
|
b41bf7cf4e | ||
|
95a3021e53 | ||
|
b8939b8ccb | ||
|
8d6eaf3da4 | ||
|
18c74ecf09 | ||
|
f285110773 | ||
|
7f8df9533b | ||
|
e4cb916dff | ||
|
0b0b125bca | ||
|
c4e6b565a5 | ||
|
6e4236d5ee | ||
|
5c6343e85e | ||
|
50924a0672 | ||
|
b167eb9e22 | ||
|
fae364f079 | ||
|
2149bee87f | ||
|
08bee074ac | ||
|
ec8d30a19d | ||
|
31242e23eb | ||
|
9611e31481 | ||
|
5d1fff3df6 | ||
|
1dd747a24d | ||
|
cc3e27eca1 | ||
|
77f0fe5b80 | ||
|
5c316b50fa | ||
|
e8dd2e2b4d | ||
|
81f1bfd23f | ||
|
819b92a1d5 | ||
|
eaadb1c5c2 | ||
|
6a1b230c7e | ||
|
8a3547ecd0 | ||
|
4f458ce93a | ||
|
59af85ce1c | ||
|
dfa25a1796 | ||
|
2a16d24760 | ||
|
4657aef306 | ||
|
9ee2c2e9c1 | ||
|
02dca52948 | ||
|
5b954a3584 | ||
|
0f15d2d45b | ||
|
6a9f4a57b9 | ||
|
c8dace09b7 | ||
|
92ddb2b791 | ||
|
30c76eb420 | ||
|
579f43ed1c | ||
|
6e6e5f4747 | ||
|
421cda2ef0 | ||
|
0a742b867f | ||
|
82032133f1 | ||
|
b4c3985b61 | ||
|
19363f6cb9 | ||
|
d1d14bca13 | ||
|
89d7a05ea7 | ||
|
a9ebd2f80e | ||
|
d0637750e7 | ||
|
29f045636a | ||
|
2f3ded734f | ||
|
658701a943 | ||
|
61f164b5ff | ||
|
7f50d84953 | ||
|
19ff0fd618 | ||
|
d82eb373a6 | ||
|
edb46f480f | ||
|
a1f6220f33 | ||
|
410f08a317 | ||
|
e9a12b2f4e | ||
|
2997522c52 | ||
|
a87580663e | ||
|
b5d93f477a | ||
|
2c1a6ca67c | ||
|
84098ae933 | ||
|
e2f0162e5a | ||
|
59ae661f62 | ||
|
c4fbc8373d | ||
|
abb78d1d6b | ||
|
6b5aa9d06e | ||
|
6e78ec11fb | ||
|
7be3718a36 | ||
|
2c54627926 | ||
|
9d710801d8 | ||
|
3fceee8f2b | ||
|
3eb8f56b00 | ||
|
dbf964e430 | ||
|
3f406dcdf0 | ||
|
12a37e5342 | ||
|
47d4561bf8 | ||
|
93d1a264da | ||
|
f88f360404 | ||
|
83f689d9eb | ||
|
b1769153c7 | ||
|
1239026a8f | ||
|
575e21a1f5 | ||
|
96ddd5f4e5 | ||
|
15c81749b8 | ||
|
0873d3eaf9 | ||
|
d81151efa2 | ||
|
b84e6e07d1 | ||
|
c9f9bcfc86 | ||
|
6c1ba0aa13 | ||
|
df4ca46c02 | ||
|
dac9c091b2 | ||
|
e29902ed66 | ||
|
b3cdfe4fdf | ||
|
d265179f46 | ||
|
54d52a2986 | ||
|
4f80085fa3 | ||
|
c9c4f30637 | ||
|
1c095415a4 | ||
|
19acc05516 | ||
|
2cbde8b55c | ||
|
15cf87ef01 | ||
|
57bf499ce9 | ||
|
4fbbd34db9 | ||
|
9b04e43b4c | ||
|
5848ec498b | ||
|
5a570ff283 | ||
|
1dd6fa4b6a | ||
|
32377fd131 | ||
|
2f294b9f2b | ||
|
0b8295926e | ||
|
27ce0b5eb7 | ||
|
2797b4bd89 | ||
|
e9ba20f13c | ||
|
1ef68a34fe | ||
|
4189da19b1 | ||
|
ad3f8e7bf4 | ||
|
0dfe46a162 | ||
|
edeb804128 | ||
|
b49f234185 | ||
|
85a63b3bb3 | ||
|
04a0d012fc | ||
|
eaa33f2544 | ||
|
d5004d79bd | ||
|
96be2ebf35 | ||
|
fc90843207 | ||
|
679d40b3ce | ||
|
5307ee5d17 | ||
|
dd753498fa | ||
|
30e5a31591 | ||
|
2befd69c31 | ||
|
995b4d07ff | ||
|
788bbe969f | ||
|
99a89a7329 | ||
|
f8b5fe8b1e | ||
|
368cba1149 | ||
|
dac6639cc1 | ||
|
345a0e04fc | ||
|
82182015e2 | ||
|
384e8d43a6 | ||
|
b203b22d4d | ||
|
b9ea0061d5 | ||
|
e9afb39a4a | ||
|
df55a66153 | ||
|
6df0c2acf3 | ||
|
046bf20592 | ||
|
2879e2701f | ||
|
7771ecb0d0 | ||
|
cc9f452699 | ||
|
a8fb2d9bee | ||
|
165997c791 | ||
|
22e3c25e12 | ||
|
495b7eebbf | ||
|
4c39a32be1 | ||
|
584d7961eb | ||
|
977421edb7 | ||
|
f0b48aabff | ||
|
191c180946 | ||
|
03fe8f88f9 | ||
|
bb47712696 | ||
|
f466ff3243 | ||
|
306cf51da4 | ||
|
5857823c3b | ||
|
02418d2d97 | ||
|
0569b706dc | ||
|
bfda5a5492 | ||
|
03e5ca054d | ||
|
3e29d39f05 | ||
|
01f14b461f | ||
|
edb79d8c53 | ||
|
db71b87309 | ||
|
8f426a0184 | ||
|
773d42b886 | ||
|
1b7c51ebde | ||
|
e2d4f9dc8c | ||
|
0a9b595f80 | ||
|
86e9974410 | ||
|
423f88a458 | ||
|
9bc3e4e47c | ||
|
1838ca1994 | ||
|
2411006fdb | ||
|
5421925d6c | ||
|
d9b2b9f753 | ||
|
a081f78bd8 | ||
|
5275e0c904 | ||
|
2903167fad | ||
|
a25cb024fe | ||
|
6203d82f48 | ||
|
21ebe0c148 | ||
|
43510d5626 | ||
|
3cd97b0772 | ||
|
bd72f0eeb0 |
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
name: Bug Report 🐛
|
name: Bug Report 🐛
|
||||||
description: Report something that's not working the way it's (probably) intended to. PAY ATTENTION, Support requests for external programs (reverse proxies, 3rd party servers, other peoples' forks) will be refused!"
|
description: Report something that's not working the intended way. Support requests for external programs (reverse proxies, 3rd party servers, other peoples' forks) will be refused!
|
||||||
title: '[BUG] <title>'
|
title: '[BUG] <title>'
|
||||||
labels: ['bug']
|
labels: ['bug']
|
||||||
body:
|
body:
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -9,7 +9,7 @@ body:
|
|||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: similarRequest
|
id: similarRequest
|
||||||
attributes:
|
attributes:
|
||||||
label: Have you searched for similar [requests](https://github.com/SillyTavern/SillyTavern/issues?q=)?
|
label: Have you searched for similar requests?
|
||||||
description:
|
description:
|
||||||
options:
|
options:
|
||||||
- 'No'
|
- 'No'
|
||||||
|
5
.github/readme-zh_cn.md
vendored
5
.github/readme-zh_cn.md
vendored
@@ -1,8 +1,8 @@
|
|||||||
[English](readme.md) | 中文
|
[English](readme.md) | 中文
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
移动设备界面友好,多种人工智能服务或模型支持(KoboldAI/CPP, Horde, NovelAI, Ooba, OpenAI, OpenRouter, Claude, Scale),类似 Galgame 的 老 婆 模 式,Horde SD,文本系统语音生成,世界信息(Lorebooks),可定制的界面,自动翻译,和比你所需要的更多的 Prompt。附带扩展服务,支持文本绘画生成与语音生成和基于向量数据库 ChromaDB 的聊天信息总结。
|
移动设备界面友好,多种人工智能服务或模型支持(KoboldAI/CPP, Horde, NovelAI, Ooba, OpenAI, OpenRouter, Claude, Scale),类似 Galgame 的 老 婆 模 式,Horde SD,文本系统语音生成,世界信息(Lorebooks),可定制的界面,自动翻译,和比你所需要的更多的 Prompt。附带扩展服务,支持文本绘画生成与语音生成和基于向量数据库 的聊天信息总结。
|
||||||
|
|
||||||
基于 TavernAI 1.2.8 的分叉版本
|
基于 TavernAI 1.2.8 的分叉版本
|
||||||
|
|
||||||
@@ -81,7 +81,6 @@ SillyTavern 支持扩展服务,一些额外的人工智能模块可通过 [Sil
|
|||||||
* 在聊天窗口发送图片,并由人工智能解释图片内容
|
* 在聊天窗口发送图片,并由人工智能解释图片内容
|
||||||
* 文本图像生成(5 预设,以及 "自由模式")
|
* 文本图像生成(5 预设,以及 "自由模式")
|
||||||
* 聊天信息的文字转语音(通过 ElevenLabs、Silero 或操作系统的语音生成)
|
* 聊天信息的文字转语音(通过 ElevenLabs、Silero 或操作系统的语音生成)
|
||||||
* ChromaDB 向量数据库,用于更智能的聊天 Prompt
|
|
||||||
|
|
||||||
扩展服务的完整功能介绍和使用教程,请参阅 [Docs](https://docs.sillytavern.app/extras/extensions/)。
|
扩展服务的完整功能介绍和使用教程,请参阅 [Docs](https://docs.sillytavern.app/extras/extensions/)。
|
||||||
|
|
||||||
|
15
.github/readme.md
vendored
15
.github/readme.md
vendored
@@ -1,15 +1,19 @@
|
|||||||
English | [中文](readme-zh_cn.md)
|
English | [中文](readme-zh_cn.md)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Mobile-friendly, Multi-API (KoboldAI/CPP, Horde, NovelAI, Ooba, OpenAI, OpenRouter, Claude, Scale), VN-like Waifu Mode, Horde SD, System TTS, WorldInfo (lorebooks), customizable UI, auto-translate, and more prompt options than you'd ever want or need. Optional Extras server for more SD/TTS options + ChromaDB/Summarize.
|
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.
|
||||||
|
|
||||||
Based on a fork of TavernAI 1.2.8
|
Based on a fork of [TavernAI](https://github.com/TavernAI/TavernAI) 1.2.8
|
||||||
|
|
||||||
|
## Important news!
|
||||||
|
|
||||||
|
1. We have created a [Documentation website](https://docs.sillytavern.app/) to answer most of your questions and help you get started.
|
||||||
|
|
||||||
|
2. Missing extensions after the update? Since the 1.10.6 release version, most of the previously built-in extensions have been converted to downloadable add-ons. You can download them via the built-in "Download Extensions and Assets" menu in the extensions panel (stacked blocks icon in the top bar).
|
||||||
|
|
||||||
### Brought to you by Cohee, RossAscends, and the SillyTavern community
|
### Brought to you by Cohee, RossAscends, and the SillyTavern community
|
||||||
|
|
||||||
NOTE: We have created a [Documentation website](https://docs.sillytavern.app/) to answer most of your questions and help you get started.
|
|
||||||
|
|
||||||
### What is SillyTavern or TavernAI?
|
### What is SillyTavern or TavernAI?
|
||||||
|
|
||||||
SillyTavern is a user interface you can install on your computer (and Android phones) that allows you to interact with text generation AIs and chat/roleplay with characters you or the community create.
|
SillyTavern is a user interface you can install on your computer (and Android phones) that allows you to interact with text generation AIs and chat/roleplay with characters you or the community create.
|
||||||
@@ -80,7 +84,6 @@ SillyTavern has extensibility support, with some additional AI modules hosted vi
|
|||||||
* Sending images to chat, and the AI interpreting the content
|
* Sending images to chat, and the AI interpreting the content
|
||||||
* Stable Diffusion image generation (5 chat-related presets plus 'free mode')
|
* Stable Diffusion image generation (5 chat-related presets plus 'free mode')
|
||||||
* Text-to-speech for AI response messages (via ElevenLabs, Silero, or the OS's System TTS)
|
* Text-to-speech for AI response messages (via ElevenLabs, Silero, or the OS's System TTS)
|
||||||
* ChromaDB vector storage for smarter chat prompt formatting
|
|
||||||
|
|
||||||
A full list of included extensions and tutorials on how to use them can be found in the [Docs](https://docs.sillytavern.app/extras/extensions/).
|
A full list of included extensions and tutorials on how to use them can be found in the [Docs](https://docs.sillytavern.app/extras/extensions/).
|
||||||
|
|
||||||
|
2
.github/workflows/docker-publish.yml
vendored
2
.github/workflows/docker-publish.yml
vendored
@@ -11,7 +11,7 @@ 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 may not contain uppercase characters, so we can not use the repository name
|
||||||
# Creates a string like: ghcr.io/SillyTavern/sillytavern
|
# Creates a string like: ghcr.io/SillyTavern/sillytavern
|
||||||
image_name: ghcr.io/${{ github.repository_owner }}/sillytavern
|
image_name: ghcr.io/sillytavern/sillytavern
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ COPY . ./
|
|||||||
|
|
||||||
# Copy default chats, characters and user avatars to <folder>.default folder
|
# Copy default chats, characters and user avatars to <folder>.default folder
|
||||||
RUN \
|
RUN \
|
||||||
IFS="," RESOURCES="characters,chats,groups,group chats,User Avatars,worlds" && \
|
IFS="," RESOURCES="characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings" && \
|
||||||
\
|
\
|
||||||
echo "*** Store default $RESOURCES in <folder>.default ***" && \
|
echo "*** Store default $RESOURCES in <folder>.default ***" && \
|
||||||
for R in $RESOURCES; do mv "public/$R" "public/$R.default"; done && \
|
for R in $RESOURCES; do mv "public/$R" "public/$R.default"; done && \
|
||||||
|
@@ -70,7 +70,7 @@
|
|||||||
"#@markdown * ckpt/sd15 - base SD 1.5\n",
|
"#@markdown * ckpt/sd15 - base SD 1.5\n",
|
||||||
"#@markdown * stabilityai/stable-diffusion-2-1-base - base SD 2.1\n",
|
"#@markdown * stabilityai/stable-diffusion-2-1-base - base SD 2.1\n",
|
||||||
"extras_enable_chromadb = True #@param {type:\"boolean\"}\n",
|
"extras_enable_chromadb = True #@param {type:\"boolean\"}\n",
|
||||||
"#@markdown Enables ChromaDB for Infinity Context plugin\n",
|
"#@markdown Enables ChromaDB module\n",
|
||||||
"\n",
|
"\n",
|
||||||
"import subprocess\n",
|
"import subprocess\n",
|
||||||
"import secrets\n",
|
"import secrets\n",
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
"!git clone https://github.com/Cohee1207/tts_samples\n",
|
"!git clone https://github.com/Cohee1207/tts_samples\n",
|
||||||
"!npm install -g localtunnel\n",
|
"!npm install -g localtunnel\n",
|
||||||
"!pip install -r requirements-complete.txt\n",
|
"!pip install -r requirements-complete.txt\n",
|
||||||
"!pip install tensorflow==2.12\n",
|
"!pip install tensorflow==2.14\n",
|
||||||
"!pip install colorama\n",
|
"!pip install colorama\n",
|
||||||
"!pip install Flask-Cors\n",
|
"!pip install Flask-Cors\n",
|
||||||
"!pip install Flask-Compress\n",
|
"!pip install Flask-Compress\n",
|
||||||
|
@@ -10,6 +10,7 @@ const listen = true; // If true, Can be access from other device or PC. otherwis
|
|||||||
const allowKeysExposure = false; // If true, private API keys could be fetched to the frontend.
|
const allowKeysExposure = false; // If true, private API keys could be fetched to the frontend.
|
||||||
const skipContentCheck = false; // If true, no new default content will be delivered to you.
|
const skipContentCheck = false; // If true, no new default content will be delivered to you.
|
||||||
const thumbnailsQuality = 95; // Quality of thumbnails. 0-100
|
const thumbnailsQuality = 95; // Quality of thumbnails. 0-100
|
||||||
|
const disableChatBackup = false; // Disables the backup of chat logs to the /backups folder
|
||||||
|
|
||||||
// If true, Allows insecure settings for listen, whitelist, and authentication.
|
// If true, Allows insecure settings for listen, whitelist, and authentication.
|
||||||
// Change this setting only on "trusted networks". Do not change this value unless you are aware of the issues that can arise from changing this setting and configuring a insecure setting.
|
// Change this setting only on "trusted networks". Do not change this value unless you are aware of the issues that can arise from changing this setting and configuring a insecure setting.
|
||||||
@@ -26,6 +27,8 @@ const extras = {
|
|||||||
captioningModel: 'Xenova/vit-gpt2-image-captioning',
|
captioningModel: 'Xenova/vit-gpt2-image-captioning',
|
||||||
// Feature extraction model. HuggingFace ID of a model in ONNX format.
|
// Feature extraction model. HuggingFace ID of a model in ONNX format.
|
||||||
embeddingModel: 'Xenova/all-mpnet-base-v2',
|
embeddingModel: 'Xenova/all-mpnet-base-v2',
|
||||||
|
// GPT-2 text generation model. HuggingFace ID of a model in ONNX format.
|
||||||
|
promptExpansionModel: 'Cohee/fooocus_expansion-onnx',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Request overrides for additional headers
|
// Request overrides for additional headers
|
||||||
@@ -49,4 +52,5 @@ module.exports = {
|
|||||||
requestOverrides,
|
requestOverrides,
|
||||||
thumbnailsQuality,
|
thumbnailsQuality,
|
||||||
extras,
|
extras,
|
||||||
|
disableChatBackup,
|
||||||
};
|
};
|
||||||
|
@@ -406,7 +406,6 @@
|
|||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
"single_line": false,
|
||||||
"use_stop_sequence": false,
|
|
||||||
"streaming_kobold": false,
|
"streaming_kobold": false,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -416,7 +415,12 @@
|
|||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"use_default_badwordsids": false,
|
||||||
|
"grammar": ""
|
||||||
},
|
},
|
||||||
"oai_settings": {
|
"oai_settings": {
|
||||||
"preset_settings_openai": "Default",
|
"preset_settings_openai": "Default",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Initialize missing user files
|
# Initialize missing user files
|
||||||
IFS="," RESOURCES="characters,groups,group chats,chats,User Avatars,worlds"
|
IFS="," RESOURCES="characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings"
|
||||||
for R in $RESOURCES; do
|
for R in $RESOURCES; do
|
||||||
if [ ! -e "config/$R" ]; then
|
if [ ! -e "config/$R" ]; then
|
||||||
echo "Resource not found, copying from defaults: $R"
|
echo "Resource not found, copying from defaults: $R"
|
||||||
|
249
package-lock.json
generated
249
package-lock.json
generated
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.10.4",
|
"version": "1.10.7",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.10.4",
|
"version": "1.10.7",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@agnai/sentencepiece-js": "^1.1.1",
|
"@agnai/sentencepiece-js": "^1.1.1",
|
||||||
"@agnai/web-tokenizers": "^0.1.3",
|
"@agnai/web-tokenizers": "^0.1.3",
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
|
"bing-translate-api": "^2.9.1",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"compression": "^1",
|
"compression": "^1",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
@@ -694,11 +695,57 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@sindresorhus/is": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||||
|
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@szmarczak/http-timer": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
|
||||||
|
"dependencies": {
|
||||||
|
"defer-to-connect": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tokenizer/token": {
|
"node_modules/@tokenizer/token": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||||
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
|
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/cacheable-request": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/http-cache-semantics": "*",
|
||||||
|
"@types/keyv": "^3.1.4",
|
||||||
|
"@types/node": "*",
|
||||||
|
"@types/responselike": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/http-cache-semantics": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw=="
|
||||||
|
},
|
||||||
|
"node_modules/@types/keyv": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/long": {
|
"node_modules/@types/long": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
||||||
@@ -709,6 +756,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
|
||||||
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
|
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/responselike": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-TiGnitEDxj2X0j+98Eqk5lv/Cij8oHd32bU4D/Yw6AOq7vvTk0gSD2GPj0G/HkvhMoVsdlhYF4yqqlyPBTM6Sg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
@@ -858,6 +913,14 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/bing-translate-api": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bing-translate-api/-/bing-translate-api-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-DaYqa7iupfj+fj/KeaeZSp5FUY/ZR4sZ6jqoTP0RHkYOUfo7wwoxlhYDkh4VcvBBzuVORnBEgdXBVQrfM4kk7g==",
|
||||||
|
"dependencies": {
|
||||||
|
"got": "^11.8.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bl": {
|
"node_modules/bl": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
@@ -999,6 +1062,31 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cacheable-lookup": {
|
||||||
|
"version": "5.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
|
||||||
|
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cacheable-request": {
|
||||||
|
"version": "7.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
|
||||||
|
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
|
||||||
|
"dependencies": {
|
||||||
|
"clone-response": "^1.0.2",
|
||||||
|
"get-stream": "^5.1.0",
|
||||||
|
"http-cache-semantics": "^4.0.0",
|
||||||
|
"keyv": "^4.0.0",
|
||||||
|
"lowercase-keys": "^2.0.0",
|
||||||
|
"normalize-url": "^6.0.1",
|
||||||
|
"responselike": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
@@ -1082,6 +1170,25 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/clone-response": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-response": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/clone-response/node_modules/mimic-response": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -1290,7 +1397,6 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mimic-response": "^3.1.0"
|
"mimic-response": "^3.1.0"
|
||||||
},
|
},
|
||||||
@@ -1310,6 +1416,14 @@
|
|||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/defer-to-connect": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/define-lazy-prop": {
|
"node_modules/define-lazy-prop": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||||
@@ -1458,7 +1572,6 @@
|
|||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
}
|
}
|
||||||
@@ -1774,6 +1887,20 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-stream": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pump": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gifwrap": {
|
"node_modules/gifwrap": {
|
||||||
"version": "0.10.1",
|
"version": "0.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
|
||||||
@@ -1835,6 +1962,30 @@
|
|||||||
"resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz",
|
||||||
"integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A=="
|
"integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/got": {
|
||||||
|
"version": "11.8.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
|
||||||
|
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sindresorhus/is": "^4.0.0",
|
||||||
|
"@szmarczak/http-timer": "^4.0.5",
|
||||||
|
"@types/cacheable-request": "^6.0.1",
|
||||||
|
"@types/responselike": "^1.0.0",
|
||||||
|
"cacheable-lookup": "^5.0.3",
|
||||||
|
"cacheable-request": "^7.0.2",
|
||||||
|
"decompress-response": "^6.0.0",
|
||||||
|
"http2-wrapper": "^1.0.0-beta.5.2",
|
||||||
|
"lowercase-keys": "^2.0.0",
|
||||||
|
"p-cancelable": "^2.0.0",
|
||||||
|
"responselike": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.19.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/got?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gpt-3-encoder": {
|
"node_modules/gpt-3-encoder": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/gpt-3-encoder/-/gpt-3-encoder-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/gpt-3-encoder/-/gpt-3-encoder-1.1.4.tgz",
|
||||||
@@ -1922,6 +2073,11 @@
|
|||||||
"entities": "^4.4.0"
|
"entities": "^4.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/http-cache-semantics": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
|
||||||
|
},
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
@@ -1937,6 +2093,18 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/http2-wrapper": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
|
||||||
|
"dependencies": {
|
||||||
|
"quick-lru": "^5.1.1",
|
||||||
|
"resolve-alpn": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/https-proxy-agent": {
|
"node_modules/https-proxy-agent": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
@@ -2196,6 +2364,11 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/json-buffer": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||||
|
},
|
||||||
"node_modules/json-colorizer": {
|
"node_modules/json-colorizer": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-2.2.2.tgz",
|
||||||
@@ -2284,6 +2457,14 @@
|
|||||||
"graceful-fs": "^4.1.6"
|
"graceful-fs": "^4.1.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/keyv": {
|
||||||
|
"version": "4.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
|
||||||
|
"integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
|
||||||
|
"dependencies": {
|
||||||
|
"json-buffer": "3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/load-bmfont": {
|
"node_modules/load-bmfont": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
|
||||||
@@ -2314,6 +2495,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lowercase-keys": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@@ -2403,7 +2592,6 @@
|
|||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -2549,6 +2737,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-url": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nth-check": {
|
"node_modules/nth-check": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||||
@@ -2604,7 +2803,6 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@@ -2682,6 +2880,14 @@
|
|||||||
"follow-redirects": "^1.14.8"
|
"follow-redirects": "^1.14.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/p-cancelable": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-is-promise": {
|
"node_modules/p-is-promise": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
|
||||||
@@ -3108,7 +3314,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"end-of-stream": "^1.1.0",
|
"end-of-stream": "^1.1.0",
|
||||||
"once": "^1.3.1"
|
"once": "^1.3.1"
|
||||||
@@ -3148,6 +3353,17 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/quick-lru": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/range-parser": {
|
"node_modules/range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
@@ -3265,6 +3481,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/resolve-alpn": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
|
||||||
|
},
|
||||||
"node_modules/resolve/node_modules/is-core-module": {
|
"node_modules/resolve/node_modules/is-core-module": {
|
||||||
"version": "2.12.1",
|
"version": "2.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
|
||||||
@@ -3297,6 +3518,17 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/responselike": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"lowercase-keys": "^2.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reusify": {
|
"node_modules/reusify": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||||
@@ -3905,8 +4137,7 @@
|
|||||||
"node_modules/wrappy": {
|
"node_modules/wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/write-file-atomic": {
|
"node_modules/write-file-atomic": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
"device-detector-js": "^3.0.3",
|
"device-detector-js": "^3.0.3",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"google-translate-api-browser": "^3.0.1",
|
"google-translate-api-browser": "^3.0.1",
|
||||||
|
"bing-translate-api": "^2.9.1",
|
||||||
"gpt3-tokenizer": "^1.1.5",
|
"gpt3-tokenizer": "^1.1.5",
|
||||||
"ip-matching": "^2.1.2",
|
"ip-matching": "^2.1.2",
|
||||||
"ipaddr.js": "^2.0.1",
|
"ipaddr.js": "^2.0.1",
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||||
},
|
},
|
||||||
"version": "1.10.4",
|
"version": "1.10.7",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"start-multi": "node server.js --disableCsrf",
|
"start-multi": "node server.js --disableCsrf",
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1.15,
|
"temp": 1.15,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.95,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.8,
|
|
||||||
"rep_pen": 1.05,
|
"rep_pen": 1.05,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 0.95,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.8,
|
||||||
"rep_pen_slope": 7,
|
"rep_pen_slope": 7,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
5,
|
5,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.59,
|
"temp": 0.59,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.87,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.87,
|
||||||
"rep_pen_slope": 0.3,
|
"rep_pen_slope": 0.3,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.8,
|
"temp": 0.8,
|
||||||
"top_k": 100,
|
|
||||||
"top_p": 0.9,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 1,
|
|
||||||
"rep_pen": 1.15,
|
"rep_pen": 1.15,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 0.9,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 100,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 3.4,
|
"rep_pen_slope": 3.4,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.51,
|
"temp": 0.51,
|
||||||
"top_p": 1,
|
|
||||||
"top_k": 0,
|
|
||||||
"tfs": 0.99,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"rep_pen": 1.2,
|
"rep_pen": 1.2,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.99,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -17,5 +16,9 @@
|
|||||||
4,
|
4,
|
||||||
2,
|
2,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.63,
|
"temp": 0.63,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.98,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.98,
|
|
||||||
"rep_pen": 1.05,
|
"rep_pen": 1.05,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 0.98,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.98,
|
||||||
"rep_pen_slope": 0.1,
|
"rep_pen_slope": 0.1,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
5,
|
5,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.7,
|
"temp": 0.7,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.5,
|
|
||||||
"top_a": 0.75,
|
|
||||||
"typical": 0.19,
|
|
||||||
"tfs": 0.97,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 1024,
|
"rep_pen_range": 1024,
|
||||||
|
"top_p": 0.5,
|
||||||
|
"top_a": 0.75,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 0.19,
|
||||||
|
"tfs": 0.97,
|
||||||
"rep_pen_slope": 0.7,
|
"rep_pen_slope": 0.7,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
0
|
0
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.7,
|
"temp": 0.7,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.9,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 1024,
|
"rep_pen_range": 1024,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.9,
|
||||||
"rep_pen_slope": 0.7,
|
"rep_pen_slope": 0.7,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.66,
|
"temp": 0.66,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0.96,
|
|
||||||
"typical": 0.6,
|
|
||||||
"tfs": 1,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 1024,
|
"rep_pen_range": 1024,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0.96,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 0.6,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.7,
|
"rep_pen_slope": 0.7,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
0,
|
0,
|
||||||
2,
|
2,
|
||||||
3
|
3
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.94,
|
"temp": 0.94,
|
||||||
"top_k": 12,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.94,
|
|
||||||
"rep_pen": 1.05,
|
"rep_pen": 1.05,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 12,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.94,
|
||||||
"rep_pen_slope": 0.2,
|
"rep_pen_slope": 0.2,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1.5,
|
"temp": 1.5,
|
||||||
"top_k": 85,
|
|
||||||
"top_p": 0.24,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 1,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 0.24,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 85,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1.05,
|
"temp": 1.05,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.95,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 1,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 1024,
|
"rep_pen_range": 1024,
|
||||||
|
"top_p": 0.95,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.7,
|
"rep_pen_slope": 0.7,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.9,
|
"rep_pen_slope": 0.9,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -21,5 +20,5 @@
|
|||||||
"mirostat": 2,
|
"mirostat": 2,
|
||||||
"mirostat_tau": 9.61,
|
"mirostat_tau": 9.61,
|
||||||
"mirostat_eta": 1,
|
"mirostat_eta": 1,
|
||||||
"use_default_badwordsids": true
|
"grammar": ""
|
||||||
}
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.9,
|
"rep_pen_slope": 0.9,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -21,5 +20,5 @@
|
|||||||
"mirostat": 2,
|
"mirostat": 2,
|
||||||
"mirostat_tau": 9.91,
|
"mirostat_tau": 9.91,
|
||||||
"mirostat_eta": 1,
|
"mirostat_eta": 1,
|
||||||
"use_default_badwordsids": true
|
"grammar": ""
|
||||||
}
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.9,
|
"rep_pen_slope": 0.9,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -21,5 +20,5 @@
|
|||||||
"mirostat": 2,
|
"mirostat": 2,
|
||||||
"mirostat_tau": 9.62,
|
"mirostat_tau": 9.62,
|
||||||
"mirostat_eta": 1,
|
"mirostat_eta": 1,
|
||||||
"use_default_badwordsids": true
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1.07,
|
"temp": 1.07,
|
||||||
"top_k": 100,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.93,
|
|
||||||
"rep_pen": 1.05,
|
"rep_pen": 1.05,
|
||||||
"rep_pen_range": 404,
|
"rep_pen_range": 404,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 100,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.93,
|
||||||
"rep_pen_slope": 0.8,
|
"rep_pen_slope": 0.8,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
2,
|
2,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.44,
|
"temp": 0.44,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.9,
|
|
||||||
"rep_pen": 1.15,
|
"rep_pen": 1.15,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.9,
|
||||||
"rep_pen_slope": 6.8,
|
"rep_pen_slope": 6.8,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1.35,
|
"temp": 1.35,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 0.69,
|
|
||||||
"rep_pen": 1.15,
|
"rep_pen": 1.15,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 1,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 0.69,
|
||||||
"rep_pen_slope": 0.1,
|
"rep_pen_slope": 0.1,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 1,
|
"temp": 1,
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.95,
|
|
||||||
"top_a": 0,
|
|
||||||
"typical": 1,
|
|
||||||
"tfs": 1,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 600,
|
"rep_pen_range": 600,
|
||||||
|
"top_p": 0.95,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -17,5 +16,9 @@
|
|||||||
4,
|
4,
|
||||||
2,
|
2,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"temp": 0.72,
|
"temp": 0.72,
|
||||||
"tfs": 1,
|
|
||||||
"top_a": 0,
|
|
||||||
"top_k": 0,
|
|
||||||
"top_p": 0.73,
|
|
||||||
"typical": 1,
|
|
||||||
"rep_pen": 1.1,
|
"rep_pen": 1.1,
|
||||||
"rep_pen_range": 2048,
|
"rep_pen_range": 2048,
|
||||||
|
"top_p": 0.73,
|
||||||
|
"top_a": 0,
|
||||||
|
"top_k": 0,
|
||||||
|
"typical": 1,
|
||||||
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0.2,
|
"rep_pen_slope": 0.2,
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
@@ -16,5 +16,9 @@
|
|||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
4
|
4
|
||||||
]
|
],
|
||||||
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
}
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 0.95,
|
"tfs": 0.95,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -17,5 +16,9 @@
|
|||||||
4,
|
4,
|
||||||
2,
|
2,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -17,5 +16,9 @@
|
|||||||
4,
|
4,
|
||||||
2,
|
2,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
@@ -8,7 +8,6 @@
|
|||||||
"typical": 1,
|
"typical": 1,
|
||||||
"tfs": 1,
|
"tfs": 1,
|
||||||
"rep_pen_slope": 0,
|
"rep_pen_slope": 0,
|
||||||
"single_line": false,
|
|
||||||
"sampler_order": [
|
"sampler_order": [
|
||||||
6,
|
6,
|
||||||
0,
|
0,
|
||||||
@@ -17,5 +16,9 @@
|
|||||||
4,
|
4,
|
||||||
2,
|
2,
|
||||||
5
|
5
|
||||||
]
|
],
|
||||||
}
|
"mirostat": 0,
|
||||||
|
"mirostat_tau": 5,
|
||||||
|
"mirostat_eta": 0.1,
|
||||||
|
"grammar": ""
|
||||||
|
}
|
1
public/assets/blip/.placeholder
Normal file
1
public/assets/blip/.placeholder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Put blip audio files here
|
1
public/assets/live2d/.placeholder
Normal file
1
public/assets/live2d/.placeholder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Put live2d model folders here
|
11
public/context/Adventure.json
Normal file
11
public/context/Adventure.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
|
||||||
|
"example_separator": "",
|
||||||
|
"chat_start": "",
|
||||||
|
"always_force_name2": false,
|
||||||
|
"trim_sentences": false,
|
||||||
|
"include_newline": false,
|
||||||
|
"custom_stopping_strings": "[\"\\n\"]",
|
||||||
|
"custom_stopping_strings_macro": true,
|
||||||
|
"name": "Adventure"
|
||||||
|
}
|
6
public/context/ChatML.json
Normal file
6
public/context/ChatML.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"story_string": "<|im_start|>system\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}<|im_end|>",
|
||||||
|
"chat_start": "",
|
||||||
|
"example_separator": "",
|
||||||
|
"name": "ChatML"
|
||||||
|
}
|
6
public/context/Libra-32B.json
Normal file
6
public/context/Libra-32B.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"story_string": "### Instruction:\nWrite {{char}}'s next reply in this roleplay with {{user}}. Use the provided character sheet and example dialogue for formatting direction and character speech patterns.\n\n{{#if system}}{{system}}\n\n{{/if}}### Character Sheet:\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
|
||||||
|
"chat_start": "### START ROLEPLAY:",
|
||||||
|
"example_separator": "### Example:",
|
||||||
|
"name": "Libra-32B"
|
||||||
|
}
|
6
public/context/Lightning 1.1.json
Normal file
6
public/context/Lightning 1.1.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"story_string": "{{system}}\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{char}}'s description:{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality:{{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{user}}'s persona: {{persona}}\n{{/if}}",
|
||||||
|
"chat_start": "This is the history of the roleplay:",
|
||||||
|
"example_separator": "Example of an interaction:",
|
||||||
|
"name": "Lightning 1.1"
|
||||||
|
}
|
6
public/context/Mistral.json
Normal file
6
public/context/Mistral.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"story_string": "[INST] {{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}[/INST]",
|
||||||
|
"chat_start": "",
|
||||||
|
"example_separator": "Examples:",
|
||||||
|
"name": "Mistral"
|
||||||
|
}
|
6
public/context/Story.json
Normal file
6
public/context/Story.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
|
||||||
|
"chat_start": "",
|
||||||
|
"example_separator": "",
|
||||||
|
"name": "Story"
|
||||||
|
}
|
@@ -103,39 +103,39 @@ input.extension_missing[type="checkbox"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** LEFT COLUMN **/
|
/** LEFT COLUMN **/
|
||||||
#extensions_settings>.expression_settings {
|
#extensions_settings>#assets_ui {
|
||||||
order: 1;
|
order: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>.background_settings {
|
#extensions_settings>.expression_settings {
|
||||||
order: 2;
|
order: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>.sd_settings {
|
#extensions_settings>.background_settings {
|
||||||
order: 3;
|
order: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>#tts_settings {
|
#extensions_settings>.sd_settings {
|
||||||
order: 4;
|
order: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>#rvc_settings {
|
#extensions_settings>#tts_settings {
|
||||||
order: 5;
|
order: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>.objective-settings {
|
#extensions_settings>#rvc_settings {
|
||||||
order: 6;
|
order: 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>#speech_recognition_settings {
|
#extensions_settings>.objective-settings {
|
||||||
order: 7;
|
order: 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>#audio_settings {
|
#extensions_settings>#speech_recognition_settings {
|
||||||
order: 8;
|
order: 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extensions_settings>#assets_ui {
|
#extensions_settings>#audio_settings {
|
||||||
order: 9;
|
order: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
max-width: 90svw;
|
max-width: 90svw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.world_entry_thin_controls,
|
/* .world_entry_thin_controls, */
|
||||||
#persona-management-block,
|
#persona-management-block,
|
||||||
#character_popup .flex-container {
|
#character_popup .flex-container {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -63,6 +63,15 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.world_entry .inline-drawer-toggle {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#worldInfoScanningCheckboxes {
|
||||||
|
flex-flow: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -70,6 +79,10 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.world_entry_form_control {
|
||||||
|
/* width: 100%; */
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-content {
|
.drawer-content {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -125,6 +138,20 @@
|
|||||||
|
|
||||||
.wi-settings {
|
.wi-settings {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.WIEntryTitleAndStatus,
|
||||||
|
.WIEntryHeaderControls {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#WIEntryHeaderTitlesPC {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.WIEntryHeaderTitleMobile {
|
||||||
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#character_popup,
|
#character_popup,
|
||||||
@@ -161,7 +188,8 @@
|
|||||||
|
|
||||||
#showRawPrompt,
|
#showRawPrompt,
|
||||||
#copyPromptToClipboard,
|
#copyPromptToClipboard,
|
||||||
#groupCurrentMemberPopoutButton {
|
#groupCurrentMemberPopoutButton,
|
||||||
|
#summaryExtensionPopoutButton {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +293,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bg_menu_content {
|
.bg_list {
|
||||||
width: unset;
|
width: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,8 +339,7 @@
|
|||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
max-height: 50vh;
|
max-height: 50vh;
|
||||||
max-width: 50vh;
|
max-width: 90vw;
|
||||||
width: 50vw;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
filter: drop-shadow(2px 2px 2px #51515199);
|
filter: drop-shadow(2px 2px 2px #51515199);
|
||||||
@@ -418,4 +445,4 @@
|
|||||||
#horde_model {
|
#horde_model {
|
||||||
height: unset;
|
height: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -78,6 +78,7 @@
|
|||||||
|
|
||||||
#rm_group_members:empty {
|
#rm_group_members:empty {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rm_group_members:empty::before {
|
#rm_group_members:empty::before {
|
||||||
@@ -226,4 +227,5 @@
|
|||||||
|
|
||||||
.group_member .avatar {
|
.group_member .avatar {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
flex-basis: auto;
|
||||||
|
}
|
||||||
|
@@ -6,6 +6,16 @@
|
|||||||
color: var(--fullred);
|
color: var(--fullred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highlighted {
|
||||||
|
color: black;
|
||||||
|
background-color: yellow;
|
||||||
|
text-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.m-t-1 {
|
.m-t-1 {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
@@ -99,6 +109,10 @@
|
|||||||
align-self: start;
|
align-self: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gap3px {
|
||||||
|
gap: 3px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.gap5px {
|
.gap5px {
|
||||||
gap: 5px !important;
|
gap: 5px !important;
|
||||||
}
|
}
|
||||||
@@ -120,6 +134,10 @@
|
|||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.width100px {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.widthUnset {
|
.widthUnset {
|
||||||
width: unset;
|
width: unset;
|
||||||
}
|
}
|
||||||
@@ -147,6 +165,10 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.textAlignCenter {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.margin-right-10px {
|
.margin-right-10px {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
@@ -230,6 +252,10 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.padding0 {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.padding5 {
|
.padding5 {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
@@ -366,6 +392,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:disabled,
|
||||||
|
textarea:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.debug-red {
|
.debug-red {
|
||||||
border: 1px solid red !important;
|
border: 1px solid red !important;
|
||||||
}
|
}
|
||||||
@@ -394,6 +425,11 @@
|
|||||||
font-size: calc(var(--mainFontSize) * 0.6) !important;
|
font-size: calc(var(--mainFontSize) * 0.6) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.paddingBottom5px {
|
||||||
|
padding: unset;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.paddingTopBot5 {
|
.paddingTopBot5 {
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
}
|
}
|
||||||
@@ -421,4 +457,4 @@
|
|||||||
|
|
||||||
.opacity1 {
|
.opacity1 {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
|
@@ -138,8 +138,7 @@
|
|||||||
filter: brightness(1);
|
filter: brightness(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags_view,
|
.tags_view {
|
||||||
.open_alternate_greetings {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
}
|
}
|
||||||
@@ -171,4 +170,4 @@
|
|||||||
-1px 1px 0px black,
|
-1px 1px 0px black,
|
||||||
1px -1px 0px black;
|
1px -1px 0px black;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
@@ -328,8 +328,7 @@ body.movingUI .drawer-content,
|
|||||||
body.movingUI #expression-holder,
|
body.movingUI #expression-holder,
|
||||||
body.movingUI .zoomed_avatar,
|
body.movingUI .zoomed_avatar,
|
||||||
body.movingUI .draggable,
|
body.movingUI .draggable,
|
||||||
body.movingUI #floatingPrompt,
|
body.movingUI #floatingPrompt {
|
||||||
body.movingUI #groupMemberListPopout {
|
|
||||||
resize: both;
|
resize: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
min-height: 32px;
|
min-height: calc(var(--mainFontSize) + 13px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.delete_entry_button {
|
.delete_entry_button {
|
||||||
@@ -157,6 +157,37 @@
|
|||||||
width: 10em;
|
width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#world_info_search {
|
#world_info_search,
|
||||||
width: 10em;
|
#world_info_sort_order {
|
||||||
|
width: 7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wi-card-entry {
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: var(--SmartThemeBorderColor);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.world_entry {
|
||||||
|
transition: opacity 500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabledWIEntry {
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: grayscale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabledWIEntry:not(input):hover {
|
||||||
|
opacity: 1;
|
||||||
|
filter: grayscale(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.height32px {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.WIEntryHeaderTitleMobile {
|
||||||
|
display: none;
|
||||||
|
}
|
619
public/i18n.json
619
public/i18n.json
@@ -20,7 +20,7 @@
|
|||||||
"select": "选择 ",
|
"select": "选择 ",
|
||||||
"context size(tokens)": "上下文大小 (Toekns)",
|
"context size(tokens)": "上下文大小 (Toekns)",
|
||||||
"unlocked": "解锁",
|
"unlocked": "解锁",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "只有在选定的模型支持大于 2048 个Toekn 时可以选择启用,在启用该选项时,你应该知道自己在做什么。",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "只有在选定的模型支持大于 4096 个Toekn 时可以选择启用,在启用该选项时,你应该知道自己在做什么。",
|
||||||
"rep.pen": "频率惩罚",
|
"rep.pen": "频率惩罚",
|
||||||
"rep.pen range": "存在惩罚",
|
"rep.pen range": "存在惩罚",
|
||||||
"temperature": "温度设置",
|
"temperature": "温度设置",
|
||||||
@@ -70,6 +70,9 @@
|
|||||||
"Streaming": "流式响应",
|
"Streaming": "流式响应",
|
||||||
"Display the response bit by bit as it is generated.": "在生成响应时逐位显示响应。",
|
"Display the response bit by bit as it is generated.": "在生成响应时逐位显示响应。",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "关闭此选项后,响应将在完成后立即显示所有响应。",
|
"When this is off, responses will be displayed all at once when they are complete.": "关闭此选项后,响应将在完成后立即显示所有响应。",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "每个请求仅生成一行(仅限 KoboldAI,被 KoboldCpp 忽略)。",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "禁止序列结束 (EOS) 代币(使用 KoboldCpp,也可能使用 KoboldAI 禁止其他代币)。",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "适合故事写作,但不应用于聊天和指导模式。",
|
||||||
"Enhance Definitions": "增强定义",
|
"Enhance Definitions": "增强定义",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "使用 OpenAI 知识库增强公众人物和已知虚构人物的定义",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "使用 OpenAI 知识库增强公众人物和已知虚构人物的定义",
|
||||||
"Wrap in Quotes": "用引号包裹",
|
"Wrap in Quotes": "用引号包裹",
|
||||||
@@ -571,7 +574,7 @@
|
|||||||
"select": "選択 ",
|
"select": "選択 ",
|
||||||
"context size(tokens)": "コンテキストサイズ(トークン数)",
|
"context size(tokens)": "コンテキストサイズ(トークン数)",
|
||||||
"unlocked": "解除",
|
"unlocked": "解除",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "2048トークンより大きいコンテキストサイズをサポートするのは、一部のモデルのみです。このオプションを変更する前に、自分が何をしているかを理解してください。",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "4096トークンより大きいコンテキストサイズをサポートするのは、一部のモデルのみです。このオプションを変更する前に、自分が何をしているかを理解してください。",
|
||||||
"rep.pen": "Rep. Pen.",
|
"rep.pen": "Rep. Pen.",
|
||||||
"rep.pen range": "Rep. Pen. 範囲",
|
"rep.pen range": "Rep. Pen. 範囲",
|
||||||
"temperature": "温度",
|
"temperature": "温度",
|
||||||
@@ -620,6 +623,9 @@
|
|||||||
"Streaming": "ストリーミング",
|
"Streaming": "ストリーミング",
|
||||||
"Display the response bit by bit as it is generated.": "生成されると、レスポンスをビットごとに表示します。",
|
"Display the response bit by bit as it is generated.": "生成されると、レスポンスをビットごとに表示します。",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "これをオフにすると、レスポンスは完了時に一度にすべて表示されます。",
|
"When this is off, responses will be displayed all at once when they are complete.": "これをオフにすると、レスポンスは完了時に一度にすべて表示されます。",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "リクエストごとに 1 行のみ生成します (KoboldAI のみ、KoboldCpp では無視されます)。",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "End-of-Sequence (EOS) トークンを禁止します (KoboldCpp を使用し、場合によっては KoboldAI を使用する他のトークンも禁止します)。",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "ストーリーを書くのには適していますが、チャットや指示モードには使用しないでください。",
|
||||||
"Enhance Definitions": "定義を強化",
|
"Enhance Definitions": "定義を強化",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "公共人物および既知の架空のキャラクターの定義を強化するためにOAIの知識ベースを使用する",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "公共人物および既知の架空のキャラクターの定義を強化するためにOAIの知識ベースを使用する",
|
||||||
"Wrap in Quotes": "引用符で囲む",
|
"Wrap in Quotes": "引用符で囲む",
|
||||||
@@ -1122,7 +1128,7 @@
|
|||||||
"select": "선택",
|
"select": "선택",
|
||||||
"context size(tokens)": "맥락 크기(토큰수)",
|
"context size(tokens)": "맥락 크기(토큰수)",
|
||||||
"Unlocked Context Size": "한도 해제",
|
"Unlocked Context Size": "한도 해제",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "토큰 2049개 이상의 맥락을 사용할 수 있는 모델에서만 사용하세요. 파워유저 옵션이에요.",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "토큰 4096개 이상의 맥락을 사용할 수 있는 모델에서만 사용하세요. 파워유저 옵션이에요.",
|
||||||
"rep.pen": "반복 페널티",
|
"rep.pen": "반복 페널티",
|
||||||
"rep.pen range": "반복 페널티 범위",
|
"rep.pen range": "반복 페널티 범위",
|
||||||
"temperature": "온도",
|
"temperature": "온도",
|
||||||
@@ -1172,6 +1178,9 @@
|
|||||||
"Streaming": "스트리밍",
|
"Streaming": "스트리밍",
|
||||||
"Display the response bit by bit as it is generated.": "답변이 생성되는 도중 실시간으로 출력합니다.",
|
"Display the response bit by bit as it is generated.": "답변이 생성되는 도중 실시간으로 출력합니다.",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "이 옵션을 해지하면 답변이 완성된 다음 한 번에 출력합니다.",
|
"When this is off, responses will be displayed all at once when they are complete.": "이 옵션을 해지하면 답변이 완성된 다음 한 번에 출력합니다.",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "요청당 한 줄만 생성합니다(KoboldAI만 해당, KoboldCpp에서는 무시됨).",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "EOS(End-of-Sequence) 토큰(KoboldCpp 및 KoboldAI의 다른 토큰 포함)을 금지합니다.",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "스토리 작성에 적합하지만 채팅 및 교육 모드에는 사용하면 안 됩니다.",
|
||||||
"Enhance Definitions": "똑똑해지기",
|
"Enhance Definitions": "똑똑해지기",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "OpenAI 지식 데이터베이스를 활용하여 공공인물, 유명한 캐릭터 등 이미 알려진 정보를 사용합니다.",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "OpenAI 지식 데이터베이스를 활용하여 공공인물, 유명한 캐릭터 등 이미 알려진 정보를 사용합니다.",
|
||||||
"Wrap in Quotes": "자동 따옴표",
|
"Wrap in Quotes": "자동 따옴표",
|
||||||
@@ -1677,7 +1686,7 @@
|
|||||||
"select": "Выбрать",
|
"select": "Выбрать",
|
||||||
"context size(tokens)": "Размер контекста (в токенах)",
|
"context size(tokens)": "Размер контекста (в токенах)",
|
||||||
"unlocked": "Неограниченный",
|
"unlocked": "Неограниченный",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Только отдельные модели поддерживают контекст, превышающий 2048 токенов. Используйте только если понимаете, что делаете.",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Только отдельные модели поддерживают контекст, превышающий 4096 токенов. Используйте только если понимаете, что делаете.",
|
||||||
"rep.pen": "Rep. Pen.",
|
"rep.pen": "Rep. Pen.",
|
||||||
"rep.pen range": "Диапазон Rep. Pen.",
|
"rep.pen range": "Диапазон Rep. Pen.",
|
||||||
"temperature": "Температура",
|
"temperature": "Температура",
|
||||||
@@ -1739,6 +1748,9 @@
|
|||||||
"Streaming": "Потоковый вывод текста",
|
"Streaming": "Потоковый вывод текста",
|
||||||
"Display the response bit by bit as it is generated.": "Отображать ответ по кускам в процессе генерации.",
|
"Display the response bit by bit as it is generated.": "Отображать ответ по кускам в процессе генерации.",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "Если данная функция отключена, ответ будет отображен полностью после генерации.",
|
"When this is off, responses will be displayed all at once when they are complete.": "Если данная функция отключена, ответ будет отображен полностью после генерации.",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Генерируйте только одну строку для каждого запроса (только KoboldAI, игнорируется KoboldCpp).",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Запретите токен конца последовательности (EOS) (с помощью KoboldCpp и, возможно, также других токенов с помощью KoboldAI).",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "Подходит для написания историй, но не должен использоваться в режиме чата и инструктирования.",
|
||||||
"Enhance Definitions": "Улучшенная узнаваемость",
|
"Enhance Definitions": "Улучшенная узнаваемость",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Позволяет использовать базу знаний, улучшающую узнаваемость ИИ публичных лиц и вымышленных персонажей",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Позволяет использовать базу знаний, улучшающую узнаваемость ИИ публичных лиц и вымышленных персонажей",
|
||||||
"Wrap in Quotes": "Заключать в кавычки",
|
"Wrap in Quotes": "Заключать в кавычки",
|
||||||
@@ -2299,8 +2311,8 @@
|
|||||||
"response legth(tokens)": "lunghezza risposta (in Token)",
|
"response legth(tokens)": "lunghezza risposta (in Token)",
|
||||||
"select": "seleziona",
|
"select": "seleziona",
|
||||||
"context size(tokens)": "dimensione contesto (in Token)",
|
"context size(tokens)": "dimensione contesto (in Token)",
|
||||||
"unlocked": "sbloccato",
|
"unlocked": "Sblocca",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Seleziona il supporto ai modls soltanto se le dimenzioni contesto sono più grandi di 2048 token. Procedi soltanto se sai cosa stai facendo.",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Seleziona il supporto ai modls soltanto se le dimenzioni contesto sono più grandi di 4096 token. Procedi soltanto se sai cosa stai facendo.",
|
||||||
"rep.pen": "rep.pen",
|
"rep.pen": "rep.pen",
|
||||||
"rep.pen range": "rep.pen range",
|
"rep.pen range": "rep.pen range",
|
||||||
"temperature": "temperature",
|
"temperature": "temperature",
|
||||||
@@ -2330,7 +2342,7 @@
|
|||||||
"Typical P": "Typical P",
|
"Typical P": "Typical P",
|
||||||
"Do Sample": "Do Sample",
|
"Do Sample": "Do Sample",
|
||||||
"Add BOS Token": "Aggiungi BOS Token",
|
"Add BOS Token": "Aggiungi BOS Token",
|
||||||
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Aggiungi bos_token all'inizio di un prompt. Disabilitarlo potrebbe rendere le risposte più creative.",
|
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Aggiungi bos_token all'inizio di un prompt. Disattivarlo potrebbe rendere le risposte più creative.",
|
||||||
"Ban EOS Token": "Blocca EOS Token",
|
"Ban EOS Token": "Blocca EOS Token",
|
||||||
"Ban the eos_token. This forces the model to never end the generation prematurely": "Blocca eos_token. Questo costringe il modello a non concludere prematuramente la generazione del testo.",
|
"Ban the eos_token. This forces the model to never end the generation prematurely": "Blocca eos_token. Questo costringe il modello a non concludere prematuramente la generazione del testo.",
|
||||||
"Skip Special Tokens": "Salta Token speciali",
|
"Skip Special Tokens": "Salta Token speciali",
|
||||||
@@ -2350,6 +2362,9 @@
|
|||||||
"Streaming": "Streaming",
|
"Streaming": "Streaming",
|
||||||
"Display the response bit by bit as it is generated.": "Mostra la risposta mano a mano che viene generata.",
|
"Display the response bit by bit as it is generated.": "Mostra la risposta mano a mano che viene generata.",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "Quando questa casella è disattivata, le risposte vengono mostrate soltanto una volta che il testo è stato ultimato.",
|
"When this is off, responses will be displayed all at once when they are complete.": "Quando questa casella è disattivata, le risposte vengono mostrate soltanto una volta che il testo è stato ultimato.",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genera solo una riga per richiesta (solo KoboldAI, ignorata da KoboldCpp).",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Bandire il token End-of-Sequence (EOS) (con KoboldCpp, ed eventualmente anche altri token con KoboldAI).",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "Buono per scrivere storie, ma non dovrebbe essere usato per la modalità chat e istruzioni.",
|
||||||
"Enhance Definitions": "Migliora le definizioni",
|
"Enhance Definitions": "Migliora le definizioni",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa la conoscenza di OpenAI per migliorare le definizioni di personaggi pubblici e personaggi immaginari famosi.",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa la conoscenza di OpenAI per migliorare le definizioni di personaggi pubblici e personaggi immaginari famosi.",
|
||||||
"Wrap in Quotes": "Invia i messaggi tra virgolette",
|
"Wrap in Quotes": "Invia i messaggi tra virgolette",
|
||||||
@@ -2364,7 +2379,7 @@
|
|||||||
"Impersonation prompt": "Prompt per l'impersonificazione dell'utente",
|
"Impersonation prompt": "Prompt per l'impersonificazione dell'utente",
|
||||||
"Prompt that is used for Impersonation function": "Prompt utilizzato per la funzione di impersonificazione dell'utente",
|
"Prompt that is used for Impersonation function": "Prompt utilizzato per la funzione di impersonificazione dell'utente",
|
||||||
"Logit Bias": "Logit Bias",
|
"Logit Bias": "Logit Bias",
|
||||||
"Helps to ban or reenforce the usage of certain words": "Aiuta a bloccare o rinforzare l'utilizzo di alcuni tipi di parole.",
|
"Helps to ban or reenforce the usage of certain words": "Aiuta a disincentivare o rinforzare l'utilizzo di alcuni tipi di parole.",
|
||||||
"View / Edit bias preset": "Mostra / Modifica bias preset",
|
"View / Edit bias preset": "Mostra / Modifica bias preset",
|
||||||
"Add bias entry": "Aggiungi voce bias",
|
"Add bias entry": "Aggiungi voce bias",
|
||||||
"Jailbreak activation message": "Messaggio d'attivazione del Jailbreak",
|
"Jailbreak activation message": "Messaggio d'attivazione del Jailbreak",
|
||||||
@@ -2378,7 +2393,7 @@
|
|||||||
"Use Horde": "Usa Horde",
|
"Use Horde": "Usa Horde",
|
||||||
"API url": "Url API",
|
"API url": "Url API",
|
||||||
"Register a Horde account for faster queue times": "Crea un account Horde per tempi di attesa più brevi",
|
"Register a Horde account for faster queue times": "Crea un account Horde per tempi di attesa più brevi",
|
||||||
"Learn how to contribute your idle GPU cycles to the Hord": "Impara come fare in modo di usare i tuoi cicli GPU in idle per contribuire a Horde",
|
"Learn how to contribute your idle GPU cycles to the Hord": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
|
||||||
"Adjust context size to worker capabilities": "Sistema la grandezza del contesto alle sue capacità operazionali",
|
"Adjust context size to worker capabilities": "Sistema la grandezza del contesto alle sue capacità operazionali",
|
||||||
"Adjust response length to worker capabilities": "Sistema la lunghezza della risposta alle sue capacità operazionali",
|
"Adjust response length to worker capabilities": "Sistema la lunghezza della risposta alle sue capacità operazionali",
|
||||||
"API key": "Chiave API",
|
"API key": "Chiave API",
|
||||||
@@ -2391,15 +2406,17 @@
|
|||||||
"Novel API key": "NovelAI API key",
|
"Novel API key": "NovelAI API key",
|
||||||
"Follow": "Segui",
|
"Follow": "Segui",
|
||||||
"these directions": "questi suggerimenti",
|
"these directions": "questi suggerimenti",
|
||||||
"to get your NovelAI API key.": "per acquisire la chiave API di NovelAI.",
|
"to get your NovelAI API key.": "per ottenere la chiave API di NovelAI.",
|
||||||
"Enter it in the box below": "Inserisci la chiave all'interno della casella qui sotto",
|
"Enter it in the box below": "Inserisci la chiave all'interno della casella qui sotto",
|
||||||
"Novel AI Model": "Modello di NovelAI",
|
"Novel AI Model": "Modello di NovelAI",
|
||||||
|
"Euterpe": "Euterpe",
|
||||||
|
"Krake": "Krake",
|
||||||
"No connection": "Nessuna connessione",
|
"No connection": "Nessuna connessione",
|
||||||
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
|
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
|
||||||
"Make sure you run it with": "assicurati di farlo partire con",
|
"Make sure you run it with": "assicurati di farlo partire con",
|
||||||
"Blocking API url": "Bloccare l'indirizzo API",
|
"Blocking API url": "Blocca l'indirizzo API",
|
||||||
"Streaming API url": "Streaming dell'indirizzo API",
|
"Streaming API url": "Streaming dell'indirizzo API",
|
||||||
"to get your OpenAI API key.": "per acquisire la tua chiave API di OpenAI.",
|
"to get your OpenAI API key.": "per ottenere la tua chiave API di OpenAI.",
|
||||||
"OpenAI Model": "Modello di OpenAI",
|
"OpenAI Model": "Modello di OpenAI",
|
||||||
"View API Usage Metrics": "Mostra le metriche di utilizzo delle API",
|
"View API Usage Metrics": "Mostra le metriche di utilizzo delle API",
|
||||||
"Bot": "Bot",
|
"Bot": "Bot",
|
||||||
@@ -2408,14 +2425,14 @@
|
|||||||
"View hidden API keys": "Mostra le chiavi API nascoste",
|
"View hidden API keys": "Mostra le chiavi API nascoste",
|
||||||
"Advanced Formatting": "Formattazione avanzata",
|
"Advanced Formatting": "Formattazione avanzata",
|
||||||
"AutoFormat Overrides": "Sovrascrittura AutoFormat",
|
"AutoFormat Overrides": "Sovrascrittura AutoFormat",
|
||||||
"Disable description formatting": "Disabilita la formattazione della descrizione",
|
"Disable description formatting": "Disattiva la formattazione della descrizione",
|
||||||
"Disable personality formatting": "Disabilita la formattazione della personalità",
|
"Disable personality formatting": "Disattiva la formattazione della personalità",
|
||||||
"Disable scenario formatting": "Disabilita la formattazione dello scenario",
|
"Disable scenario formatting": "Disattiva la formattazione dello scenario",
|
||||||
"Disable example chats formatting": "Disabilita la formattazione degli esempi di chat",
|
"Disable example chats formatting": "Disattiva la formattazione degli esempi di chat",
|
||||||
"Disable chat start formatting": "Disabilita la formattazione della chat iniziale",
|
"Disable chat start formatting": "Disattiva la formattazione della chat iniziale",
|
||||||
"Custom Chat Separator": "Separatore di chat personalizzato",
|
"Custom Chat Separator": "Separatore di chat personalizzato",
|
||||||
"Instruct mode": "Modalità istruzione",
|
"Instruct mode": "Modalità istruzione",
|
||||||
"Enabled": "Abilita",
|
"Enabled": "Attiva",
|
||||||
"Wrap Sequences with Newline": "Ogni sequenza viene rimandata a capo",
|
"Wrap Sequences with Newline": "Ogni sequenza viene rimandata a capo",
|
||||||
"Include Names": "Includi i nomi",
|
"Include Names": "Includi i nomi",
|
||||||
"System Prompt": "Prompt di sistema",
|
"System Prompt": "Prompt di sistema",
|
||||||
@@ -2432,11 +2449,15 @@
|
|||||||
"Sentencepiece (LLaMA)": "Sentencepiece (LLaMA)",
|
"Sentencepiece (LLaMA)": "Sentencepiece (LLaMA)",
|
||||||
"Token Padding": "Token Padding",
|
"Token Padding": "Token Padding",
|
||||||
"Always add character's name to prompt": "Aggiungi sempre il nome del personaggio al prompt",
|
"Always add character's name to prompt": "Aggiungi sempre il nome del personaggio al prompt",
|
||||||
"Keep Example Messages in Prompt": "Mantieni i messaggi d'esempio nel Prompt",
|
"Keep Example Messages in Prompt": "Mantieni i messaggi d'esempio dal prompt",
|
||||||
"Remove Empty New Lines from Output": "Rimuovi le linee di testo vuote dall'output",
|
"Remove Empty New Lines from Output": "Rimuovi le linee di testo vuote dall'output",
|
||||||
"Disabled for all models": "Disabilita per tutti i modelli",
|
"Pygmalion Formatting": "Formattazione Pygmalion",
|
||||||
|
"Disabled for all models": "Disattiva per tutti i modelli",
|
||||||
"Automatic (based on model name)": "Automatico (basato sul nome del modello)",
|
"Automatic (based on model name)": "Automatico (basato sul nome del modello)",
|
||||||
"Enabled for all models": "Abilita per tutti i modelli",
|
"Enabled for all models": "Attiva per tutti i modelli",
|
||||||
|
"Multigen": "Multigen",
|
||||||
|
"First chunk (tokens)": "Primo pacchetto (in Token)",
|
||||||
|
"Next chunks (tokens)": "Pacchetto successivo (in Token)",
|
||||||
"Anchors Order": "Anchors Order",
|
"Anchors Order": "Anchors Order",
|
||||||
"Character then Style": "Prima il personaggio, successivamente lo stile",
|
"Character then Style": "Prima il personaggio, successivamente lo stile",
|
||||||
"Style then Character": "Prima lo stile, successivamente il personaggio",
|
"Style then Character": "Prima lo stile, successivamente il personaggio",
|
||||||
@@ -2452,35 +2473,35 @@
|
|||||||
"About soft prompts": "Riguardo i prompt leggeri",
|
"About soft prompts": "Riguardo i prompt leggeri",
|
||||||
"None": "None",
|
"None": "None",
|
||||||
"User Settings": "Settaggi utente",
|
"User Settings": "Settaggi utente",
|
||||||
"UI Customization": "Personalizzazione dell'interfaccia grafica",
|
"UI Customization": "Personalizzazione UI",
|
||||||
"Avatar Style": "Stile dell'avatar",
|
"Avatar Style": "Stile avatar",
|
||||||
"Circle": "Cerchio",
|
"Circle": "Cerchio",
|
||||||
"Rectangle": "Rettangolo",
|
"Rectangle": "Rettangolo",
|
||||||
"Chat Style": "Stile della Chat",
|
"Chat Style": "Stile della Chat",
|
||||||
"Default": "Predefinito",
|
"Default": "Predefinito",
|
||||||
"Bubbles": "Bolle",
|
"Bubbles": "Bolle",
|
||||||
"Chat Width (PC)": "Lunghezza della chat (PC)",
|
"Chat Width (PC)": "Lunghezza della chat (PC)",
|
||||||
"No Blur Effect": "Nessun effetto di sfocatura",
|
"No Blur Effect": "Nessun effetto sfocatura",
|
||||||
"No Text Shadows": "Nessuna ombreggiatura del testo",
|
"No Text Shadows": "Nessuna ombreggiatura testo",
|
||||||
"Waifu Mode": "♡ Modalità Waifu ♡",
|
"Waifu Mode": "♡ Modalità Waifu ♡",
|
||||||
"Message Timer": "Timer del messaggio",
|
"Message Timer": "Timer messaggio",
|
||||||
"Characters Hotswap": "Hotswap dei personaggi",
|
"Characters Hotswap": "Hotswap personaggi",
|
||||||
"Movable UI Panels": "Pannelli dell'interfaccia grafica movibili",
|
"Movable UI Panels": "Pannelli UI movibili",
|
||||||
"Reset Panels": "Ripristina i pannelli",
|
"Reset Panels": "Ripristina i pannelli",
|
||||||
"UI Colors": "Colori UI",
|
"UI Colors": "Colori UI",
|
||||||
"Main Text": "Testo principale",
|
"Main Text": "Testo principale",
|
||||||
"Italics Text": "Testo in Italic",
|
"Italics Text": "Testo in Italic",
|
||||||
"Quote Text": "Testo citato",
|
"Quote Text": "Testo citato",
|
||||||
"Shadow Color": "Colore dell'ombreggiatura",
|
"Shadow Color": "Colore ombreggiatura",
|
||||||
"FastUI BG": "FastUI BG",
|
"FastUI BG": "FastUI BG",
|
||||||
"Blur Tint": "Tinta della sfocatura",
|
"Blur Tint": "Tinta sfocatura",
|
||||||
"Font Scale": "Grandezza del font",
|
"Font Scale": "Grandezza font",
|
||||||
"Blur Strength": "Intensità della sfocatura",
|
"Blur Strength": "Intensità sfocatura",
|
||||||
"Text Shadow Width": "Larghezza dell'ombreggiatura del testo",
|
"Text Shadow Width": "Larghezza ombreggiatura testo",
|
||||||
"UI Theme Preset": "Tema dell'interfaccia grafica",
|
"UI Theme Preset": "Tema UI",
|
||||||
"Power User Options": "Opzioni Power User",
|
"Power User Options": "Opzioni utente avanzate",
|
||||||
"Swipes": "Swipes",
|
"Swipes": "Swipes",
|
||||||
"Background Sound Only": "Soltanto il suono di background",
|
"Background Sound Only": "Soltanto suono di background",
|
||||||
"Auto-load Last Chat": "Carica automaticamente l'ultima chat",
|
"Auto-load Last Chat": "Carica automaticamente l'ultima chat",
|
||||||
"Auto-save Message Edits": "Salva automaticamente i messaggi editati",
|
"Auto-save Message Edits": "Salva automaticamente i messaggi editati",
|
||||||
"Auto-fix Markdown": "Correggi automaticamente il testo per la formattazione in Markdown",
|
"Auto-fix Markdown": "Correggi automaticamente il testo per la formattazione in Markdown",
|
||||||
@@ -2488,13 +2509,13 @@
|
|||||||
"Allow {{user}}: in bot messages": "Permetti {{user}}: nei messaggi del bot",
|
"Allow {{user}}: in bot messages": "Permetti {{user}}: nei messaggi del bot",
|
||||||
"Auto-scroll Chat": "scorrimento automatico della chat",
|
"Auto-scroll Chat": "scorrimento automatico della chat",
|
||||||
"Render Formulas": "Renderizza le formule",
|
"Render Formulas": "Renderizza le formule",
|
||||||
"Send on Enter": "Inviare premendo Invio",
|
"Send on Enter": "Inoltrare premendo Invio",
|
||||||
"Always disabled": "Sempre disabilitato",
|
"Always disabled": "Sempre disattivato",
|
||||||
"Automatic (desktop)": "Automatico (desktop)",
|
"Automatic (desktop)": "Automatico (desktop)",
|
||||||
"Always enabled": "Sempre abilitato",
|
"Always enabled": "Sempre attivato",
|
||||||
"Name": "Nome",
|
"Name": "Nome",
|
||||||
"Your Avatar": "Il tuo avatar",
|
"Your Avatar": "Il tuo avatar",
|
||||||
"Extensions API:": "Estensioni delle API:",
|
"Extensions API:": "Estensioni API aggiuntive:",
|
||||||
"SillyTavern-extras": "SillyTavern-extras",
|
"SillyTavern-extras": "SillyTavern-extras",
|
||||||
"Auto-connect": "Connessione automatica",
|
"Auto-connect": "Connessione automatica",
|
||||||
"Active extensions": "Estensione attiva",
|
"Active extensions": "Estensione attiva",
|
||||||
@@ -2504,8 +2525,8 @@
|
|||||||
"Group Controls": "Controlli del gruppo",
|
"Group Controls": "Controlli del gruppo",
|
||||||
"Group reply strategy": "Organizzazione per le risposte del gruppo",
|
"Group reply strategy": "Organizzazione per le risposte del gruppo",
|
||||||
"Natural order": "Ordine naturale",
|
"Natural order": "Ordine naturale",
|
||||||
"List order": "Lista dell'ordine",
|
"List order": "Ordine lista",
|
||||||
"Allow self responses": "Permetti la risposta automatica",
|
"Allow self responses": "Permetti risposta automatica",
|
||||||
"Auto Mode": "Modalità automatica",
|
"Auto Mode": "Modalità automatica",
|
||||||
"Add Members": "Aggiungi membri",
|
"Add Members": "Aggiungi membri",
|
||||||
"Current Members": "Membri correnti",
|
"Current Members": "Membri correnti",
|
||||||
@@ -2546,7 +2567,7 @@
|
|||||||
"After Char": "Dopo Char",
|
"After Char": "Dopo Char",
|
||||||
"Insertion Order": "Ordine di inserimento",
|
"Insertion Order": "Ordine di inserimento",
|
||||||
"Tokens:": "Token",
|
"Tokens:": "Token",
|
||||||
"Disable": "Disabilita",
|
"Disable": "Disattiva",
|
||||||
"${characterName}": "${nomePersonaggio}",
|
"${characterName}": "${nomePersonaggio}",
|
||||||
"CHAR": "CHAR",
|
"CHAR": "CHAR",
|
||||||
"is typing": "sta scrivendo...",
|
"is typing": "sta scrivendo...",
|
||||||
@@ -2560,6 +2581,7 @@
|
|||||||
"Regenerate": "Rigenera",
|
"Regenerate": "Rigenera",
|
||||||
"PNG": "PNG",
|
"PNG": "PNG",
|
||||||
"JSON": "JSON",
|
"JSON": "JSON",
|
||||||
|
"WEBP": "WEBP",
|
||||||
"presets": "preset",
|
"presets": "preset",
|
||||||
"Message Sound": "Suono del messaggio",
|
"Message Sound": "Suono del messaggio",
|
||||||
"Author's Note": "Note d'autore",
|
"Author's Note": "Note d'autore",
|
||||||
@@ -2567,21 +2589,21 @@
|
|||||||
"Replace empty message": "Sostituisci i messaggi vuoti",
|
"Replace empty message": "Sostituisci i messaggi vuoti",
|
||||||
"Send this text instead of nothing when the text box is empty.": "Quando il campo di testo è vuoto, invia invece questo messaggio.",
|
"Send this text instead of nothing when the text box is empty.": "Quando il campo di testo è vuoto, invia invece questo messaggio.",
|
||||||
"NSFW avoidance prompt": "NSFW avoidance prompt",
|
"NSFW avoidance prompt": "NSFW avoidance prompt",
|
||||||
"Prompt that is used when the NSFW toggle is off": "Prompt utilizzato quando la casella NSFW è disabilitata.",
|
"Prompt that is used when the NSFW toggle is off": "Prompt utilizzato quando la casella NSFW è disattivata.",
|
||||||
"Advanced prompt bits": "Advanced prompt bits",
|
"Advanced prompt bits": "Advanced prompt bits",
|
||||||
"World Info format template": "Formattazione del modello 'Info Mondo'",
|
"World Info format template": "Formato template 'Info Mondo'",
|
||||||
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "Seleziona le informazioni del mondo attualmente attive prima di inserirle nel prompt. Usa {0} per segnalare dove vuoi che il contenuto venga inserito all'interno del prompt.",
|
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "Seleziona le informazioni del mondo attualmente attive prima di inserirle nel prompt. Usa {0} per segnalare dove vuoi che il contenuto venga inserito all'interno del prompt.",
|
||||||
"Unrestricted maximum value for the context slider": "Valore massimo illimitato per la grandezza del contesto.",
|
"Unrestricted maximum value for the context slider": "Valore massimo illimitato per la grandezza del contesto.",
|
||||||
"Chat Completion Source": "Sorgente IA per la Chat",
|
"Chat Completion Source": "Sorgente IA per la Chat",
|
||||||
"Avoid sending sensitive information to the Horde.": "Evita di inviare informazioni sensibili e personali a Horde",
|
"Avoid sending sensitive information to the Horde.": "Evita di inviare informazioni sensibili e personali a Horde",
|
||||||
"Review the Privacy statement": "Leggi l'informativa sulla privacy",
|
"Review the Privacy statement": "Leggi l'informativa sulla privacy",
|
||||||
"Learn how to contribute your idel GPU cycles to the Horde": "Impara come fare in modo di usare i tuoi cicli GPU in idle per contribuire a Horde",
|
"Learn how to contribute your idel GPU cycles to the Horde": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
|
||||||
"Trusted workers only": "Utilizza solo utenti di fiducia",
|
"Trusted workers only": "Utilizza solo utenti di fiducia",
|
||||||
"For privacy reasons, your API key will be hidden after you reload the page.": "Per motivi di sicurezza la tua chiave API verrà oscurata dopo aver ricaricato la pagina.",
|
"For privacy reasons, your API key will be hidden after you reload the page.": "Per motivi di sicurezza la tua chiave API verrà oscurata dopo aver ricaricato la pagina.",
|
||||||
"-- Horde models not loaded --": "-- Modelli Horde non caricati --",
|
"-- Horde models not loaded --": "-- Modelli Horde non caricati --",
|
||||||
"Example: http://127.0.0.1:5000/api ": "Esempio: http://127.0.0.1:5000/api",
|
"Example: http://127.0.0.1:5000/api ": "Esempio: http://127.0.0.1:5000/api",
|
||||||
"No connection...": "Nessuna connessione",
|
"No connection...": "Nessuna connessione",
|
||||||
"Get your NovelAI API Key": "Acquisici la chiave API per NovelAI",
|
"Get your NovelAI API Key": "Ottieni la chiave API per NovelAI",
|
||||||
"KoboldAI Horde": "KoboldAI Horde",
|
"KoboldAI Horde": "KoboldAI Horde",
|
||||||
"Text Gen WebUI (ooba)": "Text Gen WebUI (ooba)",
|
"Text Gen WebUI (ooba)": "Text Gen WebUI (ooba)",
|
||||||
"NovelAI": "NovelAI",
|
"NovelAI": "NovelAI",
|
||||||
@@ -2595,7 +2617,7 @@
|
|||||||
"Presets": "Preset",
|
"Presets": "Preset",
|
||||||
"Separator": "Separatore",
|
"Separator": "Separatore",
|
||||||
"Start Reply With": "Inizia la risposta con",
|
"Start Reply With": "Inizia la risposta con",
|
||||||
"Show reply prefix in chat": "Mostra il prefix di risposta nella chat",
|
"Show reply prefix in chat": "Mostra il prefisso della risposta nella chat",
|
||||||
"Worlds/Lorebooks": "Mondi/Lorebook",
|
"Worlds/Lorebooks": "Mondi/Lorebook",
|
||||||
"Active World(s)": "Mondi Attivi",
|
"Active World(s)": "Mondi Attivi",
|
||||||
"Character Lore Insertion Strategy": "Strategia per l'inserimento della lore all'interno del contesto dell'IA",
|
"Character Lore Insertion Strategy": "Strategia per l'inserimento della lore all'interno del contesto dell'IA",
|
||||||
@@ -2619,40 +2641,40 @@
|
|||||||
"Order:": "Ordine",
|
"Order:": "Ordine",
|
||||||
"Probability:": "Probabilità:",
|
"Probability:": "Probabilità:",
|
||||||
"Delete Entry": "Elimina Voce",
|
"Delete Entry": "Elimina Voce",
|
||||||
"User Message Blur Tint": "Sfocatura tinta per i messaggi dell'utente",
|
"User Message Blur Tint": "Sfocatura sfondo utente",
|
||||||
"AI Message Blur Tint": "Sfocatura tinta per i messaggi dell'IA",
|
"AI Message Blur Tint": "Sfocatura sfondo IA",
|
||||||
"Chat Style:": "Stile Chat",
|
"Chat Style:": "Stile Chat",
|
||||||
"Chat Width (PC):": "Larghezza riquadro chat (PC)",
|
"Chat Width (PC):": "Larghezza riquadro chat (PC)",
|
||||||
"Chat Timestamps": "Timestamp della chat",
|
"Chat Timestamps": "Timestamp della chat",
|
||||||
"Message IDs": "ID del Messaggio",
|
"Message IDs": "ID del Messaggio",
|
||||||
"Prefer Character Card Prompt": "Prompt preferito per la 'Carta Personaggio'",
|
"Prefer Character Card Prompt": "Priorità prompt 'Carta Personaggio'",
|
||||||
"Prefer Character Card Jailbreak": "Jailbreak preferito per la 'Carta Personaggio'",
|
"Prefer Character Card Jailbreak": "Priorità jailbreak 'Carta Personaggio'",
|
||||||
"Press Send to continue": "Premi Invio per continuare",
|
"Press Send to continue": "Premi Invio per continuare",
|
||||||
"Log prompts to console": "Registro prompt a console",
|
"Log prompts to console": "Registro prompt a console",
|
||||||
"Never resize avatars": "Non ridimensionare mai l'avatar",
|
"Never resize avatars": "Non ridimensionare mai l'avatar",
|
||||||
"Show avatar filenames": "Mostra il nome del file dell'avatar",
|
"Show avatar filenames": "Mostra il nome del file dell'avatar",
|
||||||
"Import Card Tags": "Importa i tag della carta",
|
"Import Card Tags": "Importa i tag della carta",
|
||||||
"Confirm message deletion": "Conferma l'eliminazione del messaggio",
|
"Confirm message deletion": "Conferma l'eliminazione del messaggio",
|
||||||
"Spoiler Free Mode": "Modalità Spoiler Free",
|
"Spoiler Free Mode": "Modalità spoiler free",
|
||||||
"Auto-swipe": "Auto-swipe",
|
"Auto-swipe": "Auto-swipe",
|
||||||
"Minimum generated message length": "Lunghezza minima per i messaggi generati",
|
"Minimum generated message length": "Lunghezza minima per i messaggi generati",
|
||||||
"Blacklisted words": "Parole nella lista nera",
|
"Blacklisted words": "Parole nella lista nera",
|
||||||
"Blacklisted word count to swipe": "Numero delle parole nella lista nera",
|
"Blacklisted word count to swipe": "Numero delle parole nella lista nera",
|
||||||
"Reload Chat": "Ricarica la chat",
|
"Reload Chat": "Ricarica la chat",
|
||||||
"Not Connected": "Non connesso",
|
"Not Connected": "Non connesso",
|
||||||
"Persona Management": "Gestione della proprio alterego",
|
"Persona Management": "Gestione del proprio alter ego",
|
||||||
"Persona Description": "Descrizione dell'alterego",
|
"Persona Description": "Descrizione alter ego",
|
||||||
"Before Character Card": "Prima della 'Carta Personaggio'",
|
"Before Character Card": "Prima della 'Carta Personaggio'",
|
||||||
"After Character Card": "Dopo la 'Carta Personaggio'",
|
"After Character Card": "Dopo la 'Carta Personaggio'",
|
||||||
"Top of Author's Note": "Inizio delle note d'autore",
|
"Top of Author's Note": "All'inizio delle note d'autore",
|
||||||
"Bottom of Author's Note": "Fine delle note d'autore",
|
"Bottom of Author's Note": "Alla fine delle note d'autore",
|
||||||
"How do I use this?": "Cos'è e cosa posso farci?",
|
"How do I use this?": "Cos'è e cosa posso farci?",
|
||||||
"More...": "Mostra di più...",
|
"More...": "Mostra di più...",
|
||||||
"Link to World Info": "Collegamento alle 'Info Mondo'",
|
"Link to World Info": "Collegamento 'Info Mondo'",
|
||||||
"Import Card Lore": "Importa la storia dell carta",
|
"Import Card Lore": "Importa la storia dell carta",
|
||||||
"Scenario Override": "Sovrascrizione dello scenario",
|
"Scenario Override": "Sovrascrittura dello scenario",
|
||||||
"Rename": "Rinomina",
|
"Rename": "Rinomina",
|
||||||
"Character Description": "Descrizione del personaggio",
|
"Character Description": "Descrizione personaggio",
|
||||||
"Creator's Notes": "Note del Creatore",
|
"Creator's Notes": "Note del Creatore",
|
||||||
"A-Z": "A-Z",
|
"A-Z": "A-Z",
|
||||||
"Z-A": "Z-A",
|
"Z-A": "Z-A",
|
||||||
@@ -2667,13 +2689,13 @@
|
|||||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserisci {{original}} all'intero della casella per includere i rispettivi prompt predefiniti dai settaggi di sistema.",
|
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserisci {{original}} all'intero della casella per includere i rispettivi prompt predefiniti dai settaggi di sistema.",
|
||||||
"Main Prompt": "Prompt Principale",
|
"Main Prompt": "Prompt Principale",
|
||||||
"Jailbreak": "Jailbreak",
|
"Jailbreak": "Jailbreak",
|
||||||
"Creator's Metadata (Not sent with the AI prompt)": "Metadata del creatore (Non viene inviata all'IA)",
|
"Creator's Metadata (Not sent with the AI prompt)": "Metadata del creatore (Non viene inviato all'IA)",
|
||||||
"Everything here is optional": "Tutto ciò che si trova qui è opzionale",
|
"Everything here is optional": "Tutto ciò che si trova qui è opzionale",
|
||||||
"Created by": "Creato da",
|
"Created by": "Creato da",
|
||||||
"Character Version": "Versione del personaggio",
|
"Character Version": "Versione del personaggio",
|
||||||
"Tags to Embed": "Tag da incorporare",
|
"Tags to Embed": "Tag da incorporare",
|
||||||
"How often the character speaks in group chats!": "La frequenza con la quale il personaggio parla all'interno delle chat di gruppo!",
|
"How often the character speaks in group chats!": "La frequenza con la quale il personaggio parla all'interno delle chat di gruppo!",
|
||||||
"Important to set the character's writing style.": "Esso è importante per impostare lo stile di scrittura del personaggio",
|
"Important to set the character's writing style.": "È importante per impostare lo stile di scrittura del personaggio",
|
||||||
"ATTENTION!": "ATTENZIONE!",
|
"ATTENTION!": "ATTENZIONE!",
|
||||||
"Samplers Order": "Ordine dei campionatori",
|
"Samplers Order": "Ordine dei campionatori",
|
||||||
"Samplers will be applied in a top-down order. Use with caution.": "L'ordine dei campioni va dall'alto verso il basso. Usalo con cautela.",
|
"Samplers will be applied in a top-down order. Use with caution.": "L'ordine dei campioni va dall'alto verso il basso. Usalo con cautela.",
|
||||||
@@ -2697,9 +2719,9 @@
|
|||||||
"Enter your name": "Inserisci il tuo nome",
|
"Enter your name": "Inserisci il tuo nome",
|
||||||
"Name this character": "Dai un nome a questo personaggio",
|
"Name this character": "Dai un nome a questo personaggio",
|
||||||
"Search / Create Tags": "Cerca / Crea tag",
|
"Search / Create Tags": "Cerca / Crea tag",
|
||||||
"Describe your character's physical and mental traits here.": "Descrivi qui le caratteristiche fisiche e psicologiche del tuo personaggio.",
|
"Describe your character's physical and mental traits here.": "Descrivi le caratteristiche fisiche e psicologiche del tuo personaggio.",
|
||||||
"This will be the first message from the character that starts every chat.": "Questo sarà il primo messaggio che il personaggio utilizzerà all'inizio di ogni chat.",
|
"This will be the first message from the character that starts every chat.": "Questo sarà il primo messaggio che il personaggio utilizzerà all'inizio di ogni chat.",
|
||||||
"Chat Name (Optional)": "Nome della chat(Opzionale)",
|
"Chat Name (Optional)": "Nome della chat (opzionale)",
|
||||||
"Filter...": "Filtro...",
|
"Filter...": "Filtro...",
|
||||||
"Search...": "Cerca...",
|
"Search...": "Cerca...",
|
||||||
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "Ogni elemento racchiuso qui dentro sostituirà il prompt principale predefinito usato da questo personaggio. (v2 spec: system_prompt)",
|
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "Ogni elemento racchiuso qui dentro sostituirà il prompt principale predefinito usato da questo personaggio. (v2 spec: system_prompt)",
|
||||||
@@ -2709,7 +2731,7 @@
|
|||||||
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "(Descrivi il bot, scrivi dei suggerimenti o informa riguardo i modelli IA su cui è stato testato. Questo verrà mostrato nella lista personaggio)",
|
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "(Descrivi il bot, scrivi dei suggerimenti o informa riguardo i modelli IA su cui è stato testato. Questo verrà mostrato nella lista personaggio)",
|
||||||
"(Write a comma-separated list of tags)": "(Scrivi una lista di tag separati dalle virgole)",
|
"(Write a comma-separated list of tags)": "(Scrivi una lista di tag separati dalle virgole)",
|
||||||
"(A brief description of the personality)": "(Scrivi una breve descrizione della sua personalità)",
|
"(A brief description of the personality)": "(Scrivi una breve descrizione della sua personalità)",
|
||||||
"(Circumstances and context of the interaction)": "(Scrivi le circostanze e il contesto della scena)",
|
"(Circumstances and context of the interaction)": "(Scrivi le circostanze e il contesto dello scenario)",
|
||||||
"(Examples of chat dialog. Begin each example with START on a new line.)": "(Esempi di dialogo. Inizia ogni esempio con START quando vai a capo.)",
|
"(Examples of chat dialog. Begin each example with START on a new line.)": "(Esempi di dialogo. Inizia ogni esempio con START quando vai a capo.)",
|
||||||
"Injection text (supports parameters)": "Injection text (supporta i parametri)",
|
"Injection text (supports parameters)": "Injection text (supporta i parametri)",
|
||||||
"Injection depth": "Profondità dell'Injection",
|
"Injection depth": "Profondità dell'Injection",
|
||||||
@@ -2722,14 +2744,14 @@
|
|||||||
"Not connected to API!": "Non connesso a nessuna API!",
|
"Not connected to API!": "Non connesso a nessuna API!",
|
||||||
"AI Response Configuration": "Configurazione della risposta dell'IA",
|
"AI Response Configuration": "Configurazione della risposta dell'IA",
|
||||||
"AI Configuration panel will stay open": "Se clicchi il lucchetto, il pannello di configurazione dell'IA rimarrà aperto",
|
"AI Configuration panel will stay open": "Se clicchi il lucchetto, il pannello di configurazione dell'IA rimarrà aperto",
|
||||||
"Update current preset": "Aggiorna il preset corrente",
|
"Update current preset": "Aggiorna preset corrente",
|
||||||
"Create new preset": "Crea un nuovo preset",
|
"Create new preset": "Crea un nuovo preset",
|
||||||
"Import preset": "Importa preset",
|
"Import preset": "Importa preset",
|
||||||
"Export preset": "Esporta preset",
|
"Export preset": "Esporta preset",
|
||||||
"Delete the preset": "Cancella il preset",
|
"Delete the preset": "Cancella preset",
|
||||||
"Inserts jailbreak as a last system message": "Inserisci il Jailbreak come ultimo messaggio del sistema",
|
"Inserts jailbreak as a last system message": "Inserisci il Jailbreak come ultimo messaggio del sistema",
|
||||||
"NSFW block goes first in the resulting prompt": "Il blocco al contenuto NSFW spunterà per primo nel prompt corrente",
|
"NSFW block goes first in the resulting prompt": "Il blocco al contenuto NSFW spunterà per primo nel prompt corrente",
|
||||||
"Enables OpenAI completion streaming": "Abilita 'streaming completion' per OpenAI",
|
"Enables OpenAI completion streaming": "Attiva 'streaming completion' per OpenAI",
|
||||||
"Wrap user messages in quotes before sending": "Mette tra il messaggio dell'utente in virgolette prima di inviare il messaggio",
|
"Wrap user messages in quotes before sending": "Mette tra il messaggio dell'utente in virgolette prima di inviare il messaggio",
|
||||||
"Restore default prompt": "Ripristina il prompt predefinito",
|
"Restore default prompt": "Ripristina il prompt predefinito",
|
||||||
"New preset": "Nuovo preset",
|
"New preset": "Nuovo preset",
|
||||||
@@ -2765,18 +2787,18 @@
|
|||||||
"Change Background Image": "Cambia l'immagine dello sfondo",
|
"Change Background Image": "Cambia l'immagine dello sfondo",
|
||||||
"Extensions": "Estensioni",
|
"Extensions": "Estensioni",
|
||||||
"Click to set a new User Name": "Clicca qui per impostare un nuovo nome utente",
|
"Click to set a new User Name": "Clicca qui per impostare un nuovo nome utente",
|
||||||
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "Clicca qui per bloccare l'alterego selezionato alla chat corrente. Clicca di nuovo per rimuovere il blocco.",
|
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "Clicca qui per bloccare l'alter ego selezionato alla chat corrente. Clicca di nuovo per rimuovere il blocco.",
|
||||||
"Click to set user name for all messages": "Clicca qui per impostare il nome utente per tutti i messaggi",
|
"Click to set user name for all messages": "Clicca qui per impostare il nome utente per tutti i messaggi",
|
||||||
"Create a dummy persona": "Crea una tuo alterego fittizio",
|
"Create a dummy persona": "Crea una tuo alter ego fittizio",
|
||||||
"Character Management": "Gestione personaggio",
|
"Character Management": "Gestione personaggio",
|
||||||
"Locked = Character Management panel will stay open": "Se clicchi il lucchetto, il pannello della Gestione personaggio rimarrà aperto",
|
"Locked = Character Management panel will stay open": "Se clicchi il lucchetto, il pannello di gestione del personaggio rimarrà aperto",
|
||||||
"Select/Create Characters": "Seleziona/Crea Personaggi",
|
"Select/Create Characters": "Seleziona/Crea Personaggi",
|
||||||
"Token counts may be inaccurate and provided just for reference.": "Il conteggio dei Token potrebbe risultare inaccurato, perciò è da utilizzarsi solo come una approssimazione.",
|
"Token counts may be inaccurate and provided just for reference.": "Il conteggio dei Token potrebbe risultare inaccurato, perciò è da utilizzarsi solo come una approssimazione.",
|
||||||
"Click to select a new avatar for this character": "Clicca qui per selezionare un nuovo avatar per questo personaggio",
|
"Click to select a new avatar for this character": "Clicca qui per selezionare un nuovo avatar per questo personaggio",
|
||||||
"Add to Favorites": "Aggiungi ai Favoriti",
|
"Add to Favorites": "Aggiungi ai favoriti",
|
||||||
"Advanced Definition": "Definizioni Avanzate",
|
"Advanced Definition": "Definizioni avanzate",
|
||||||
"Character Lore": "Storia del personaggio",
|
"Character Lore": "Storia del personaggio",
|
||||||
"Export and Download": "Esporta e Scarica",
|
"Export and Download": "Esporta e scarica",
|
||||||
"Duplicate Character": "Duplica il personaggio",
|
"Duplicate Character": "Duplica il personaggio",
|
||||||
"Create Character": "Crea un personaggio",
|
"Create Character": "Crea un personaggio",
|
||||||
"Delete Character": "Elimina un personaggio",
|
"Delete Character": "Elimina un personaggio",
|
||||||
@@ -2820,8 +2842,8 @@
|
|||||||
"Move message up": "Muovi il messaggio in alto",
|
"Move message up": "Muovi il messaggio in alto",
|
||||||
"Move message down": "Muovi il messaggio in basso",
|
"Move message down": "Muovi il messaggio in basso",
|
||||||
"Enlarge": "Ingrandisci",
|
"Enlarge": "Ingrandisci",
|
||||||
"Temporarily disable automatic replies from this character": "Disabilita temporaneamente le risposte in automatico da parte di questo personaggio",
|
"Temporarily disable automatic replies from this character": "Disattiva temporaneamente le risposte in automatico da parte di questo personaggio",
|
||||||
"Enable automatic replies from this character": "Abilita le risposte in automatico da parte di questo personaggio",
|
"Enable automatic replies from this character": "Attiva le risposte in automatico da parte di questo personaggio",
|
||||||
"Trigger a message from this character": "Innesca un messaggio di risposta da parte di questo personaggio",
|
"Trigger a message from this character": "Innesca un messaggio di risposta da parte di questo personaggio",
|
||||||
"Move up": "Muovi sopra",
|
"Move up": "Muovi sopra",
|
||||||
"Move down": "Muovi sotto",
|
"Move down": "Muovi sotto",
|
||||||
@@ -2834,13 +2856,13 @@
|
|||||||
"Ask AI to write your message for you": "Chiedi all'IA di scrivere un messaggio al posto tuo",
|
"Ask AI to write your message for you": "Chiedi all'IA di scrivere un messaggio al posto tuo",
|
||||||
"Continue the last message": "Continua l'ultimo messaggio in chat",
|
"Continue the last message": "Continua l'ultimo messaggio in chat",
|
||||||
"Bind user name to that avatar": "Lega il nome utente a questo avatar",
|
"Bind user name to that avatar": "Lega il nome utente a questo avatar",
|
||||||
"Select this as default persona for the new chats.": "Seleziona questo alterego come predefinito per tutte le nuove chat",
|
"Select this as default persona for the new chats.": "Seleziona questo alter ego come predefinito per tutte le nuove chat",
|
||||||
"Change persona image": "Cambia l'immagine del tuo alterego",
|
"Change persona image": "Cambia l'immagine del tuo alter ego",
|
||||||
"Delete persona": "Elimina il tuo alterego",
|
"Delete persona": "Elimina il tuo alter ego",
|
||||||
"--- Pick to Edit ---": "--- Scegli per modificare ---",
|
"--- Pick to Edit ---": "--- Seleziona per modificare ---",
|
||||||
"Add text here that would make the AI generate things you don't want in your outputs.": "Scrivi qui ciò che non vuoi l'IA generi nel suo output.",
|
"Add text here that would make the AI generate things you don't want in your outputs.": "Scrivi ciò che non vuoi l'IA generi nel suo output.",
|
||||||
"write short replies, write replies using past tense": "Scrivi risposte brevi, scrivi risposte usando il passato",
|
"write short replies, write replies using past tense": "Scrivi risposte brevi, scrivi risposte usando il passato",
|
||||||
"Alert if your world info is greater than the allocated budget.": "Questo avvisa nel momento in cui le 'Info Mondo' consumano più di quanto allocato nel budget.",
|
"Alert if your world info is greater than the allocated budget.": "Ti avvisa nel momento in cui 'Info Mondo' consuma più di quanto allocato nel budget.",
|
||||||
"Clear your cookie": "Cancella i cookie",
|
"Clear your cookie": "Cancella i cookie",
|
||||||
"Restore new group chat prompt": "Ripristina il prompt della nuova chat di gruppo",
|
"Restore new group chat prompt": "Ripristina il prompt della nuova chat di gruppo",
|
||||||
"Save movingUI changes to a new file": "Salva i cambiamenti apportati alla posizione dei pannelli dell'UI (MovingUI) in un nuovo file",
|
"Save movingUI changes to a new file": "Salva i cambiamenti apportati alla posizione dei pannelli dell'UI (MovingUI) in un nuovo file",
|
||||||
@@ -2851,25 +2873,25 @@
|
|||||||
"Prompts": "Prompt",
|
"Prompts": "Prompt",
|
||||||
"Tokens": "Token",
|
"Tokens": "Token",
|
||||||
"Reset current character": "Ripristina il personaggio attuale",
|
"Reset current character": "Ripristina il personaggio attuale",
|
||||||
"(0 = disabled)": "(0 = disabilitato)",
|
"(0 = disabled)": "(0 = disattivato)",
|
||||||
"1 = disabled": "1 = disabilitato",
|
"1 = disabled": "1 = disattivato",
|
||||||
"Activation Regex": "Attivazione Regex",
|
"Activation Regex": "Attivazione Regex",
|
||||||
"Active World(s) for all chats": "Attiva i Mondi per tutte le chat",
|
"Active World(s) for all chats": "Attiva i Mondi per tutte le chat",
|
||||||
"Add character names": "Aggiungi i nomi dei personaggi",
|
"Add character names": "Aggiungi i nomi dei personaggi",
|
||||||
"Add Memo": "Aggiungi note",
|
"Add Memo": "Aggiungi note",
|
||||||
"Advanced Character Search": "Ricerca dei personaggi avanzata",
|
"Advanced Character Search": "Ricerca personaggi avanzata",
|
||||||
"Aggressive": "Aggressivo",
|
"Aggressive": "Aggressivo",
|
||||||
"AI21 Model": "Modello AI21",
|
"AI21 Model": "Modello AI21",
|
||||||
"Alert On Overflow": "Avviso in caso di Overflow",
|
"Alert On Overflow": "Avviso in caso di Overflow",
|
||||||
"Allow fallback routes": "Permetti fallback routes",
|
"Allow fallback routes": "Permetti fallback routes",
|
||||||
"Allow fallback routes Description": "Permetti la descrizione di fallback routes",
|
"Allow fallback routes Description": "Permetti descrizione fallback routes",
|
||||||
"Alt Method": "Metodo Alt",
|
"Alt Method": "Metodo Alt",
|
||||||
"Alternate Greetings": "Alterna i saluti",
|
"Alternate Greetings": "Alterna i saluti",
|
||||||
"Alternate Greetings Hint": "Suggerimenti per i saluti alternati",
|
"Alternate Greetings Hint": "Premi la croce in alto a destra per generare una nuova casella di testo",
|
||||||
"Alternate Greetings Subtitle": "Sottotitoli per i saluti alternati",
|
"Alternate Greetings Subtitle": "Qui saranno presenti i saluti alternativi",
|
||||||
"Assistant Prefill": "Assistant Prefill",
|
"Assistant Prefill": "Assistant Prefill",
|
||||||
"Banned Tokens": "Token banditi",
|
"Banned Tokens": "Token banditi",
|
||||||
"Blank": "In bianco",
|
"Blank": "Nuovo",
|
||||||
"Browser default": "Predefinito del browser",
|
"Browser default": "Predefinito del browser",
|
||||||
"Budget Cap": "Limite budget",
|
"Budget Cap": "Limite budget",
|
||||||
"CFG": "CFG",
|
"CFG": "CFG",
|
||||||
@@ -2887,13 +2909,14 @@
|
|||||||
"Example Separator": "Separatore d'esempio",
|
"Example Separator": "Separatore d'esempio",
|
||||||
"Exclude Assistant suffix": "Escludi il suffisso assistente",
|
"Exclude Assistant suffix": "Escludi il suffisso assistente",
|
||||||
"Exclude the assistant suffix from being added to the end of prompt.": "Esclude il suffisso assistente dall'essere aggiunto alla fine del prompt.",
|
"Exclude the assistant suffix from being added to the end of prompt.": "Esclude il suffisso assistente dall'essere aggiunto alla fine del prompt.",
|
||||||
"Force for Groups and Personas": "Forzalo per gruppi e alterego",
|
"Force for Groups and Personas": "Forzalo per gruppi e alter ego",
|
||||||
"Global Negatives": "Global Negatives",
|
"Global Negatives": "Global Negatives",
|
||||||
"In Story String / Chat Completion: After Character Card": "Nella stringa narrativa / Chat Completion: Dopo la 'Carta Personaggio'",
|
"In Story String / Chat Completion: After Character Card": "Nella stringa narrativa / Chat Completion: Dopo la 'Carta Personaggio'",
|
||||||
"In Story String / Chat Completion: Before Character Card": "Nella stringa narrativa / Chat Completion: Prima della 'Carta Personaggio",
|
"In Story String / Chat Completion: Before Character Card": "Nella stringa narrativa / Chat Completion: Prima della 'Carta Personaggio",
|
||||||
"Instruct": "Instruct",
|
"Instruct": "Instruct",
|
||||||
"Instruct Mode": "Modalità Instruct",
|
"Instruct Mode": "Modalità Instruct",
|
||||||
"Last Sequence": "Ultima sequenza",
|
"Last Sequence": "Ultima sequenza",
|
||||||
|
"Lazy Chat Loading": "Caricamento svogliato della chat",
|
||||||
"Least tokens": "Token minimi",
|
"Least tokens": "Token minimi",
|
||||||
"Light": "Leggero",
|
"Light": "Leggero",
|
||||||
"Load koboldcpp order": "Ripristina l'ordine di koboldcpp",
|
"Load koboldcpp order": "Ripristina l'ordine di koboldcpp",
|
||||||
@@ -2908,7 +2931,7 @@
|
|||||||
"Mirostat LR": "Mirostat LR",
|
"Mirostat LR": "Mirostat LR",
|
||||||
"Mirostat Mode": "Mirostat Mode",
|
"Mirostat Mode": "Mirostat Mode",
|
||||||
"Mirostat Tau": "Mirostat Tau",
|
"Mirostat Tau": "Mirostat Tau",
|
||||||
"Model Icon": "Icona del modello",
|
"Model Icon": "Icona modello",
|
||||||
"Most tokens": "Token massimi",
|
"Most tokens": "Token massimi",
|
||||||
"MovingUI Preset": "Preset MovingUI",
|
"MovingUI Preset": "Preset MovingUI",
|
||||||
"Negative Prompt": "Prompt negativo",
|
"Negative Prompt": "Prompt negativo",
|
||||||
@@ -2936,7 +2959,7 @@
|
|||||||
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che una nuova chat sta per iniziare.",
|
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che una nuova chat sta per iniziare.",
|
||||||
"Set at the beginning of the chat history to indicate that a new group chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che un nuova chat di gruppo sta per iniziare.",
|
"Set at the beginning of the chat history to indicate that a new group chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che un nuova chat di gruppo sta per iniziare.",
|
||||||
"Show External models (provided by API)": "Mostra modelli esterni (Forniti dall'API)",
|
"Show External models (provided by API)": "Mostra modelli esterni (Forniti dall'API)",
|
||||||
"Show Notifications Show notifications on switching personas": "Mostra una notifica quando l'alterego viene cambiato",
|
"Show Notifications Show notifications on switching personas": "Mostra una notifica quando l'alter ego viene cambiato",
|
||||||
"Show tags in responses": "Mostra i tag nelle risposte",
|
"Show tags in responses": "Mostra i tag nelle risposte",
|
||||||
"Story String": "Stringa narrativa",
|
"Story String": "Stringa narrativa",
|
||||||
"Text Adventure": "Avventura testuale",
|
"Text Adventure": "Avventura testuale",
|
||||||
@@ -2944,23 +2967,101 @@
|
|||||||
"Toggle Panels": "Interruttore pannelli",
|
"Toggle Panels": "Interruttore pannelli",
|
||||||
"Top A Sampling": "Top A Sampling",
|
"Top A Sampling": "Top A Sampling",
|
||||||
"Top K Sampling": "Top K Sampling",
|
"Top K Sampling": "Top K Sampling",
|
||||||
"UI Language": "Linguaggio interfaccia grafica",
|
"UI Language": "Linguaggio UI",
|
||||||
"Unlocked Context Size": "Sblocca dimensione contesto",
|
"Unlocked Context Size": "Sblocca dimensione contesto",
|
||||||
"Usage Stats": "Statistiche di utilizzo",
|
"Usage Stats": "Statistiche di utilizzo",
|
||||||
"Use AI21 Tokenizer": "Utilizza il Tokenizer di AI21",
|
"Use AI21 Tokenizer": "Utilizza il Tokenizer di AI21",
|
||||||
"Use API key (Only required for Mancer)": "Utilizza la chiave API (Necessario soltanto per Mancer)",
|
"Use API key (Only required for Mancer)": "Utilizza la chiave API (Necessario soltanto per Mancer)",
|
||||||
"Use character author's note": "Utilizza le note d'autore del personaggio",
|
"Use character author's note": "Utilizza le note d'autore del personaggio",
|
||||||
"Use character CFG scales": "Utilizza CFG scales del personaggio",
|
"Use character CFG scales": "Utilizza CFG scales del personaggio",
|
||||||
"Use Proxy password field instead. This input will be ignored.": "Utilizza il campo del password proxy al suo posto. Questo input verrà ignorato.",
|
"Use Proxy password field instead. This input will be ignored.": "Utilizza il campo della password proxy al suo posto. Questo input verrà ignorato.",
|
||||||
"Use style tags to modify the writing style of the output": "Utilizza lo stile delle tag per modificare lo stile di scrittura in output",
|
"Use style tags to modify the writing style of the output": "Utilizza lo stile delle tag per modificare lo stile di scrittura in output",
|
||||||
"Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.": "Utilizza il tokenizer appropiato per i modelli giurassici, visto che è più efficente di quello di GPT.",
|
"Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.": "Utilizza il tokenizer appropiato per i modelli giurassici, visto che è più efficente di quello di GPT.",
|
||||||
"Used if CFG Scale is unset globally, per chat or character": "Usato se CFG Scale non è settato globalmente, per le chat o per i personaggi",
|
"Used if CFG Scale is unset globally, per chat or character": "È utilizzato soltanto se CFG Scale non è settato globalmente, per le chat o per i personaggi",
|
||||||
"Very aggressive": "Esageratamente aggressivo",
|
"Very aggressive": "Esageratamente aggressivo",
|
||||||
"Very light": "Esageratamente leggero",
|
"Very light": "Esageratamente leggero",
|
||||||
"Welcome to SillyTavern!": "Benvenuto in SillyTavern!",
|
"Welcome to SillyTavern!": "Benvenuto in SillyTavern!",
|
||||||
"Will be used as a password for the proxy instead of API key.": "Verrà usato come password per il proxy invece che la chiave API.",
|
"Will be used as a password for the proxy instead of API key.": "Verrà usato come password per il proxy invece che la chiave API.",
|
||||||
"Window AI Model": "Modello Window AI",
|
"Window AI Model": "Modello Window AI",
|
||||||
"Your Persona": "Il tuo alterego"
|
"Your Persona": "Il tuo alter ego",
|
||||||
|
"Start Claude's answer with...": "Inizia la risposta di Claude con...",
|
||||||
|
"# of messages (0 = disabled)": "'# dei messaggi (0 = disattivato)'",
|
||||||
|
"Advanced": "Avanzata",
|
||||||
|
"AI Module": "Modulo IA",
|
||||||
|
"AI21 API Key": "Chiave API AI21",
|
||||||
|
"Allow NSFW images from Horde": "Permetti immagini NSFW da Horde",
|
||||||
|
"Anthropic's developer console": "Console di sviluppo per Anthropic",
|
||||||
|
"Avoid spending Anlas": "Evita di spendere Anlas",
|
||||||
|
"Click Authorize below or get the key from": "Clicca Autorizza qui sotto oppure ottieni la chiave da",
|
||||||
|
"Connect": "Connettiti",
|
||||||
|
"Context Order": "Ordine del contesto",
|
||||||
|
"Continue nudge": "Continua nudge (spinta)",
|
||||||
|
"Convert to Persona": "Converti in alter ego",
|
||||||
|
"Debug Menu": "Menu Debug",
|
||||||
|
"Debug Warning": "Avviso Debug",
|
||||||
|
"Enable simple UI mode": "Avvia la modalità UI semplice",
|
||||||
|
"Enter": "Invio",
|
||||||
|
"Example Dialogues": "Dialoghi d'esempio",
|
||||||
|
"Example: https://neuro.mancer.tech/webui/MODEL/api": "Esempio: https://neuro.mancer.tech/webui/MODEL/api",
|
||||||
|
"Example: ws://127.0.0.1:5005/api/v1/stream": "Esempio: ws://127.0.0.1:5005/api/v1/stream",
|
||||||
|
"Execute": "Esegui",
|
||||||
|
"Get it here:": "Ottienila qui:",
|
||||||
|
"Get your key from": "Ottieni la tua chiave da",
|
||||||
|
"Hint": "Suggerimento",
|
||||||
|
"If you are using:": "Se stai usando:",
|
||||||
|
"In Story String / Prompt Manager": "Stringa narrativa / Gestione prompt",
|
||||||
|
"In-Chat Position not affected": "La posizione in-chat non è influenzata",
|
||||||
|
"Karras (not all samplers supported)": "Karras (Non tutti i sampler sono supportati)",
|
||||||
|
"Learn how to contribute your idle GPU cycles to the Horde": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
|
||||||
|
"Models": "Modelli",
|
||||||
|
"New Chat": "Nuova chat",
|
||||||
|
"New Example Chat": "Esempio nuova chat",
|
||||||
|
"New Group Chat": "Nuova chat di gruppo",
|
||||||
|
"Not connected...": "Non connesso...",
|
||||||
|
"Not connected...": "Non connesso...",
|
||||||
|
"Opus tier": "Opus tier",
|
||||||
|
"Output Sequence": "Sequenza Output",
|
||||||
|
"Permanent": "Permanente",
|
||||||
|
"Scale API Key": "Chiave API Scale",
|
||||||
|
"Send names in the ChatML objects.": "Condividi a ChatML i nomi dei partecipanti.",
|
||||||
|
"Show impersonated replies in groups": "Mostra risposte impersonate nelle chat di gruppo",
|
||||||
|
"Show Message Token Count": "Mostra costo in Token per messaggio",
|
||||||
|
"Show notifications on switching personas": "Mostra notifiche quando l'alter ego cambia",
|
||||||
|
"Simple": "Semplice",
|
||||||
|
"Slack and Poe cookies will not work here, do not bother trying.": "I cookie di Slack e Poe non funzioneranno qui, non perdere tempo provandoci.",
|
||||||
|
"Strip Example Messages from Prompt": "Rimuovi i messaggi d'esempio dal prompt",
|
||||||
|
"Summary": "Riassunto",
|
||||||
|
"to use anonymous mode.": "per utilizzare la modalità in anonimo.",
|
||||||
|
"UI Mode": "Modalità UI",
|
||||||
|
"Use style tags to modify the writing style of the output.": "Utilizza i tag di stile per modificare la forma di scrittura in uscita.",
|
||||||
|
"Utility Prompts": "Utility Prompt",
|
||||||
|
"View my Kudos": "Mostra i miei Kudos",
|
||||||
|
"View Remaining Credits": "Mostra crediti rimanenti",
|
||||||
|
"World Info Format Template": "Formato template 'Info Mondo'",
|
||||||
|
"Wraps activated World Info entries before inserting into the prompt.": "Seleziona le informazioni del mondo attualmente attive prima di inserirle nel prompt.",
|
||||||
|
"Local server classification": "Classificazione server locale",
|
||||||
|
"Create Branch": "Crea nuovo ramo",
|
||||||
|
"removes blur from window backgrounds": "Elimina la sfocatura dagli sfondi delle finestre",
|
||||||
|
"Allow for Chat Completion APIs": "Permetti per le 'Chat Completion API'",
|
||||||
|
"at Depth": "a profondità",
|
||||||
|
"Auto-Continue": "Risposta continua",
|
||||||
|
"Auto-Expand Message Actions": "Espansione automatica dei messaggi d'azione",
|
||||||
|
"Automatic (PC)": "Automatico (PC)",
|
||||||
|
"Character Exclusion": "Estromissione del personaggio",
|
||||||
|
"Chat Background": "Sfondo chat",
|
||||||
|
"Custom CSS": "CSS personalizzato",
|
||||||
|
"Depth:": "Profondità:",
|
||||||
|
"Disabled": "Disattivato",
|
||||||
|
"Filter to Character(s)": "Filtra per personaggio",
|
||||||
|
"Grammar": "Grammatica",
|
||||||
|
"Miscellaneous": "Varie",
|
||||||
|
"PaLM API Key": "Chiave API PaLM",
|
||||||
|
"Relax message trim in Groups": "Troncatura leggera dei messaggi nelle chat di gruppo",
|
||||||
|
"Target length (tokens)": "Lunghezza target (in token)",
|
||||||
|
"Theme Toggles": "Interruttore tema",
|
||||||
|
"Type in the desired custom grammar (GBNF).": "Scrivi la tua grammatica personalizzata (GBNF).",
|
||||||
|
"UI Background": "Sfondo UI",
|
||||||
|
"UI Border": "Bordo UI"
|
||||||
},
|
},
|
||||||
"nl-nl": {
|
"nl-nl": {
|
||||||
"clickslidertips": "klikregel tips",
|
"clickslidertips": "klikregel tips",
|
||||||
@@ -2974,7 +3075,7 @@
|
|||||||
"select": "selecteer",
|
"select": "selecteer",
|
||||||
"context size(tokens)": "contextgrootte (in tokens)",
|
"context size(tokens)": "contextgrootte (in tokens)",
|
||||||
"unlocked": "ontgrendeld",
|
"unlocked": "ontgrendeld",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Selecteer alleen modellen die contextgroottes groter dan 2048 tokens ondersteunen. Ga alleen verder als je weet wat je doet!",
|
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Selecteer alleen modellen die contextgroottes groter dan 4096 tokens ondersteunen. Ga alleen verder als je weet wat je doet!",
|
||||||
"rep.pen": "rep.pen",
|
"rep.pen": "rep.pen",
|
||||||
"rep.pen range": "rep.pen bereik",
|
"rep.pen range": "rep.pen bereik",
|
||||||
"temperature": "temperatuur",
|
"temperature": "temperatuur",
|
||||||
@@ -3024,6 +3125,9 @@
|
|||||||
"Streaming": "Streaming",
|
"Streaming": "Streaming",
|
||||||
"Display the response bit by bit as it is generated.": "Toon het antwoord stukje bij beetje terwijl het wordt gegenereerd.",
|
"Display the response bit by bit as it is generated.": "Toon het antwoord stukje bij beetje terwijl het wordt gegenereerd.",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "Wanneer dit is uitgeschakeld, worden antwoorden in één keer weergegeven wanneer ze compleet zijn.",
|
"When this is off, responses will be displayed all at once when they are complete.": "Wanneer dit is uitgeschakeld, worden antwoorden in één keer weergegeven wanneer ze compleet zijn.",
|
||||||
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genereer slechts één regel per verzoek (alleen KoboldAI, genegeerd door KoboldCpp).",
|
||||||
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Verbied het End-of-Sequence (EOS) token (met KoboldCpp, en mogelijk ook andere tokens met KoboldAI).",
|
||||||
|
"Good for story writing, but should not be used for chat and instruct mode.": "Goed voor het schrijven van verhalen, maar mag niet worden gebruikt voor de chat- en instructiemodus.",
|
||||||
"Enhance Definitions": "Verbeter definities",
|
"Enhance Definitions": "Verbeter definities",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Gebruik de OAI-kennisbank om definities van publieke figuren en bekende fictieve personages te verbeteren.",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Gebruik de OAI-kennisbank om definities van publieke figuren en bekende fictieve personages te verbeteren.",
|
||||||
"Wrap in Quotes": "Wikkel in aanhalingstekens",
|
"Wrap in Quotes": "Wikkel in aanhalingstekens",
|
||||||
@@ -3511,165 +3615,168 @@
|
|||||||
"Select this as default persona for the new chats.": "Selecteer dit als standaard persona voor de nieuwe chats.",
|
"Select this as default persona for the new chats.": "Selecteer dit als standaard persona voor de nieuwe chats.",
|
||||||
"Change persona image": "persona afbeelding wijzigen",
|
"Change persona image": "persona afbeelding wijzigen",
|
||||||
"Delete persona": "persona verwijderen"
|
"Delete persona": "persona verwijderen"
|
||||||
},
|
},
|
||||||
"es-spa": {
|
"es-spa": {
|
||||||
"clickslidertips": "Haz click en el número al lado de la barra \npara seleccionar un número manualmente.",
|
"clickslidertips": "Haz click en el número al lado de la barra \npara seleccionar un número manualmente.",
|
||||||
"kobldpresets": "Configuraciones de KoboldAI",
|
"kobldpresets": "Configuraciones de KoboldAI",
|
||||||
"guikoboldaisettings": "Configuración actual de la interfaz de KoboldAI",
|
"guikoboldaisettings": "Configuración actual de la interfaz de KoboldAI",
|
||||||
"novelaipreserts": "Configuraciones de NovelAI",
|
"novelaipreserts": "Configuraciones de NovelAI",
|
||||||
"default": "Predeterminado",
|
"default": "Predeterminado",
|
||||||
"openaipresets": "Configuraciones de OpenAI",
|
"openaipresets": "Configuraciones de OpenAI",
|
||||||
"text gen webio(ooba) presets": "Configuraciones de WebUI(ooba)",
|
"text gen webio(ooba) presets": "Configuraciones de WebUI(ooba)",
|
||||||
"response legth(tokens)": "Largo de la respuesta de la IA (en Tokens)",
|
"response legth(tokens)": "Largo de la respuesta de la IA (en Tokens)",
|
||||||
"select": "Seleccionar",
|
"select": "Seleccionar",
|
||||||
"context size(tokens)": "Tamaño del contexto (en Tokens)",
|
"context size(tokens)": "Tamaño del contexto (en Tokens)",
|
||||||
"unlocked": "Desbloqueado",
|
"unlocked": "Desbloqueado",
|
||||||
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Solo algunos modelos tienen soporte para tamaños de más de 2048 tokens. Procede 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 tienen soporte para tamaños de más de 4096 tokens. Procede solo si sabes lo que estás haciendo.",
|
||||||
"rep.pen": "Rep. Pen.",
|
"rep.pen": "Rep. Pen.",
|
||||||
"rep.pen range": "Rango de Rep. Pen.",
|
"rep.pen range": "Rango de Rep. Pen.",
|
||||||
"temperature": "Temperature",
|
"temperature": "Temperature",
|
||||||
"Encoder Rep. Pen.": "Encoder Rep. Pen.",
|
"Encoder Rep. Pen.": "Encoder Rep. Pen.",
|
||||||
"No Repeat Ngram Size": "No Repeat Ngram Size",
|
"No Repeat Ngram Size": "No Repeat Ngram Size",
|
||||||
"Min Length": "Largo mínimo",
|
"Min Length": "Largo mínimo",
|
||||||
"OpenAI Reverse Proxy": "Reverse Proxy de OpenAI",
|
"OpenAI Reverse Proxy": "Reverse Proxy de OpenAI",
|
||||||
"Alternative server URL (leave empty to use the default value).": "URL del server alternativo (deja vacío para usar el predeterminado)",
|
"Alternative server URL (leave empty to use the default value).": "URL del server alternativo (deja vacío para usar el predeterminado)",
|
||||||
"Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Borra tu clave(API) real de OpenAI ANTES de escribir nada en este campo.",
|
"Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Borra tu clave(API) real de OpenAI ANTES de escribir nada en este campo.",
|
||||||
"We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "SillyTaven no puede dar soporte por problemas encontrados durante el uso de un proxy no-oficial de OpenAI",
|
"We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "SillyTaven no puede dar soporte por problemas encontrados durante el uso de un proxy no-oficial de OpenAI",
|
||||||
"Legacy Streaming Processing": "Processo Streaming Legacy",
|
"Legacy Streaming Processing": "Processo Streaming Legacy",
|
||||||
"Enable this if the streaming doesn't work with your proxy": "Habilita esta opción si el \"streaming\" no está funcionando.",
|
"Enable this if the streaming doesn't work with your proxy": "Habilita esta opción si el \"streaming\" no está funcionando.",
|
||||||
"Context Size (tokens)": "Tamaño del contexto (en Tokens)",
|
"Context Size (tokens)": "Tamaño del contexto (en Tokens)",
|
||||||
"Max Response Length (tokens)": "Tamaño máximo (en Tokens)",
|
"Max Response Length (tokens)": "Tamaño máximo (en Tokens)",
|
||||||
"Temperature": "Temperatura",
|
"Temperature": "Temperatura",
|
||||||
"Frequency Penalty": "Frequency Penalty",
|
"Frequency Penalty": "Frequency Penalty",
|
||||||
"Presence Penalty": "Presence Penalty",
|
"Presence Penalty": "Presence Penalty",
|
||||||
"Top-p": "Top-p",
|
"Top-p": "Top-p",
|
||||||
"Display bot response text chunks as they are generated": "Muestra el texto poco a poco al mismo tiempo que es generado.",
|
"Display bot response text chunks as they are generated": "Muestra el texto poco a poco al mismo tiempo que es generado.",
|
||||||
"Top A": "Top-a",
|
"Top A": "Top-a",
|
||||||
"Typical Sampling": "Typical Sampling",
|
"Typical Sampling": "Typical Sampling",
|
||||||
"Tail Free Sampling": "Tail Free Sampling",
|
"Tail Free Sampling": "Tail Free Sampling",
|
||||||
"Rep. Pen. Slope": "Rep. Pen. Slope",
|
"Rep. Pen. Slope": "Rep. Pen. Slope",
|
||||||
"Single-line mode": "Modo \"Solo una línea\"",
|
"Single-line mode": "Modo \"Solo una línea\"",
|
||||||
"Top K": "Top-k",
|
"Top K": "Top-k",
|
||||||
"Top P": "Top-p",
|
"Top P": "Top-p",
|
||||||
"Do Sample": "Do Sample",
|
"Do Sample": "Do Sample",
|
||||||
"Add BOS Token": "Añadir BOS Token",
|
"Add BOS Token": "Añadir BOS Token",
|
||||||
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Añade el \"bos_token\" al inicio del prompt. Desabilitar esto puede hacer las respuestas de la IA más creativas",
|
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Añade el \"bos_token\" al inicio del prompt. Desabilitar esto puede hacer las respuestas de la IA más creativas",
|
||||||
"Ban EOS Token": "Prohibir EOS Token",
|
"Ban EOS Token": "Prohibir EOS Token",
|
||||||
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibe el \"eos_token\". Esto obliga a la IA a no terminar su generación de forma prematura",
|
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibe el \"eos_token\". Esto obliga a la IA a no terminar su generación de forma prematura",
|
||||||
"Skip Special Tokens": "Saltarse Tokens Especiales",
|
"Skip Special Tokens": "Saltarse Tokens Especiales",
|
||||||
"Beam search": "Beam Search",
|
"Beam search": "Beam Search",
|
||||||
"Number of Beams": "Number of Beams",
|
"Number of Beams": "Number of Beams",
|
||||||
"Length Penalty": "Length Penalty",
|
"Length Penalty": "Length Penalty",
|
||||||
"Early Stopping": "Early Stopping",
|
"Early Stopping": "Early Stopping",
|
||||||
"Contrastive search": "Contrastive search",
|
"Contrastive search": "Contrastive search",
|
||||||
"Penalty Alpha": "Penalty Alpha",
|
"Penalty Alpha": "Penalty Alpha",
|
||||||
"Seed": "Seed",
|
"Seed": "Seed",
|
||||||
"Inserts jailbreak as a last system message.": "Inserta el \"jailbreak\" como el último mensaje del Sistema",
|
"Inserts jailbreak as a last system message.": "Inserta el \"jailbreak\" como el último mensaje del Sistema",
|
||||||
"This tells the AI to ignore its usual content restrictions.": "Esto ayuda a la IA para ignorar sus restricciones de contenido",
|
"This tells the AI to ignore its usual content restrictions.": "Esto ayuda a la IA para ignorar sus restricciones de contenido",
|
||||||
"NSFW Encouraged": "Alentar \"NSFW\"",
|
"NSFW Encouraged": "Alentar \"NSFW\"",
|
||||||
"Tell the AI that NSFW is allowed.": "Le dice a la IA que el contenido NSFW (+18) está permitido",
|
"Tell the AI that NSFW is allowed.": "Le dice a la IA que el contenido NSFW (+18) está permitido",
|
||||||
"NSFW Prioritized": "Priorizar NSFW",
|
"NSFW Prioritized": "Priorizar NSFW",
|
||||||
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El \"prompt NSFW\" va antes para enfatizar su efecto",
|
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El \"prompt NSFW\" va antes para enfatizar su efecto",
|
||||||
"Streaming": "Streaming",
|
"Streaming": "Streaming",
|
||||||
"Display the response bit by bit as it is generated.": "Enseña el texto poco a poco mientras es generado",
|
"Display the response bit by bit as it is generated.": "Enseña el texto poco a poco mientras es generado",
|
||||||
"When this is off, responses will be displayed all at once when they are complete.": "Cuando esto está deshabilitado, las respuestas se mostrarán de una vez cuando la generación se haya completado",
|
"When this is off, responses will be displayed all at once when they are complete.": "Cuando esto está deshabilitado, las respuestas se mostrarán de una vez cuando la generación se haya completado",
|
||||||
"Enhance Definitions": "Definiciones Mejoradas",
|
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genera solo una línea por solicitud (solo KoboldAI, ignorada por KoboldCpp).",
|
||||||
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa el conocimiento de OpenAI (GPT 3.5, GPT 4, ChatGPT) para mejorar las definiciones de figuras públicas y personajes ficticios",
|
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Prohibir el token de fin de secuencia (EOS) (con KoboldCpp, y posiblemente también otros tokens con KoboldAI).",
|
||||||
"Wrap in Quotes": "Envolver En Comillas",
|
"Good for story writing, but should not be used for chat and instruct mode.": "Bueno para escribir historias, pero no debe usarse para chatear ni para el modo de instrucción.",
|
||||||
"Wrap entire user message in quotes before sending.": "Envuelve todo el mensaje en comillas antes de enviar",
|
"Enhance Definitions": "Definiciones Mejoradas",
|
||||||
"Leave off if you use quotes manually for speech.": "Déjalo deshabilitado si usas comillas manualmente para denotar diálogo",
|
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa el conocimiento de OpenAI (GPT 3.5, GPT 4, ChatGPT) para mejorar las definiciones de figuras públicas y personajes ficticios",
|
||||||
"Main prompt": "Prompt Principal",
|
"Wrap in Quotes": "Envolver En Comillas",
|
||||||
"The main prompt used to set the model behavior": "El prompt principal usado para definir el comportamiento de la IA",
|
"Wrap entire user message in quotes before sending.": "Envuelve todo el mensaje en comillas antes de enviar",
|
||||||
"NSFW prompt": "Prompt NSFW",
|
"Leave off if you use quotes manually for speech.": "Déjalo deshabilitado si usas comillas manualmente para denotar diálogo",
|
||||||
"Prompt that is used when the NSFW toggle is on": "Prompt que es utilizado cuando \"Alentar NSFW\" está activado",
|
"Main prompt": "Prompt Principal",
|
||||||
"Jailbreak prompt": "Jailbreak prompt",
|
"The main prompt used to set the model behavior": "El prompt principal usado para definir el comportamiento de la IA",
|
||||||
"Prompt that is used when the Jailbreak toggle is on": "Prompt que es utilizado cuando Jailbreak Prompt está activado",
|
"NSFW prompt": "Prompt NSFW",
|
||||||
"Impersonation prompt": "Prompt \"Impersonar\"",
|
"Prompt that is used when the NSFW toggle is on": "Prompt que es utilizado cuando \"Alentar NSFW\" está activado",
|
||||||
"Prompt that is used for Impersonation function": "Prompt que es utilizado para la función \"Impersonar\"",
|
"Jailbreak prompt": "Jailbreak prompt",
|
||||||
"Restore default prompt":"Restaurar el prompt por defecto",
|
"Prompt that is used when the Jailbreak toggle is on": "Prompt que es utilizado cuando Jailbreak Prompt está activado",
|
||||||
"Logit Bias": "Logit Bias",
|
"Impersonation prompt": "Prompt \"Impersonar\"",
|
||||||
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o alentar el uso de algunas palabras",
|
"Prompt that is used for Impersonation function": "Prompt que es utilizado para la función \"Impersonar\"",
|
||||||
"View / Edit bias preset": "Ver/Editar configuración de \"Logit Bias\"",
|
"Restore default prompt":"Restaurar el prompt por defecto",
|
||||||
"Add bias entry": "Añadir bias",
|
"Logit Bias": "Logit Bias",
|
||||||
"Jailbreak activation message": "Mensaje de activación de Jailbrak",
|
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o alentar el uso de algunas palabras",
|
||||||
"Message to send when auto-jailbreak is on.": "Mensaje enviado cuando auto-jailbreak está activado",
|
"View / Edit bias preset": "Ver/Editar configuración de \"Logit Bias\"",
|
||||||
"Jailbreak confirmation reply": "Mensaje de confirmación de Jailbreak",
|
"Add bias entry": "Añadir bias",
|
||||||
"Bot must send this back to confirm jailbreak": "La IA debe enviar un mensaje para confirmar el jailbreak",
|
"Jailbreak activation message": "Mensaje de activación de Jailbrak",
|
||||||
"Character Note": "Nota del personaje",
|
"Message to send when auto-jailbreak is on.": "Mensaje enviado cuando auto-jailbreak está activado",
|
||||||
"Influences bot behavior in its responses": "Influencia el comportamiento de la IA y sus respuestas",
|
"Jailbreak confirmation reply": "Mensaje de confirmación de Jailbreak",
|
||||||
"API": "API",
|
"Bot must send this back to confirm jailbreak": "La IA debe enviar un mensaje para confirmar el jailbreak",
|
||||||
"KoboldAI": "KoboldAI",
|
"Character Note": "Nota del personaje",
|
||||||
"Use Horde": "Usar AI Horde de KoboldAI",
|
"Influences bot behavior in its responses": "Influencia el comportamiento de la IA y sus respuestas",
|
||||||
"API url": "URL de la API",
|
"API": "API",
|
||||||
"Register a Horde account for faster queue times": "Regístrate en KoboldAI para conseguir respuestas más rápido",
|
"KoboldAI": "KoboldAI",
|
||||||
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir a AI Horde con tu GPU",
|
"Use Horde": "Usar AI Horde de KoboldAI",
|
||||||
"Adjust context size to worker capabilities": "Ajustar tamaño del contexto a las capacidades del trabajador",
|
"API url": "URL de la API",
|
||||||
"Adjust response length to worker capabilities": "Ajustar tamaño de la respuesta a las capacidades del trabajador",
|
"Register a Horde account for faster queue times": "Regístrate en KoboldAI para conseguir respuestas más rápido",
|
||||||
"API key": "API key",
|
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir a AI Horde con tu GPU",
|
||||||
"Register": "Registrarse",
|
"Adjust context size to worker capabilities": "Ajustar tamaño del contexto a las capacidades del trabajador",
|
||||||
"For privacy reasons": "Por motivos de privacidad, tu API será ocultada cuando se vuelva a cargar la página",
|
"Adjust response length to worker capabilities": "Ajustar tamaño de la respuesta a las capacidades del trabajador",
|
||||||
"Model": "Modelo IA",
|
"API key": "API key",
|
||||||
"Hold Control / Command key to select multiple models.": "Presiona Ctrl/Command Key para seleccionar multiples modelos",
|
"Register": "Registrarse",
|
||||||
"Horde models not loaded": "Modelos del Horde no cargados",
|
"For privacy reasons": "Por motivos de privacidad, tu API será ocultada cuando se vuelva a cargar la página",
|
||||||
"Not connected": "Desconectado",
|
"Model": "Modelo IA",
|
||||||
"Novel API key": "API key de NovelAI",
|
"Hold Control / Command key to select multiple models.": "Presiona Ctrl/Command Key para seleccionar multiples modelos",
|
||||||
"Follow": "Sigue",
|
"Horde models not loaded": "Modelos del Horde no cargados",
|
||||||
"these directions": "estas instrucciones",
|
"Not connected": "Desconectado",
|
||||||
"to get your NovelAI API key.": "para conseguir tu NovelAI API key",
|
"Novel API key": "API key de NovelAI",
|
||||||
"Enter it in the box below": "Introduce tu clave API de OpenAI en el siguiente campo",
|
"Follow": "Sigue",
|
||||||
"Novel AI Model": "Modelo IA de NovelAI",
|
"these directions": "estas instrucciones",
|
||||||
"No connection": "Desconectado",
|
"to get your NovelAI API key.": "para conseguir tu NovelAI API key",
|
||||||
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
|
"Enter it in the box below": "Introduce tu clave API de OpenAI en el siguiente campo",
|
||||||
"Make sure you run it with": "Asegúrate de usar el argumento --api cuando se ejecute",
|
"Novel AI Model": "Modelo IA de NovelAI",
|
||||||
"Blocking API url": "API URL",
|
"No connection": "Desconectado",
|
||||||
"Streaming API url": "Streaming API URL",
|
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
|
||||||
"to get your OpenAI API key.": "para conseguir tu clave API de OpenAI",
|
"Make sure you run it with": "Asegúrate de usar el argumento --api cuando se ejecute",
|
||||||
"OpenAI Model": "Modelo AI de OpenAI",
|
"Blocking API url": "API URL",
|
||||||
"View API Usage Metrics": "Ver métricas de uso de la API",
|
"Streaming API url": "Streaming API URL",
|
||||||
"Bot": "Bot",
|
"to get your OpenAI API key.": "para conseguir tu clave API de OpenAI",
|
||||||
"Auto-connect to Last Server": "Auto-conectarse con el último servidor",
|
"OpenAI Model": "Modelo AI de OpenAI",
|
||||||
"View hidden API keys": "Ver claves API ocultas",
|
"View API Usage Metrics": "Ver métricas de uso de la API",
|
||||||
"Advanced Formatting": "Formateo avanzado",
|
"Bot": "Bot",
|
||||||
"AutoFormat Overrides": "Autoformateo de overrides",
|
"Auto-connect to Last Server": "Auto-conectarse con el último servidor",
|
||||||
"Samplers Order": "Orden de Samplers",
|
"View hidden API keys": "Ver claves API ocultas",
|
||||||
"Samplers will be applied in a top-down order. Use with caution.": "Los Samplers serán aplicados de orden superior a inferior. \nUsa con precaución",
|
"Advanced Formatting": "Formateo avanzado",
|
||||||
"Load koboldcpp order": "Cargar el orden de koboldcpp",
|
"AutoFormat Overrides": "Autoformateo de overrides",
|
||||||
"Unlocked Context Size": "Desbloquear Tamaño Del Contexto",
|
"Samplers Order": "Orden de Samplers",
|
||||||
"Unrestricted maximum value for the context slider":"Desbloquea el Tamaño máximo del contexto. Solo habilita esto si sabes lo que estás haciendo.",
|
"Samplers will be applied in a top-down order. Use with caution.": "Los Samplers serán aplicados de orden superior a inferior. \nUsa con precaución",
|
||||||
"Quick Edit": "Editor Rápido de Prompts",
|
"Load koboldcpp order": "Cargar el orden de koboldcpp",
|
||||||
"Main": "Principal",
|
"Unlocked Context Size": "Desbloquear Tamaño Del Contexto",
|
||||||
"Assistant Prefill": "Prefijo del Asistente",
|
"Unrestricted maximum value for the context slider":"Desbloquea el Tamaño máximo del contexto. Solo habilita esto si sabes lo que estás haciendo.",
|
||||||
"Start Claude's answer with...": "Inicia la respuesta de Claude con...",
|
"Quick Edit": "Editor Rápido de Prompts",
|
||||||
"Utility Prompts": "Indicaciones Útiles",
|
"Main": "Principal",
|
||||||
"World Info Format Template": "Plantilla para formato de World Info",
|
"Assistant Prefill": "Prefijo del Asistente",
|
||||||
"NSFW avoidance prompt": "Prompt para evitar NSFW",
|
"Start Claude's answer with...": "Inicia la respuesta de Claude con...",
|
||||||
"Prompt that is used when the NSFW toggle is O": "Prompt utilizado para evitar NSFW cuando \"Alentar NSFW\" está deshabilitado",
|
"Utility Prompts": "Indicaciones Útiles",
|
||||||
"Wraps activated World Info entries before inserting into the prompt.": "Envuelve las entradas activadas de World Info antes de insertarlas en el prompt.",
|
"World Info Format Template": "Plantilla para formato de World Info",
|
||||||
"New Chat": "Chat Nuevo",
|
"NSFW avoidance prompt": "Prompt para evitar NSFW",
|
||||||
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Colocado al inicio del historial de chat para indicar que un nuevo chat va a comenzar.",
|
"Prompt that is used when the NSFW toggle is O": "Prompt utilizado para evitar NSFW cuando \"Alentar NSFW\" está deshabilitado",
|
||||||
"New Group Chat": "Nuevo Chat Grupal",
|
"Wraps activated World Info entries before inserting into the prompt.": "Envuelve las entradas activadas de World Info antes de insertarlas en el prompt.",
|
||||||
"Set at the beginning of the chat history to indicate that a new group chat is about to start.":"Colocado al inicio del historial de chat para indicarle a la IA que un nuevo Chat Grupal va a comenzar",
|
"New Chat": "Chat Nuevo",
|
||||||
"New Example Chat": "Nuevo Ejemplo De Chat",
|
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Colocado al inicio del historial de chat para indicar que un nuevo chat va a comenzar.",
|
||||||
"Add character names": "Incluír nombre del personaje",
|
"New Group Chat": "Nuevo Chat Grupal",
|
||||||
"Send names in the ChatML objects.": "Envía los mensajes al objeto ChatML. Ayuda a la IA a asociar mensajes con nombres en un chat grupal.",
|
"Set at the beginning of the chat history to indicate that a new group chat is about to start.":"Colocado al inicio del historial de chat para indicarle a la IA que un nuevo Chat Grupal va a comenzar",
|
||||||
"Proxy Password": "Contraseña del Proxy",
|
"New Example Chat": "Nuevo Ejemplo De Chat",
|
||||||
"Will be used as a password for the proxy instead of API key.": "Será utilizado como contraseña del proxy en vez de la clave API.",
|
"Add character names": "Incluír nombre del personaje",
|
||||||
"Chat Completion Source": "Fuente de Chat",
|
"Send names in the ChatML objects.": "Envía los mensajes al objeto ChatML. Ayuda a la IA a asociar mensajes con nombres en un chat grupal.",
|
||||||
"Use Proxy password field instead. This input will be ignored.": "Utiliza el campo de Contraseña del Proxy. Lo que pongas aquí será ignorado.",
|
"Proxy Password": "Contraseña del Proxy",
|
||||||
"Show External models (provided by API)": "Mostrar modelos externos (Proveídos por la API)",
|
"Will be used as a password for the proxy instead of API key.": "Será utilizado como contraseña del proxy en vez de la clave API.",
|
||||||
"Connect": "Conectarse",
|
"Chat Completion Source": "Fuente de Chat",
|
||||||
"[title]Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica que tu conexión con la API enviando un mensaje corto. ¡Ten en cuenta que se te cobrará por ello!",
|
"Use Proxy password field instead. This input will be ignored.": "Utiliza el campo de Contraseña del Proxy. Lo que pongas aquí será ignorado.",
|
||||||
"Continue nudge": "Empujuón para continuar",
|
"Show External models (provided by API)": "Mostrar modelos externos (Proveídos por la API)",
|
||||||
"Replace empty message": "Reemplazar mensaje vacío",
|
"Connect": "Conectarse",
|
||||||
"Send this text instead of nothing when the text box is empty.": "Envía este mensaje en vez de nada cuando la barra de chat está vacía",
|
"[title]Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica que tu conexión con la API enviando un mensaje corto. ¡Ten en cuenta que se te cobrará por ello!",
|
||||||
"No connection...": "Sin conexión...",
|
"Continue nudge": "Empujuón para continuar",
|
||||||
"Avoid sending sensitive information to the Horde.": "No envíes información personal a Horde.",
|
"Replace empty message": "Reemplazar mensaje vacío",
|
||||||
"Review the Privacy statement": "Revisa el aviso de privacidad",
|
"Send this text instead of nothing when the text box is empty.": "Envía este mensaje en vez de nada cuando la barra de chat está vacía",
|
||||||
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende como contribuír a Horde con tu GPU.",
|
"No connection...": "Sin conexión...",
|
||||||
"Trusted workers only": "Solo trabajadores de confianza",
|
"Avoid sending sensitive information to the Horde.": "No envíes información personal a Horde.",
|
||||||
"API Key": "Clave API",
|
"Review the Privacy statement": "Revisa el aviso de privacidad",
|
||||||
"Get it here:": "Consíguela aquí:",
|
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende como contribuír a Horde con tu GPU.",
|
||||||
"View my Kudos": "Ver mis Kudos",
|
"Trusted workers only": "Solo trabajadores de confianza",
|
||||||
"Models": "Modelos IA"
|
"API Key": "Clave API",
|
||||||
|
"Get it here:": "Consíguela aquí:",
|
||||||
|
"View my Kudos": "Ver mis Kudos",
|
||||||
|
"Models": "Modelos IA"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
67
public/img/palm.svg
Normal file
67
public/img/palm.svg
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Standard_product_icon__x28_1:1_x29_"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="192px" height="192px" viewBox="0 0 192 192" enable-background="new 0 0 192 192" xml:space="preserve">
|
||||||
|
<symbol id="material_x5F_product_x5F_standard_x5F_icon_x5F_keylines_00000077318920148093339210000006245950728745084294_" viewBox="-96 -96 192 192">
|
||||||
|
<g opacity="0.4">
|
||||||
|
<defs>
|
||||||
|
<path id="SVGID_1_" opacity="0.4" d="M-96,96V-96H96V96H-96z"/>
|
||||||
|
</defs>
|
||||||
|
<clipPath id="SVGID_00000071517564283228984050000017848131202901217410_">
|
||||||
|
<use xlink:href="#SVGID_1_" overflow="visible"/>
|
||||||
|
</clipPath>
|
||||||
|
<g clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)">
|
||||||
|
<g>
|
||||||
|
<path d="M95.75,95.75v-191.5h-191.5v191.5H95.75 M96,96H-96V-96H96V96L96,96z"/>
|
||||||
|
</g>
|
||||||
|
<circle fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" cx="0" cy="0" r="64"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<circle clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" cx="0" cy="0" r="88"/>
|
||||||
|
|
||||||
|
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
|
||||||
|
M64,76H-64c-6.6,0-12-5.4-12-12V-64c0-6.6,5.4-12,12-12H64c6.6,0,12,5.4,12,12V64C76,70.6,70.6,76,64,76z"/>
|
||||||
|
|
||||||
|
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
|
||||||
|
M52,88H-52c-6.6,0-12-5.4-12-12V-76c0-6.6,5.4-12,12-12H52c6.6,0,12,5.4,12,12V76C64,82.6,58.6,88,52,88z"/>
|
||||||
|
|
||||||
|
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
|
||||||
|
M76,64H-76c-6.6,0-12-5.4-12-12V-52c0-6.6,5.4-12,12-12H76c6.6,0,12,5.4,12,12V52C88,58.6,82.6,64,76,64z"/>
|
||||||
|
</g>
|
||||||
|
</symbol>
|
||||||
|
<rect id="bounding_box_1_" display="none" fill="none" width="192" height="192"/>
|
||||||
|
<g id="art_layer">
|
||||||
|
<g>
|
||||||
|
<path d="M96,181.92L96,181.92c6.63,0,12-5.37,12-12v-104H84v104C84,176.55,89.37,181.92,96,181.92z"/>
|
||||||
|
<g>
|
||||||
|
<path d="M143.81,103.87C130.87,90.94,111.54,88.32,96,96l51.37,51.37c2.12,2.12,5.77,1.28,6.67-1.57
|
||||||
|
C158.56,131.49,155.15,115.22,143.81,103.87z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M48.19,103.87C61.13,90.94,80.46,88.32,96,96l-51.37,51.37c-2.12,2.12-5.77,1.28-6.67-1.57
|
||||||
|
C33.44,131.49,36.85,115.22,48.19,103.87z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M140,64c-20.44,0-37.79,13.4-44,32h81.24c3.33,0,5.55-3.52,4.04-6.49C173.56,74.36,157.98,64,140,64z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M104.49,42.26C90.03,56.72,87.24,78.45,96,96l57.45-57.45c2.36-2.36,1.44-6.42-1.73-7.45
|
||||||
|
C135.54,25.85,117.2,29.55,104.49,42.26z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M87.51,42.26C101.97,56.72,104.76,78.45,96,96L38.55,38.55c-2.36-2.36-1.44-6.42,1.73-7.45
|
||||||
|
C56.46,25.85,74.8,29.55,87.51,42.26z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M52,64c20.44,0,37.79,13.4,44,32H14.76c-3.33,0-5.55-3.52-4.04-6.49C18.44,74.36,34.02,64,52,64z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="keylines" display="none">
|
||||||
|
|
||||||
|
<use xlink:href="#material_x5F_product_x5F_standard_x5F_icon_x5F_keylines_00000077318920148093339210000006245950728745084294_" width="192" height="192" id="material_x5F_product_x5F_standard_x5F_icon_x5F_keylines" x="-96" y="-96" transform="matrix(1 0 0 -1 96 96)" display="inline" overflow="visible"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
1455
public/index.html
1455
public/index.html
File diff suppressed because it is too large
Load Diff
18
public/instruct/Adventure.json
Normal file
18
public/instruct/Adventure.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"system_prompt": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]",
|
||||||
|
"input_sequence": "",
|
||||||
|
"output_sequence": "",
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"system_sequence": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"separator_sequence": "",
|
||||||
|
"wrap": true,
|
||||||
|
"macro": true,
|
||||||
|
"names": false,
|
||||||
|
"names_force_groups": false,
|
||||||
|
"activation_regex": "",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"first_output_sequence": "",
|
||||||
|
"name": "Adventure"
|
||||||
|
}
|
17
public/instruct/ChatML.json
Normal file
17
public/instruct/ChatML.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"wrap": false,
|
||||||
|
"names": true,
|
||||||
|
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"input_sequence": "<|im_start|>user\n",
|
||||||
|
"output_sequence": "<|im_end|>\n<|im_start|>assistant\n",
|
||||||
|
"separator_sequence": "<|im_end|>\n",
|
||||||
|
"macro": true,
|
||||||
|
"names_force_groups": true,
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"activation_regex": "",
|
||||||
|
"first_output_sequence": "<|im_start|>assistant\n",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"name": "ChatML"
|
||||||
|
}
|
17
public/instruct/Libra-32B.json
Normal file
17
public/instruct/Libra-32B.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"wrap": true,
|
||||||
|
"names": true,
|
||||||
|
"system_prompt": "Avoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"input_sequence": "",
|
||||||
|
"output_sequence": "",
|
||||||
|
"separator_sequence": "",
|
||||||
|
"macro": true,
|
||||||
|
"names_force_groups": true,
|
||||||
|
"last_output_sequence": "\n### Response:",
|
||||||
|
"activation_regex": "",
|
||||||
|
"first_output_sequence": "",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"name": "Libra-32B"
|
||||||
|
}
|
18
public/instruct/Lightning 1.1.json
Normal file
18
public/instruct/Lightning 1.1.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"wrap": true,
|
||||||
|
"names": false,
|
||||||
|
"system_prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nTake the role of {{char}} in a play that leaves a lasting impression on {{user}}. Write {{char}}'s next reply.\nNever skip or gloss over {{char}}’s actions. Progress the scene at a naturally slow pace.\n\n",
|
||||||
|
"system_sequence": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"input_sequence": "### Instruction:",
|
||||||
|
"output_sequence": "### Response: (length = unlimited)",
|
||||||
|
"separator_sequence": "",
|
||||||
|
"macro": true,
|
||||||
|
"names_force_groups": true,
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"first_output_sequence": "",
|
||||||
|
"activation_regex": "",
|
||||||
|
"name": "Lightning 1.1"
|
||||||
|
}
|
17
public/instruct/Mistral.json
Normal file
17
public/instruct/Mistral.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"wrap": false,
|
||||||
|
"names": true,
|
||||||
|
"system_prompt": "Write {{char}}'s next reply in this fictional roleplay with {{user}}.",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"input_sequence": "[INST] ",
|
||||||
|
"output_sequence": " [/INST]\n",
|
||||||
|
"separator_sequence": "\n",
|
||||||
|
"macro": true,
|
||||||
|
"names_force_groups": true,
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"activation_regex": "",
|
||||||
|
"first_output_sequence": "\n",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"name": "Mistral"
|
||||||
|
}
|
18
public/instruct/Story.json
Normal file
18
public/instruct/Story.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"system_prompt": "",
|
||||||
|
"input_sequence": "",
|
||||||
|
"output_sequence": "",
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"system_sequence": "",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"separator_sequence": "",
|
||||||
|
"wrap": true,
|
||||||
|
"macro": true,
|
||||||
|
"names": false,
|
||||||
|
"names_force_groups": false,
|
||||||
|
"activation_regex": "",
|
||||||
|
"system_sequence_prefix": "",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"first_output_sequence": "",
|
||||||
|
"name": "Story"
|
||||||
|
}
|
17
public/instruct/Synthia.json
Normal file
17
public/instruct/Synthia.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"wrap": false,
|
||||||
|
"names": false,
|
||||||
|
"system_prompt": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation.",
|
||||||
|
"system_sequence_prefix": "SYSTEM: ",
|
||||||
|
"stop_sequence": "",
|
||||||
|
"input_sequence": "USER: ",
|
||||||
|
"output_sequence": "\nASSISTANT: ",
|
||||||
|
"separator_sequence": "\n",
|
||||||
|
"macro": true,
|
||||||
|
"names_force_groups": true,
|
||||||
|
"last_output_sequence": "",
|
||||||
|
"activation_regex": "",
|
||||||
|
"first_output_sequence": "ASSISTANT: ",
|
||||||
|
"system_sequence_suffix": "",
|
||||||
|
"name": "Synthia"
|
||||||
|
}
|
968
public/script.js
968
public/script.js
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,16 @@ function debouncePromise(func, delay) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_DEPTH = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
export const INJECTION_POSITION ={
|
||||||
|
RELATIVE: 0,
|
||||||
|
ABSOLUTE: 1,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register migrations for the prompt manager when settings are loaded or an Open AI preset is loaded.
|
* Register migrations for the prompt manager when settings are loaded or an Open AI preset is loaded.
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +70,7 @@ const registerPromptManagerMigration = () => {
|
|||||||
* Represents a prompt.
|
* Represents a prompt.
|
||||||
*/
|
*/
|
||||||
class Prompt {
|
class Prompt {
|
||||||
identifier; role; content; name; system_prompt; position;
|
identifier; role; content; name; system_prompt; position; injection_position; injection_depth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Prompt instance.
|
* Create a new Prompt instance.
|
||||||
@@ -72,14 +82,18 @@ class Prompt {
|
|||||||
* @param {string} param0.name - The name of the prompt.
|
* @param {string} param0.name - The name of the prompt.
|
||||||
* @param {boolean} param0.system_prompt - Indicates if the prompt is a system prompt.
|
* @param {boolean} param0.system_prompt - Indicates if the prompt is a system prompt.
|
||||||
* @param {string} param0.position - The position of the prompt in the prompt list.
|
* @param {string} param0.position - The position of the prompt in the prompt list.
|
||||||
|
* @param {number} param0.injection_position - The insert position of the prompt.
|
||||||
|
* @param {number} param0.injection_depth - The depth of the prompt in the chat.
|
||||||
*/
|
*/
|
||||||
constructor({ identifier, role, content, name, system_prompt, position } = {}) {
|
constructor({ identifier, role, content, name, system_prompt, position, injection_depth, injection_position } = {}) {
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.role = role;
|
this.role = role;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.system_prompt = system_prompt;
|
this.system_prompt = system_prompt;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
this.injection_depth = injection_depth;
|
||||||
|
this.injection_position = injection_position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +395,8 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value = prompt.name;
|
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value = prompt.name;
|
||||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value = 'system';
|
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value = 'system';
|
||||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value = prompt.content;
|
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value = prompt.content;
|
||||||
|
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value = prompt.injection_position ?? 0;
|
||||||
|
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value = prompt.injection_depth ?? DEFAULT_DEPTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append prompt to selected character
|
// Append prompt to selected character
|
||||||
@@ -673,6 +689,8 @@ PromptManagerModule.prototype.updatePromptWithPromptEditForm = function (prompt)
|
|||||||
prompt.name = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value;
|
prompt.name = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value;
|
||||||
prompt.role = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value;
|
prompt.role = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value;
|
||||||
prompt.content = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value;
|
prompt.content = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value;
|
||||||
|
prompt.injection_position = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value);
|
||||||
|
prompt.injection_depth = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1085,10 +1103,14 @@ PromptManagerModule.prototype.loadPromptIntoEditForm = function (prompt) {
|
|||||||
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
||||||
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
||||||
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
||||||
|
const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position');
|
||||||
|
const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth');
|
||||||
|
|
||||||
nameField.value = prompt.name ?? '';
|
nameField.value = prompt.name ?? '';
|
||||||
roleField.value = prompt.role ?? '';
|
roleField.value = prompt.role ?? '';
|
||||||
promptField.value = prompt.content ?? '';
|
promptField.value = prompt.content ?? '';
|
||||||
|
injectionPositionField.value = prompt.injection_position ?? INJECTION_POSITION.RELATIVE;
|
||||||
|
injectionDepthField.value = prompt.injection_depth ?? DEFAULT_DEPTH;
|
||||||
|
|
||||||
const resetPromptButton = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_reset');
|
const resetPromptButton = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_reset');
|
||||||
if (true === prompt.system_prompt) {
|
if (true === prompt.system_prompt) {
|
||||||
@@ -1152,10 +1174,14 @@ PromptManagerModule.prototype.clearEditForm = function () {
|
|||||||
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
||||||
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
||||||
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
||||||
|
const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position');
|
||||||
|
const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth');
|
||||||
|
|
||||||
nameField.value = '';
|
nameField.value = '';
|
||||||
roleField.selectedIndex = 0;
|
roleField.selectedIndex = 0;
|
||||||
promptField.value = '';
|
promptField.value = '';
|
||||||
|
injectionPositionField.selectedIndex = 0;
|
||||||
|
injectionDepthField.value = DEFAULT_DEPTH;
|
||||||
|
|
||||||
roleField.disabled = false;
|
roleField.disabled = false;
|
||||||
}
|
}
|
||||||
@@ -1435,13 +1461,18 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const encodedName = escapeHtml(prompt.name);
|
const encodedName = escapeHtml(prompt.name);
|
||||||
|
const isSystemPrompt = !prompt.marker && prompt.system_prompt && prompt.injection_position !== INJECTION_POSITION.ABSOLUTE;
|
||||||
|
const isUserPrompt = !prompt.marker && !prompt.system_prompt && prompt.injection_position !== INJECTION_POSITION.ABSOLUTE;
|
||||||
|
const isInjectionPrompt = !prompt.marker && prompt.injection_position === INJECTION_POSITION.ABSOLUTE;
|
||||||
listItemHtml += `
|
listItemHtml += `
|
||||||
<li class="${prefix}prompt_manager_prompt ${draggableClass} ${enabledClass} ${markerClass}" data-pm-identifier="${prompt.identifier}">
|
<li class="${prefix}prompt_manager_prompt ${draggableClass} ${enabledClass} ${markerClass}" data-pm-identifier="${prompt.identifier}">
|
||||||
<span class="${prefix}prompt_manager_prompt_name" data-pm-name="${encodedName}">
|
<span class="${prefix}prompt_manager_prompt_name" data-pm-name="${encodedName}">
|
||||||
${prompt.marker ? '<span class="fa-solid fa-thumb-tack" title="Marker"></span>' : ''}
|
${prompt.marker ? '<span class="fa-solid fa-thumb-tack" title="Marker"></span>' : ''}
|
||||||
${!prompt.marker && prompt.system_prompt ? '<span class="fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
${isSystemPrompt ? '<span class="fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
||||||
${!prompt.marker && !prompt.system_prompt ? '<span class="fa-solid fa-user" title="User Prompt"></span>' : ''}
|
${isUserPrompt ? '<span class="fa-solid fa-user" title="User Prompt"></span>' : ''}
|
||||||
|
${isInjectionPrompt ? `<span class="fa-solid fa-syringe" title="In-Chat Injection"></span>` : ''}
|
||||||
${this.isPromptInspectionAllowed(prompt) ? `<a class="prompt-manager-inspect-action">${encodedName}</a>` : encodedName}
|
${this.isPromptInspectionAllowed(prompt) ? `<a class="prompt-manager-inspect-action">${encodedName}</a>` : encodedName}
|
||||||
|
${isInjectionPrompt ? `<small class="prompt-manager-injection-depth">@ ${prompt.injection_depth}</small>` : ''}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<span class="prompt_manager_prompt_controls">
|
<span class="prompt_manager_prompt_controls">
|
||||||
|
@@ -18,6 +18,8 @@ import {
|
|||||||
getThumbnailUrl,
|
getThumbnailUrl,
|
||||||
selectCharacterById,
|
selectCharacterById,
|
||||||
eventSource,
|
eventSource,
|
||||||
|
menu_type,
|
||||||
|
substituteParams,
|
||||||
} from "../script.js";
|
} from "../script.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -31,7 +33,7 @@ import {
|
|||||||
SECRET_KEYS,
|
SECRET_KEYS,
|
||||||
secret_state,
|
secret_state,
|
||||||
} from "./secrets.js";
|
} from "./secrets.js";
|
||||||
import { debounce, delay, getStringHash, isUrlOrAPIKey, waitUntilCondition } from "./utils.js";
|
import { debounce, delay, getStringHash, isValidUrl, waitUntilCondition } from "./utils.js";
|
||||||
import { chat_completion_sources, oai_settings } from "./openai.js";
|
import { chat_completion_sources, oai_settings } from "./openai.js";
|
||||||
import { getTokenCount } from "./tokenizers.js";
|
import { getTokenCount } from "./tokenizers.js";
|
||||||
|
|
||||||
@@ -234,7 +236,9 @@ export function RA_CountCharTokens() {
|
|||||||
total_tokens += Number(counter.text());
|
total_tokens += Number(counter.text());
|
||||||
permanent_tokens += isPermanent ? Number(counter.text()) : 0;
|
permanent_tokens += isPermanent ? Number(counter.text()) : 0;
|
||||||
} else {
|
} else {
|
||||||
const tokens = getTokenCount(value);
|
// We substitute macro for existing characters, but not for the character being created
|
||||||
|
const valueToCount = menu_type === 'create' ? value : substituteParams(value);
|
||||||
|
const tokens = getTokenCount(valueToCount);
|
||||||
counter.text(tokens);
|
counter.text(tokens);
|
||||||
total_tokens += tokens;
|
total_tokens += tokens;
|
||||||
permanent_tokens += isPermanent ? tokens : 0;
|
permanent_tokens += isPermanent ? tokens : 0;
|
||||||
@@ -394,7 +398,7 @@ function RA_autoconnect(PrevApi) {
|
|||||||
if (online_status === "no_connection" && LoadLocalBool('AutoConnectEnabled')) {
|
if (online_status === "no_connection" && LoadLocalBool('AutoConnectEnabled')) {
|
||||||
switch (main_api) {
|
switch (main_api) {
|
||||||
case 'kobold':
|
case 'kobold':
|
||||||
if (api_server && isUrlOrAPIKey(api_server)) {
|
if (api_server && isValidUrl(api_server)) {
|
||||||
$("#api_button").click();
|
$("#api_button").click();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -404,7 +408,7 @@ function RA_autoconnect(PrevApi) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'textgenerationwebui':
|
case 'textgenerationwebui':
|
||||||
if (api_server_textgenerationwebui && isUrlOrAPIKey(api_server_textgenerationwebui)) {
|
if (api_server_textgenerationwebui && isValidUrl(api_server_textgenerationwebui)) {
|
||||||
$("#api_button_textgenerationwebui").click();
|
$("#api_button_textgenerationwebui").click();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -415,6 +419,7 @@ function RA_autoconnect(PrevApi) {
|
|||||||
|| (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI)
|
|| (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI)
|
||||||
|| (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER)
|
|| (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER)
|
||||||
|| (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21)
|
|| (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21)
|
||||||
|
|| (secret_state[SECRET_KEYS.PALM] && oai_settings.chat_completion_source == chat_completion_sources.PALM)
|
||||||
) {
|
) {
|
||||||
$("#api_button_openai").click();
|
$("#api_button_openai").click();
|
||||||
}
|
}
|
||||||
@@ -896,6 +901,9 @@ export function initRossMods() {
|
|||||||
//Regenerate if user swipes on the last mesage in chat
|
//Regenerate if user swipes on the last mesage in chat
|
||||||
|
|
||||||
document.addEventListener('swiped-left', function (e) {
|
document.addEventListener('swiped-left', function (e) {
|
||||||
|
if (power_user.gestures === false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
var SwipeButR = $('.swipe_right:last');
|
var SwipeButR = $('.swipe_right:last');
|
||||||
var SwipeTargetMesClassParent = $(e.target).closest('.last_mes');
|
var SwipeTargetMesClassParent = $(e.target).closest('.last_mes');
|
||||||
if (SwipeTargetMesClassParent !== null) {
|
if (SwipeTargetMesClassParent !== null) {
|
||||||
@@ -905,6 +913,9 @@ export function initRossMods() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.addEventListener('swiped-right', function (e) {
|
document.addEventListener('swiped-right', function (e) {
|
||||||
|
if (power_user.gestures === false) {
|
||||||
|
return
|
||||||
|
}
|
||||||
var SwipeButL = $('.swipe_left:last');
|
var SwipeButL = $('.swipe_left:last');
|
||||||
var SwipeTargetMesClassParent = $(e.target).closest('.last_mes');
|
var SwipeTargetMesClassParent = $(e.target).closest('.last_mes');
|
||||||
if (SwipeTargetMesClassParent !== null) {
|
if (SwipeTargetMesClassParent !== null) {
|
||||||
|
@@ -235,6 +235,7 @@ function loadSettings() {
|
|||||||
chat_metadata[metadata_keys.depth] = chat_metadata[metadata_keys.depth] ?? extension_settings.note.defaultDepth ?? DEFAULT_DEPTH;
|
chat_metadata[metadata_keys.depth] = chat_metadata[metadata_keys.depth] ?? extension_settings.note.defaultDepth ?? DEFAULT_DEPTH;
|
||||||
$('#extension_floating_prompt').val(chat_metadata[metadata_keys.prompt]);
|
$('#extension_floating_prompt').val(chat_metadata[metadata_keys.prompt]);
|
||||||
$('#extension_floating_interval').val(chat_metadata[metadata_keys.interval]);
|
$('#extension_floating_interval').val(chat_metadata[metadata_keys.interval]);
|
||||||
|
$('#extension_floating_allow_wi_scan').prop('checked', extension_settings.note.allowWIScan ?? false);
|
||||||
$('#extension_floating_depth').val(chat_metadata[metadata_keys.depth]);
|
$('#extension_floating_depth').val(chat_metadata[metadata_keys.depth]);
|
||||||
$(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
|
$(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
|
||||||
|
|
||||||
@@ -389,6 +390,11 @@ function onChatChanged() {
|
|||||||
$('#extension_floating_default_token_counter').text(tokenCounter3);
|
$('#extension_floating_default_token_counter').text(tokenCounter3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAllowWIScanCheckboxChanged() {
|
||||||
|
extension_settings.note.allowWIScan = !!$(this).prop('checked');
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject author's note options and setup event listeners.
|
* Inject author's note options and setup event listeners.
|
||||||
*/
|
*/
|
||||||
@@ -402,6 +408,7 @@ export function initAuthorsNote() {
|
|||||||
$('#extension_floating_default').on('input', onExtensionFloatingDefaultInput);
|
$('#extension_floating_default').on('input', onExtensionFloatingDefaultInput);
|
||||||
$('#extension_default_depth').on('input', onDefaultDepthInput);
|
$('#extension_default_depth').on('input', onDefaultDepthInput);
|
||||||
$('#extension_default_interval').on('input', onDefaultIntervalInput);
|
$('#extension_default_interval').on('input', onDefaultIntervalInput);
|
||||||
|
$('#extension_floating_allow_wi_scan').on('input', onAllowWIScanCheckboxChanged);
|
||||||
$('input[name="extension_floating_position"]').on('change', onExtensionFloatingPositionInput);
|
$('input[name="extension_floating_position"]').on('change', onExtensionFloatingPositionInput);
|
||||||
$('input[name="extension_default_position"]').on('change', onDefaultPositionInput);
|
$('input[name="extension_default_position"]').on('change', onDefaultPositionInput);
|
||||||
$('input[name="extension_floating_char_position"]').on('change', onExtensionFloatingCharPositionInput);
|
$('input[name="extension_floating_char_position"]').on('change', onExtensionFloatingCharPositionInput);
|
||||||
|
488
public/scripts/backgrounds.js
Normal file
488
public/scripts/backgrounds.js
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl } from "../script.js";
|
||||||
|
import { saveMetadataDebounced } from "./extensions.js";
|
||||||
|
import { registerSlashCommand } from "./slash-commands.js";
|
||||||
|
import { stringFormat } from "./utils.js";
|
||||||
|
|
||||||
|
const BG_METADATA_KEY = 'custom_background';
|
||||||
|
const LIST_METADATA_KEY = 'chat_backgrounds';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background for the current chat and adds it to the list of custom backgrounds.
|
||||||
|
* @param {{url: string, path:string}} backgroundInfo
|
||||||
|
*/
|
||||||
|
function forceSetBackground(backgroundInfo) {
|
||||||
|
saveBackgroundMetadata(backgroundInfo.url);
|
||||||
|
setCustomBackground();
|
||||||
|
|
||||||
|
const list = chat_metadata[LIST_METADATA_KEY] || [];
|
||||||
|
const bg = backgroundInfo.path;
|
||||||
|
list.push(bg);
|
||||||
|
chat_metadata[LIST_METADATA_KEY] = list;
|
||||||
|
saveMetadataDebounced();
|
||||||
|
getChatBackgroundsList();
|
||||||
|
highlightNewBackground(bg);
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onChatChanged() {
|
||||||
|
if (hasCustomBackground()) {
|
||||||
|
setCustomBackground();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsetCustomBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
getChatBackgroundsList();
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChatBackgroundsList() {
|
||||||
|
const list = chat_metadata[LIST_METADATA_KEY];
|
||||||
|
const listEmpty = !Array.isArray(list) || list.length === 0;
|
||||||
|
|
||||||
|
$('#bg_custom_content').empty();
|
||||||
|
$('#bg_chat_hint').toggle(listEmpty);
|
||||||
|
|
||||||
|
if (listEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const bg of list) {
|
||||||
|
const template = getBackgroundFromTemplate(bg, true);
|
||||||
|
$('#bg_custom_content').append(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBackgroundPath(fileUrl) {
|
||||||
|
return `backgrounds/${fileUrl}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightLockedBackground() {
|
||||||
|
$('.bg_example').removeClass('locked');
|
||||||
|
|
||||||
|
const lockedBackground = chat_metadata[BG_METADATA_KEY];
|
||||||
|
|
||||||
|
if (!lockedBackground) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(`.bg_example`).each(function () {
|
||||||
|
const url = $(this).data('url');
|
||||||
|
if (url === lockedBackground) {
|
||||||
|
$(this).addClass('locked');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLockBackgroundClick(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const chatName = getCurrentChatId();
|
||||||
|
|
||||||
|
if (!chatName) {
|
||||||
|
toastr.warning('Select a chat to lock the background for it');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const relativeBgImage = getUrlParameter(this);
|
||||||
|
|
||||||
|
saveBackgroundMetadata(relativeBgImage);
|
||||||
|
setCustomBackground();
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUnlockBackgroundClick(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
removeBackgroundMetadata();
|
||||||
|
unsetCustomBackground();
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasCustomBackground() {
|
||||||
|
return chat_metadata[BG_METADATA_KEY];
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveBackgroundMetadata(file) {
|
||||||
|
chat_metadata[BG_METADATA_KEY] = file;
|
||||||
|
saveMetadataDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeBackgroundMetadata() {
|
||||||
|
delete chat_metadata[BG_METADATA_KEY];
|
||||||
|
saveMetadataDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCustomBackground() {
|
||||||
|
const file = chat_metadata[BG_METADATA_KEY];
|
||||||
|
|
||||||
|
// bg already set
|
||||||
|
if (document.getElementById("bg_custom").style.backgroundImage == file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#bg_custom").css("background-image", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsetCustomBackground() {
|
||||||
|
$("#bg_custom").css("background-image", 'none');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelectBackgroundClick() {
|
||||||
|
const isCustom = $(this).attr('custom') === 'true';
|
||||||
|
const relativeBgImage = getUrlParameter(this);
|
||||||
|
|
||||||
|
// if clicked on upload button
|
||||||
|
if (!relativeBgImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Automatically lock the background if it's custom or other background is locked
|
||||||
|
if (hasCustomBackground() || isCustom) {
|
||||||
|
saveBackgroundMetadata(relativeBgImage);
|
||||||
|
setCustomBackground();
|
||||||
|
highlightLockedBackground();
|
||||||
|
} else {
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
const customBg = window.getComputedStyle(document.getElementById('bg_custom')).backgroundImage;
|
||||||
|
|
||||||
|
// Custom background is set. Do not override the layer below
|
||||||
|
if (customBg !== 'none') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bgFile = $(this).attr("bgfile");
|
||||||
|
const backgroundUrl = getBackgroundPath(bgFile);
|
||||||
|
|
||||||
|
// Fetching to browser memory to reduce flicker
|
||||||
|
fetch(backgroundUrl).then(() => {
|
||||||
|
$("#bg1").css("background-image", relativeBgImage);
|
||||||
|
setBackground(bgFile);
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('Background could not be set: ' + backgroundUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onCopyToSystemBackgroundClick(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const bgNames = await getNewBackgroundName(this);
|
||||||
|
|
||||||
|
if (!bgNames) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bgFile = await fetch(bgNames.oldBg);
|
||||||
|
|
||||||
|
if (!bgFile.ok) {
|
||||||
|
toastr.warning('Failed to copy background');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = await bgFile.blob();
|
||||||
|
const file = new File([blob], bgNames.newBg);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.set('avatar', file);
|
||||||
|
|
||||||
|
uploadBackground(formData);
|
||||||
|
|
||||||
|
const list = chat_metadata[LIST_METADATA_KEY] || [];
|
||||||
|
const index = list.indexOf(bgNames.oldBg);
|
||||||
|
list.splice(index, 1);
|
||||||
|
saveMetadataDebounced();
|
||||||
|
getChatBackgroundsList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the new background name from the user.
|
||||||
|
* @param {Element} referenceElement
|
||||||
|
* @returns {Promise<{oldBg: string, newBg: string}>}
|
||||||
|
* */
|
||||||
|
async function getNewBackgroundName(referenceElement) {
|
||||||
|
const exampleBlock = $(referenceElement).closest('.bg_example');
|
||||||
|
const isCustom = exampleBlock.attr('custom') === 'true';
|
||||||
|
const oldBg = exampleBlock.attr('bgfile');
|
||||||
|
|
||||||
|
if (!oldBg) {
|
||||||
|
console.debug('no bgfile');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileExtension = oldBg.split('.').pop();
|
||||||
|
const fileNameBase = isCustom ? oldBg.split('/').pop() : oldBg;
|
||||||
|
const oldBgExtensionless = fileNameBase.replace(`.${fileExtension}`, '');
|
||||||
|
const newBgExtensionless = await callPopup('<h3>Enter new background name:</h3>', 'input', oldBgExtensionless);
|
||||||
|
|
||||||
|
if (!newBgExtensionless) {
|
||||||
|
console.debug('no new_bg_extensionless');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newBg = `${newBgExtensionless}.${fileExtension}`;
|
||||||
|
|
||||||
|
if (oldBgExtensionless === newBgExtensionless) {
|
||||||
|
console.debug('new_bg === old_bg');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { oldBg, newBg };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onRenameBackgroundClick(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const bgNames = await getNewBackgroundName(this);
|
||||||
|
|
||||||
|
if (!bgNames) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = { old_bg: bgNames.oldBg, new_bg: bgNames.newBg };
|
||||||
|
const response = await fetch('/renamebackground', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
cache: 'no-cache',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
await getBackgrounds();
|
||||||
|
highlightNewBackground(bgNames.newBg);
|
||||||
|
} else {
|
||||||
|
toastr.warning('Failed to rename background');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDeleteBackgroundClick(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const bgToDelete = $(this).closest('.bg_example');
|
||||||
|
const url = bgToDelete.data('url');
|
||||||
|
const isCustom = bgToDelete.attr('custom') === 'true';
|
||||||
|
const confirm = await callPopup("<h3>Delete the background?</h3>", 'confirm');
|
||||||
|
const bg = bgToDelete.attr('bgfile');
|
||||||
|
|
||||||
|
if (confirm) {
|
||||||
|
// If it's not custom, it's a built-in background. Delete it from the server
|
||||||
|
if (!isCustom) {
|
||||||
|
delBackground(bg);
|
||||||
|
} else {
|
||||||
|
const list = chat_metadata[LIST_METADATA_KEY] || [];
|
||||||
|
const index = list.indexOf(bg);
|
||||||
|
list.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const siblingSelector = '.bg_example:not(#form_bg_download)';
|
||||||
|
const nextBg = bgToDelete.next(siblingSelector);
|
||||||
|
const prevBg = bgToDelete.prev(siblingSelector);
|
||||||
|
const anyBg = $(siblingSelector);
|
||||||
|
|
||||||
|
if (nextBg.length > 0) {
|
||||||
|
nextBg.trigger('click');
|
||||||
|
} else if (prevBg.length > 0) {
|
||||||
|
prevBg.trigger('click');
|
||||||
|
} else {
|
||||||
|
$(anyBg[Math.floor(Math.random() * anyBg.length)]).trigger('click');
|
||||||
|
}
|
||||||
|
|
||||||
|
bgToDelete.remove();
|
||||||
|
|
||||||
|
if (url === chat_metadata[BG_METADATA_KEY]) {
|
||||||
|
removeBackgroundMetadata();
|
||||||
|
unsetCustomBackground();
|
||||||
|
highlightLockedBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCustom) {
|
||||||
|
getChatBackgroundsList();
|
||||||
|
saveMetadataDebounced();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const autoBgPrompt = `Pause your roleplay and choose a location ONLY from the provided list that is the most suitable for the current scene. Do not output any other text:\n{0}`;
|
||||||
|
|
||||||
|
async function autoBackgroundCommand() {
|
||||||
|
/** @type {HTMLElement[]} */
|
||||||
|
const bgTitles = Array.from(document.querySelectorAll('#bg_menu_content .BGSampleTitle'));
|
||||||
|
const options = bgTitles.map(x => ({ element: x, text: x.innerText.trim() })).filter(x => x.text.length > 0);
|
||||||
|
if (options.length == 0) {
|
||||||
|
toastr.warning('No backgrounds to choose from. Please upload some images to the "backgrounds" folder.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = options.map(option => `- ${option.text}`).join('\n');
|
||||||
|
const prompt = stringFormat(autoBgPrompt, list);
|
||||||
|
const reply = await generateQuietPrompt(prompt, false, false);
|
||||||
|
const fuse = new Fuse(options, { keys: ['text'] });
|
||||||
|
const bestMatch = fuse.search(reply, { limit: 1 });
|
||||||
|
|
||||||
|
if (bestMatch.length == 0) {
|
||||||
|
toastr.warning('No match found. Please try again.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('Automatically choosing background:', bestMatch);
|
||||||
|
bestMatch[0].item.element.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBackgrounds() {
|
||||||
|
const response = await fetch("/getbackgrounds", {
|
||||||
|
method: "POST",
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
"": "",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (response.ok === true) {
|
||||||
|
const getData = await response.json();
|
||||||
|
//background = getData;
|
||||||
|
//console.log(getData.length);
|
||||||
|
$("#bg_menu_content").children('div').remove();
|
||||||
|
for (const bg of getData) {
|
||||||
|
const template = getBackgroundFromTemplate(bg, false);
|
||||||
|
$("#bg_menu_content").append(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the URL of the background
|
||||||
|
* @param {Element} block
|
||||||
|
* @returns {string} URL of the background
|
||||||
|
*/
|
||||||
|
function getUrlParameter(block) {
|
||||||
|
return $(block).closest(".bg_example").data("url");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a background template
|
||||||
|
* @param {string} bg Path to background
|
||||||
|
* @param {boolean} isCustom Whether the background is custom
|
||||||
|
* @returns {JQuery<HTMLElement>} Background template
|
||||||
|
*/
|
||||||
|
function getBackgroundFromTemplate(bg, isCustom) {
|
||||||
|
const template = $('#background_template .bg_example').clone();
|
||||||
|
const thumbPath = isCustom ? bg : getThumbnailUrl('bg', bg);
|
||||||
|
const url = isCustom ? `url("${encodeURI(bg)}")` : `url("${getBackgroundPath(bg)}")`;
|
||||||
|
const title = isCustom ? bg.split('/').pop() : bg;
|
||||||
|
const friendlyTitle = title.slice(0, title.lastIndexOf('.'));
|
||||||
|
template.attr('title', title);
|
||||||
|
template.attr('bgfile', bg);
|
||||||
|
template.attr('custom', String(isCustom));
|
||||||
|
template.data('url', url);
|
||||||
|
template.css('background-image', `url('${thumbPath}')`);
|
||||||
|
template.find('.BGSampleTitle').text(friendlyTitle);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setBackground(bg) {
|
||||||
|
jQuery.ajax({
|
||||||
|
type: "POST", //
|
||||||
|
url: "/setbackground", //
|
||||||
|
data: JSON.stringify({
|
||||||
|
bg: bg,
|
||||||
|
}),
|
||||||
|
beforeSend: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
dataType: "json",
|
||||||
|
contentType: "application/json",
|
||||||
|
//processData: false,
|
||||||
|
success: function (html) { },
|
||||||
|
error: function (jqXHR, exception) {
|
||||||
|
console.log(exception);
|
||||||
|
console.log(jqXHR);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function delBackground(bg) {
|
||||||
|
const response = await fetch("/delbackground", {
|
||||||
|
method: "POST",
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
bg: bg,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackgroundUploadSelected() {
|
||||||
|
const form = $("#form_bg_download").get(0);
|
||||||
|
|
||||||
|
if (!(form instanceof HTMLFormElement)) {
|
||||||
|
console.error('form_bg_download is not a form');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData(form);
|
||||||
|
uploadBackground(formData);
|
||||||
|
form.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a background to the server
|
||||||
|
* @param {FormData} formData
|
||||||
|
*/
|
||||||
|
function uploadBackground(formData) {
|
||||||
|
jQuery.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/downloadbackground",
|
||||||
|
data: formData,
|
||||||
|
beforeSend: function () {
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
contentType: false,
|
||||||
|
processData: false,
|
||||||
|
success: async function (bg) {
|
||||||
|
setBackground(bg);
|
||||||
|
$("#bg1").css("background-image", `url("${getBackgroundPath(bg)}"`);
|
||||||
|
await getBackgrounds();
|
||||||
|
highlightNewBackground(bg);
|
||||||
|
},
|
||||||
|
error: function (jqXHR, exception) {
|
||||||
|
console.log(exception);
|
||||||
|
console.log(jqXHR);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} bg
|
||||||
|
*/
|
||||||
|
function highlightNewBackground(bg) {
|
||||||
|
const newBg = $(`.bg_example[bgfile="${bg}"]`);
|
||||||
|
const scrollOffset = newBg.offset().top - newBg.parent().offset().top;
|
||||||
|
$('#Backgrounds').scrollTop(scrollOffset);
|
||||||
|
newBg.addClass('flash animated');
|
||||||
|
setTimeout(() => newBg.removeClass('flash animated'), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBackgroundFilterInput() {
|
||||||
|
const filterValue = String($(this).val()).toLowerCase();
|
||||||
|
$("#bg_menu_content > div").each(function () {
|
||||||
|
const $bgContent = $(this);
|
||||||
|
if ($bgContent.attr("title").toLowerCase().includes(filterValue)) {
|
||||||
|
$bgContent.show();
|
||||||
|
} else {
|
||||||
|
$bgContent.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initBackgrounds() {
|
||||||
|
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||||
|
eventSource.on(event_types.FORCE_SET_BACKGROUND, forceSetBackground);
|
||||||
|
$(document).on("click", '.bg_example', onSelectBackgroundClick);
|
||||||
|
$(document).on('click', '.bg_example_lock', onLockBackgroundClick);
|
||||||
|
$(document).on('click', '.bg_example_unlock', onUnlockBackgroundClick);
|
||||||
|
$(document).on('click', '.bg_example_edit', onRenameBackgroundClick);
|
||||||
|
$(document).on("click", '.bg_example_cross', onDeleteBackgroundClick);
|
||||||
|
$(document).on("click", '.bg_example_copy', onCopyToSystemBackgroundClick);
|
||||||
|
$('#auto_background').on("click", autoBackgroundCommand);
|
||||||
|
$("#add_bg_button").on('change', onBackgroundUploadSelected);
|
||||||
|
$("#bg-filter").on("input", onBackgroundFilterInput);
|
||||||
|
registerSlashCommand('lockbg', onLockBackgroundClick, ['bglock'], "– locks a background for the currently selected chat", true, true);
|
||||||
|
registerSlashCommand('unlockbg', onUnlockBackgroundClick, ['bgunlock'], '– unlocks a background for the currently selected chat', true, true);
|
||||||
|
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], '– automatically changes the background based on the chat context using the AI request prompt', true, true);
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
import { characters, getCharacters, handleDeleteCharacter, callPopup } from "../../../script.js";
|
import { characters, getCharacters, handleDeleteCharacter, callPopup } from "../script.js";
|
||||||
|
|
||||||
let is_bulk_edit = false;
|
let is_bulk_edit = false;
|
||||||
|
|
||||||
@@ -64,23 +64,6 @@ async function onDeleteButtonClick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the bulk edit and delete buttons to the UI.
|
|
||||||
*/
|
|
||||||
function addButtons() {
|
|
||||||
const editButton = $(
|
|
||||||
"<i id='bulkEditButton' class='fa-solid fa-edit menu_button bulkEditButton' title='Bulk edit characters'></i>"
|
|
||||||
);
|
|
||||||
const deleteButton = $(
|
|
||||||
"<i id='bulkDeleteButton' class='fa-solid fa-trash menu_button bulkDeleteButton' title='Bulk delete characters' style='display: none;'></i>"
|
|
||||||
);
|
|
||||||
|
|
||||||
$("#charListGridToggle").after(editButton, deleteButton);
|
|
||||||
|
|
||||||
$("#bulkEditButton").on("click", onEditButtonClick);
|
|
||||||
$("#bulkDeleteButton").on("click", onDeleteButtonClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables bulk selection by adding a checkbox next to each character.
|
* Enables bulk selection by adding a checkbox next to each character.
|
||||||
*/
|
*/
|
||||||
@@ -111,7 +94,7 @@ function disableBulkSelect() {
|
|||||||
/**
|
/**
|
||||||
* Entry point that runs on page load.
|
* Entry point that runs on page load.
|
||||||
*/
|
*/
|
||||||
jQuery(async () => {
|
jQuery(() => {
|
||||||
addButtons();
|
$("#bulkEditButton").on("click", onEditButtonClick);
|
||||||
// loadSettings();
|
$("#bulkDeleteButton").on("click", onDeleteButtonClick);
|
||||||
});
|
});
|
@@ -1,19 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
chat_metadata,
|
chat_metadata,
|
||||||
|
substituteParams,
|
||||||
|
this_chid,
|
||||||
eventSource,
|
eventSource,
|
||||||
event_types,
|
event_types,
|
||||||
saveSettingsDebounced,
|
saveSettingsDebounced,
|
||||||
this_chid,
|
} from "../script.js";
|
||||||
} from "../../../script.js";
|
import { extension_settings, saveMetadataDebounced } from "./extensions.js"
|
||||||
import { selected_group } from "../../group-chats.js";
|
import { selected_group } from "./group-chats.js";
|
||||||
import { extension_settings, saveMetadataDebounced } from "../../extensions.js";
|
import { getCharaFilename, delay } from "./utils.js";
|
||||||
import { getCharaFilename, delay } from "../../utils.js";
|
import { power_user } from "./power-user.js";
|
||||||
import { power_user } from "../../power-user.js";
|
|
||||||
import { metadataKeys } from "./util.js";
|
|
||||||
|
|
||||||
// Keep track of where your extension is located, name should match repo name
|
const extensionName = 'cfg';
|
||||||
const extensionName = "cfg";
|
|
||||||
const extensionFolderPath = `scripts/extensions/${extensionName}`;
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
global: {
|
global: {
|
||||||
"guidance_scale": 1,
|
"guidance_scale": 1,
|
||||||
@@ -199,7 +197,7 @@ function loadSettings() {
|
|||||||
if (!promptSeparator.startsWith(`"`)) {
|
if (!promptSeparator.startsWith(`"`)) {
|
||||||
promptSeparatorDisplay.unshift(`"`);
|
promptSeparatorDisplay.unshift(`"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!promptSeparator.endsWith(`"`)) {
|
if (!promptSeparator.endsWith(`"`)) {
|
||||||
promptSeparatorDisplay.push(`"`);
|
promptSeparatorDisplay.push(`"`);
|
||||||
}
|
}
|
||||||
@@ -279,14 +277,8 @@ function migrateSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function is called when the extension is loaded
|
// This function is called when the extension is loaded
|
||||||
jQuery(async () => {
|
export function initCfg() {
|
||||||
// This is an example of loading HTML from a file
|
$('#CFGClose').on('click', function () {
|
||||||
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
|
|
||||||
|
|
||||||
// Append settingsHtml to extensions_settings
|
|
||||||
// extension_settings and extensions_settings2 are the left and right columns of the settings menu
|
|
||||||
// Left should be extensions that deal with system functions and right should be visual/UI related
|
|
||||||
windowHtml.find('#CFGClose').on('click', function () {
|
|
||||||
$("#cfgConfig").transition({
|
$("#cfgConfig").transition({
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
duration: 200,
|
duration: 200,
|
||||||
@@ -295,7 +287,7 @@ jQuery(async () => {
|
|||||||
setTimeout(function () { $('#cfgConfig').hide() }, 200);
|
setTimeout(function () { $('#cfgConfig').hide() }, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chat_cfg_guidance_scale').on('input', function() {
|
$('#chat_cfg_guidance_scale').on('input', function() {
|
||||||
const numberValue = Number($(this).val());
|
const numberValue = Number($(this).val());
|
||||||
const success = setChatCfg(numberValue, settingType.guidance_scale);
|
const success = setChatCfg(numberValue, settingType.guidance_scale);
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -303,15 +295,15 @@ jQuery(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chat_cfg_negative_prompt').on('input', function() {
|
$('#chat_cfg_negative_prompt').on('input', function() {
|
||||||
setChatCfg($(this).val(), settingType.negative_prompt);
|
setChatCfg($(this).val(), settingType.negative_prompt);
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chat_cfg_positive_prompt').on('input', function() {
|
$('#chat_cfg_positive_prompt').on('input', function() {
|
||||||
setChatCfg($(this).val(), settingType.positive_prompt);
|
setChatCfg($(this).val(), settingType.positive_prompt);
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chara_cfg_guidance_scale').on('input', function() {
|
$('#chara_cfg_guidance_scale').on('input', function() {
|
||||||
const value = $(this).val();
|
const value = $(this).val();
|
||||||
const success = setCharCfg(value, settingType.guidance_scale);
|
const success = setCharCfg(value, settingType.guidance_scale);
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -319,34 +311,34 @@ jQuery(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chara_cfg_negative_prompt').on('input', function() {
|
$('#chara_cfg_negative_prompt').on('input', function() {
|
||||||
setCharCfg($(this).val(), settingType.negative_prompt);
|
setCharCfg($(this).val(), settingType.negative_prompt);
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#chara_cfg_positive_prompt').on('input', function() {
|
$('#chara_cfg_positive_prompt').on('input', function() {
|
||||||
setCharCfg($(this).val(), settingType.positive_prompt);
|
setCharCfg($(this).val(), settingType.positive_prompt);
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#global_cfg_guidance_scale').on('input', function() {
|
$('#global_cfg_guidance_scale').on('input', function() {
|
||||||
extension_settings.cfg.global.guidance_scale = Number($(this).val());
|
extension_settings.cfg.global.guidance_scale = Number($(this).val());
|
||||||
$('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2));
|
$('#global_cfg_guidance_scale_counter').text(extension_settings.cfg.global.guidance_scale.toFixed(2));
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#global_cfg_negative_prompt').on('input', function() {
|
$('#global_cfg_negative_prompt').on('input', function() {
|
||||||
extension_settings.cfg.global.negative_prompt = $(this).val();
|
extension_settings.cfg.global.negative_prompt = $(this).val();
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#global_cfg_positive_prompt').on('input', function() {
|
$('#global_cfg_positive_prompt').on('input', function() {
|
||||||
extension_settings.cfg.global.positive_prompt = $(this).val();
|
extension_settings.cfg.global.positive_prompt = $(this).val();
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find(`input[name="cfg_prompt_combine"]`).on('input', function() {
|
$(`input[name="cfg_prompt_combine"]`).on('input', function() {
|
||||||
const values = windowHtml.find(`input[name="cfg_prompt_combine"]`)
|
const values = $('#cfgConfig').find(`input[name="cfg_prompt_combine"]`)
|
||||||
.filter(":checked")
|
.filter(":checked")
|
||||||
.map(function() { return parseInt($(this).val()) })
|
.map(function() { return Number($(this).val()) })
|
||||||
.get()
|
.get()
|
||||||
.filter((e) => !Number.isNaN(e)) || [];
|
.filter((e) => !Number.isNaN(e)) || [];
|
||||||
|
|
||||||
@@ -354,17 +346,17 @@ jQuery(async () => {
|
|||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find(`#cfg_prompt_insertion_depth`).on('input', function() {
|
$(`#cfg_prompt_insertion_depth`).on('input', function() {
|
||||||
chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());
|
chat_metadata[metadataKeys.prompt_insertion_depth] = Number($(this).val());
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find(`#cfg_prompt_separator`).on('input', function() {
|
$(`#cfg_prompt_separator`).on('input', function() {
|
||||||
chat_metadata[metadataKeys.prompt_separator] = $(this).val();
|
chat_metadata[metadataKeys.prompt_separator] = $(this).val();
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
windowHtml.find('#groupchat_cfg_use_chara').on('input', function() {
|
$('#groupchat_cfg_use_chara').on('input', function() {
|
||||||
const checked = !!$(this).prop('checked');
|
const checked = !!$(this).prop('checked');
|
||||||
chat_metadata[metadataKeys.groupchat_individual_chars] = checked
|
chat_metadata[metadataKeys.groupchat_individual_chars] = checked
|
||||||
|
|
||||||
@@ -375,20 +367,126 @@ jQuery(async () => {
|
|||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#movingDivs").append(windowHtml);
|
|
||||||
|
|
||||||
initialLoadSettings();
|
initialLoadSettings();
|
||||||
|
|
||||||
if (extension_settings.cfg) {
|
if (extension_settings.cfg) {
|
||||||
migrateSettings();
|
migrateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonHtml = $(await $.get(`${extensionFolderPath}/menuButton.html`));
|
$('#option_toggle_CFG').on('click', onCfgMenuItemClick);
|
||||||
buttonHtml.on('click', onCfgMenuItemClick)
|
|
||||||
buttonHtml.appendTo("#options_advanced");
|
|
||||||
|
|
||||||
// Hook events
|
// Hook events
|
||||||
eventSource.on(event_types.CHAT_CHANGED, async () => {
|
eventSource.on(event_types.CHAT_CHANGED, async () => {
|
||||||
await onChatChanged();
|
await onChatChanged();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
export const cfgType = {
|
||||||
|
chat: 0,
|
||||||
|
chara: 1,
|
||||||
|
global: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
export const metadataKeys = {
|
||||||
|
guidance_scale: "cfg_guidance_scale",
|
||||||
|
negative_prompt: "cfg_negative_prompt",
|
||||||
|
positive_prompt: "cfg_positive_prompt",
|
||||||
|
prompt_combine: "cfg_prompt_combine",
|
||||||
|
groupchat_individual_chars: "cfg_groupchat_individual_chars",
|
||||||
|
prompt_insertion_depth: "cfg_prompt_insertion_depth",
|
||||||
|
prompt_separator: "cfg_prompt_separator"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the CFG guidance scale
|
||||||
|
// If the guidance scale is 1, ignore the CFG prompt(s) since it won't be used anyways
|
||||||
|
export function getGuidanceScale() {
|
||||||
|
if (!extension_settings.cfg) {
|
||||||
|
console.warn("CFG extension is not enabled. Skipping CFG guidance.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
|
||||||
|
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
|
||||||
|
const groupchatCharOverride = chat_metadata[metadataKeys.groupchat_individual_chars] ?? false;
|
||||||
|
|
||||||
|
if (chatGuidanceScale && chatGuidanceScale !== 1 && !groupchatCharOverride) {
|
||||||
|
return {
|
||||||
|
type: cfgType.chat,
|
||||||
|
value: chatGuidanceScale
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!selected_group && charaCfg || groupchatCharOverride) && charaCfg?.guidance_scale !== 1) {
|
||||||
|
return {
|
||||||
|
type: cfgType.chara,
|
||||||
|
value: charaCfg.guidance_scale
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extension_settings.cfg.global && extension_settings.cfg.global?.guidance_scale !== 1) {
|
||||||
|
return {
|
||||||
|
type: cfgType.global,
|
||||||
|
value: extension_settings.cfg.global.guidance_scale
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the CFG prompt separator.
|
||||||
|
* @returns {string} The CFG prompt separator
|
||||||
|
*/
|
||||||
|
function getCustomSeparator() {
|
||||||
|
const defaultSeparator = "\n";
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (chat_metadata[metadataKeys.prompt_separator]) {
|
||||||
|
return JSON.parse(chat_metadata[metadataKeys.prompt_separator]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultSeparator;
|
||||||
|
} catch {
|
||||||
|
console.warn("Invalid JSON detected for prompt separator. Using default separator.");
|
||||||
|
return defaultSeparator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the CFG prompt
|
||||||
|
export function getCfgPrompt(guidanceScale, isNegative) {
|
||||||
|
let splitCfgPrompt = [];
|
||||||
|
|
||||||
|
const cfgPromptCombine = chat_metadata[metadataKeys.prompt_combine] ?? [];
|
||||||
|
if (guidanceScale.type === cfgType.chat || cfgPromptCombine.includes(cfgType.chat)) {
|
||||||
|
splitCfgPrompt.unshift(
|
||||||
|
substituteParams(
|
||||||
|
chat_metadata[isNegative ? metadataKeys.negative_prompt : metadataKeys.positive_prompt]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
|
||||||
|
if (guidanceScale.type === cfgType.chara || cfgPromptCombine.includes(cfgType.chara)) {
|
||||||
|
splitCfgPrompt.unshift(
|
||||||
|
substituteParams(
|
||||||
|
isNegative ? charaCfg.negative_prompt : charaCfg.positive_prompt
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guidanceScale.type === cfgType.global || cfgPromptCombine.includes(cfgType.global)) {
|
||||||
|
splitCfgPrompt.unshift(
|
||||||
|
substituteParams(
|
||||||
|
isNegative ? extension_settings.cfg.global.negative_prompt : extension_settings.cfg.global.positive_prompt
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const customSeparator = getCustomSeparator();
|
||||||
|
const combinedCfgPrompt = splitCfgPrompt.filter((e) => e.length > 0).join(customSeparator);
|
||||||
|
const insertionDepth = chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1;
|
||||||
|
console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedCfgPrompt}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: combinedCfgPrompt,
|
||||||
|
depth: insertionDepth
|
||||||
|
};
|
||||||
|
}
|
@@ -11,7 +11,7 @@ export {
|
|||||||
ModuleWorkerWrapper,
|
ModuleWorkerWrapper,
|
||||||
};
|
};
|
||||||
|
|
||||||
let extensionNames = [];
|
export let extensionNames = [];
|
||||||
let manifests = {};
|
let manifests = {};
|
||||||
const defaultUrl = "http://localhost:5100";
|
const defaultUrl = "http://localhost:5100";
|
||||||
|
|
||||||
@@ -123,6 +123,7 @@ const extension_settings = {
|
|||||||
apiUrl: defaultUrl,
|
apiUrl: defaultUrl,
|
||||||
apiKey: '',
|
apiKey: '',
|
||||||
autoConnect: false,
|
autoConnect: false,
|
||||||
|
notifyUpdates: false,
|
||||||
disabledExtensions: [],
|
disabledExtensions: [],
|
||||||
expressionOverrides: [],
|
expressionOverrides: [],
|
||||||
memory: {},
|
memory: {},
|
||||||
@@ -367,6 +368,15 @@ function addExtensionsButtonAndMenu() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function notifyUpdatesInputHandler() {
|
||||||
|
extension_settings.notifyUpdates = !!$('#extensions_notify_updates').prop('checked');
|
||||||
|
saveSettingsDebounced();
|
||||||
|
|
||||||
|
if (extension_settings.notifyUpdates) {
|
||||||
|
checkForExtensionUpdates(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* $(document).on('click', function (e) {
|
/* $(document).on('click', function (e) {
|
||||||
const target = $(e.target);
|
const target = $(e.target);
|
||||||
if (target.is(dropdown)) return;
|
if (target.is(dropdown)) return;
|
||||||
@@ -582,16 +592,25 @@ async function showExtensionsDetails() {
|
|||||||
let htmlExternal = '<h3>External Extensions:</h3>';
|
let htmlExternal = '<h3>External Extensions:</h3>';
|
||||||
|
|
||||||
const extensions = Object.entries(manifests).sort((a, b) => a[1].loading_order - b[1].loading_order);
|
const extensions = Object.entries(manifests).sort((a, b) => a[1].loading_order - b[1].loading_order);
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
for (const extension of extensions) {
|
for (const extension of extensions) {
|
||||||
const { isExternal, extensionHtml } = await getExtensionData(extension);
|
promises.push(getExtensionData(extension));
|
||||||
if (isExternal) {
|
|
||||||
htmlExternal += extensionHtml;
|
|
||||||
} else {
|
|
||||||
htmlDefault += extensionHtml;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settledPromises = await Promise.allSettled(promises);
|
||||||
|
|
||||||
|
settledPromises.forEach(promise => {
|
||||||
|
if (promise.status === 'fulfilled') {
|
||||||
|
const { isExternal, extensionHtml } = promise.value;
|
||||||
|
if (isExternal) {
|
||||||
|
htmlExternal += extensionHtml;
|
||||||
|
} else {
|
||||||
|
htmlDefault += extensionHtml;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const html = `
|
const html = `
|
||||||
${getModuleInformation()}
|
${getModuleInformation()}
|
||||||
${htmlDefault}
|
${htmlDefault}
|
||||||
@@ -609,6 +628,15 @@ async function showExtensionsDetails() {
|
|||||||
*/
|
*/
|
||||||
async function onUpdateClick() {
|
async function onUpdateClick() {
|
||||||
const extensionName = $(this).data('name');
|
const extensionName = $(this).data('name');
|
||||||
|
await updateExtension(extensionName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a third-party extension via the API.
|
||||||
|
* @param {string} extensionName Extension folder name
|
||||||
|
* @param {boolean} quiet If true, don't show a success message
|
||||||
|
*/
|
||||||
|
async function updateExtension(extensionName, quiet) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/extensions/update', {
|
const response = await fetch('/api/extensions/update', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -618,15 +646,20 @@ async function onUpdateClick() {
|
|||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data.isUpToDate) {
|
if (data.isUpToDate) {
|
||||||
toastr.success('Extension is already up to date');
|
if (!quiet) {
|
||||||
|
toastr.success('Extension is already up to date');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toastr.success(`Extension updated to ${data.shortCommitHash}`);
|
toastr.success(`Extension ${extensionName} updated to ${data.shortCommitHash}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!quiet) {
|
||||||
|
showExtensionsDetails();
|
||||||
}
|
}
|
||||||
showExtensionsDetails();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the click event for the delete button of an extension.
|
* Handles the click event for the delete button of an extension.
|
||||||
@@ -639,23 +672,26 @@ async function onDeleteClick() {
|
|||||||
// use callPopup to create a popup for the user to confirm before delete
|
// use callPopup to create a popup for the user to confirm before delete
|
||||||
const confirmation = await callPopup(`Are you sure you want to delete ${extensionName}?`, 'delete_extension');
|
const confirmation = await callPopup(`Are you sure you want to delete ${extensionName}?`, 'delete_extension');
|
||||||
if (confirmation) {
|
if (confirmation) {
|
||||||
try {
|
await deleteExtension(extensionName);
|
||||||
const response = await fetch('/api/extensions/delete', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: getRequestHeaders(),
|
|
||||||
body: JSON.stringify({ extensionName })
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error:', error);
|
|
||||||
}
|
|
||||||
toastr.success(`Extension ${extensionName} deleted`);
|
|
||||||
showExtensionsDetails();
|
|
||||||
// reload the page to remove the extension from the list
|
|
||||||
location.reload();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export async function deleteExtension(extensionName) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/extensions/delete', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({ extensionName })
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
toastr.success(`Extension ${extensionName} deleted`);
|
||||||
|
showExtensionsDetails();
|
||||||
|
// reload the page to remove the extension from the list
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the version details of a specific extension.
|
* Fetches the version details of a specific extension.
|
||||||
@@ -680,9 +716,42 @@ async function getExtensionVersion(extensionName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs a third-party extension via the API.
|
||||||
|
* @param {string} url Extension repository URL
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function installExtension(url) {
|
||||||
|
console.debug('Extension installation started', url);
|
||||||
|
|
||||||
|
toastr.info('Please wait...', 'Installing extension');
|
||||||
|
|
||||||
async function loadExtensionSettings(settings) {
|
const request = await fetch('/api/extensions/install', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({ url }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!request.ok) {
|
||||||
|
const text = await request.text();
|
||||||
|
toastr.warning(text || request.statusText, 'Extension installation failed', { timeOut: 5000 });
|
||||||
|
console.error('Extension installation failed', request.status, request.statusText, text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await request.json();
|
||||||
|
toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been installed successfully!`, 'Extension installation successful');
|
||||||
|
console.debug(`Extension "${response.display_name}" has been installed successfully at ${response.extensionPath}`);
|
||||||
|
await loadExtensionSettings({}, false);
|
||||||
|
eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads extension settings from the app settings.
|
||||||
|
* @param {object} settings App Settings
|
||||||
|
* @param {boolean} versionChanged Is this a version change?
|
||||||
|
*/
|
||||||
|
async function loadExtensionSettings(settings, versionChanged) {
|
||||||
if (settings.extension_settings) {
|
if (settings.extension_settings) {
|
||||||
Object.assign(extension_settings, settings.extension_settings);
|
Object.assign(extension_settings, settings.extension_settings);
|
||||||
}
|
}
|
||||||
@@ -690,15 +759,80 @@ async function loadExtensionSettings(settings) {
|
|||||||
$("#extensions_url").val(extension_settings.apiUrl);
|
$("#extensions_url").val(extension_settings.apiUrl);
|
||||||
$("#extensions_api_key").val(extension_settings.apiKey);
|
$("#extensions_api_key").val(extension_settings.apiKey);
|
||||||
$("#extensions_autoconnect").prop('checked', extension_settings.autoConnect);
|
$("#extensions_autoconnect").prop('checked', extension_settings.autoConnect);
|
||||||
|
$("#extensions_notify_updates").prop('checked', extension_settings.notifyUpdates);
|
||||||
|
|
||||||
// Activate offline extensions
|
// Activate offline extensions
|
||||||
eventSource.emit(event_types.EXTENSIONS_FIRST_LOAD);
|
eventSource.emit(event_types.EXTENSIONS_FIRST_LOAD);
|
||||||
extensionNames = await discoverExtensions();
|
extensionNames = await discoverExtensions();
|
||||||
manifests = await getManifests(extensionNames)
|
manifests = await getManifests(extensionNames)
|
||||||
|
|
||||||
|
if (versionChanged) {
|
||||||
|
await autoUpdateExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
await activateExtensions();
|
await activateExtensions();
|
||||||
if (extension_settings.autoConnect && extension_settings.apiUrl) {
|
if (extension_settings.autoConnect && extension_settings.apiUrl) {
|
||||||
connectToApi(extension_settings.apiUrl);
|
connectToApi(extension_settings.apiUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extension_settings.notifyUpdates) {
|
||||||
|
checkForExtensionUpdates(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there are updates available for 3rd-party extensions.
|
||||||
|
* @param {boolean} force Skip nag check
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
async function checkForExtensionUpdates(force) {
|
||||||
|
if (!force) {
|
||||||
|
const STORAGE_NAG_KEY = 'extension_update_nag';
|
||||||
|
const currentDate = new Date().toDateString();
|
||||||
|
|
||||||
|
// Don't nag more than once a day
|
||||||
|
if (localStorage.getItem(STORAGE_NAG_KEY) === currentDate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(STORAGE_NAG_KEY, currentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatesAvailable = [];
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (const [id, manifest] of Object.entries(manifests)) {
|
||||||
|
if (manifest.auto_update && id.startsWith('third-party')) {
|
||||||
|
const promise = new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const data = await getExtensionVersion(id.replace('third-party', ''));
|
||||||
|
if (data.isUpToDate === false) {
|
||||||
|
updatesAvailable.push(manifest.display_name);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking for extension updates', error);
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
promises.push(promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.allSettled(promises);
|
||||||
|
|
||||||
|
if (updatesAvailable.length > 0) {
|
||||||
|
toastr.info(`${updatesAvailable.map(x => `• ${x}`).join('\n')}`, 'Extension updates available');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function autoUpdateExtensions() {
|
||||||
|
for (const [id, manifest] of Object.entries(manifests)) {
|
||||||
|
if (manifest.auto_update && id.startsWith('third-party')) {
|
||||||
|
console.debug(`Auto-updating 3rd-party extension: ${manifest.display_name} (${id})`);
|
||||||
|
await updateExtension(id.replace('third-party', ''), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runGenerationInterceptors(chat, contextSize) {
|
async function runGenerationInterceptors(chat, contextSize) {
|
||||||
@@ -721,8 +855,36 @@ jQuery(function () {
|
|||||||
$("#extensions_connect").on('click', connectClickHandler);
|
$("#extensions_connect").on('click', connectClickHandler);
|
||||||
$("#extensions_autoconnect").on('input', autoConnectInputHandler);
|
$("#extensions_autoconnect").on('input', autoConnectInputHandler);
|
||||||
$("#extensions_details").on('click', showExtensionsDetails);
|
$("#extensions_details").on('click', showExtensionsDetails);
|
||||||
|
$("#extensions_notify_updates").on('input', notifyUpdatesInputHandler);
|
||||||
$(document).on('click', '.toggle_disable', onDisableExtensionClick);
|
$(document).on('click', '.toggle_disable', onDisableExtensionClick);
|
||||||
$(document).on('click', '.toggle_enable', onEnableExtensionClick);
|
$(document).on('click', '.toggle_enable', onEnableExtensionClick);
|
||||||
$(document).on('click', '.btn_update', onUpdateClick);
|
$(document).on('click', '.btn_update', onUpdateClick);
|
||||||
$(document).on('click', '.btn_delete', onDeleteClick);
|
$(document).on('click', '.btn_delete', onDeleteClick);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the click event for the third-party extension import button.
|
||||||
|
* Prompts the user to enter the Git URL of the extension to import.
|
||||||
|
* After obtaining the Git URL, makes a POST request to '/api/extensions/install' to import the extension.
|
||||||
|
* If the extension is imported successfully, a success message is displayed.
|
||||||
|
* If the extension import fails, an error message is displayed and the error is logged to the console.
|
||||||
|
* After successfully importing the extension, the extension settings are reloaded and a 'EXTENSION_SETTINGS_LOADED' event is emitted.
|
||||||
|
*
|
||||||
|
* @listens #third_party_extension_button#click - The click event of the '#third_party_extension_button' element.
|
||||||
|
*/
|
||||||
|
$('#third_party_extension_button').on('click', async () => {
|
||||||
|
const html = `<h3>Enter the Git URL of the extension to install</h3>
|
||||||
|
<br>
|
||||||
|
<p><b>Disclaimer:</b> Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.</p>
|
||||||
|
<br>
|
||||||
|
<p>Example: <tt> https://github.com/author/extension-name </tt></p>`
|
||||||
|
const input = await callPopup(html, 'input');
|
||||||
|
|
||||||
|
if (!input) {
|
||||||
|
console.debug('Extension install cancelled');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = input.trim();
|
||||||
|
await installExtension(url);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
9
public/scripts/extensions/assets/confirm.html
Normal file
9
public/scripts/extensions/assets/confirm.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="m-b-1">
|
||||||
|
Are you sure you want to connect to '{{url}}'?
|
||||||
|
</div>
|
||||||
|
<div class="flex-container justifyCenter">
|
||||||
|
<label class="checkbox_label" for="assets-remember">
|
||||||
|
<input type="checkbox" id="assets-remember">
|
||||||
|
Don't ask again for this URL
|
||||||
|
</label>
|
||||||
|
</div>
|
@@ -1,14 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
- Check failed install file (0kb size ?)
|
|
||||||
*/
|
*/
|
||||||
//const DEBUG_TONY_SAMA_FORK_MODE = false
|
//const DEBUG_TONY_SAMA_FORK_MODE = true
|
||||||
|
|
||||||
import { getRequestHeaders, callPopup } from "../../../script.js";
|
import { getRequestHeaders, callPopup } from "../../../script.js";
|
||||||
|
import { deleteExtension, extensionNames, installExtension, renderExtensionTemplate } from "../../extensions.js";
|
||||||
|
import { getStringHash, isValidUrl } from "../../utils.js";
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = 'Assets';
|
const MODULE_NAME = 'assets';
|
||||||
const DEBUG_PREFIX = "<Assets module> ";
|
const DEBUG_PREFIX = "<Assets module> ";
|
||||||
|
let previewAudio = null;
|
||||||
let ASSETS_JSON_URL = "https://raw.githubusercontent.com/SillyTavern/SillyTavern-Content/main/index.json"
|
let ASSETS_JSON_URL = "https://raw.githubusercontent.com/SillyTavern/SillyTavern-Content/main/index.json"
|
||||||
|
|
||||||
const extensionName = "assets";
|
const extensionName = "assets";
|
||||||
@@ -29,7 +31,7 @@ const defaultSettings = {
|
|||||||
|
|
||||||
function downloadAssetsList(url) {
|
function downloadAssetsList(url) {
|
||||||
updateCurrentAssets().then(function () {
|
updateCurrentAssets().then(function () {
|
||||||
fetch(url)
|
fetch(url, { cache: "no-cache" })
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(json => {
|
.then(json => {
|
||||||
|
|
||||||
@@ -47,10 +49,20 @@ function downloadAssetsList(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.debug(DEBUG_PREFIX, "Updated available assets to", availableAssets);
|
console.debug(DEBUG_PREFIX, "Updated available assets to", availableAssets);
|
||||||
|
// First extensions, then everything else
|
||||||
|
const assetTypes = Object.keys(availableAssets).sort((a, b) => (a === 'extension') ? -1 : (b === 'extension') ? 1 : 0);
|
||||||
|
|
||||||
for (const assetType in availableAssets) {
|
for (const assetType of assetTypes) {
|
||||||
let assetTypeMenu = $('<div />', { id: "assets_audio_ambient_div", class: "assets-list-div" });
|
let assetTypeMenu = $('<div />', { id: "assets_audio_ambient_div", class: "assets-list-div" });
|
||||||
assetTypeMenu.append(`<h3>${assetType}</h3>`)
|
assetTypeMenu.append(`<h3>${assetType}</h3>`)
|
||||||
|
|
||||||
|
if (assetType == 'extension') {
|
||||||
|
assetTypeMenu.append(`
|
||||||
|
<div class="assets-list-git">
|
||||||
|
To download extensions from this page, you need to have <a href="https://git-scm.com/downloads" target="_blank">Git</a> installed.
|
||||||
|
</div>`);
|
||||||
|
}
|
||||||
|
|
||||||
for (const i in availableAssets[assetType]) {
|
for (const i in availableAssets[assetType]) {
|
||||||
const asset = availableAssets[assetType][i];
|
const asset = availableAssets[assetType][i];
|
||||||
const elemId = `assets_install_${assetType}_${i}`;
|
const elemId = `assets_install_${assetType}_${i}`;
|
||||||
@@ -59,7 +71,7 @@ function downloadAssetsList(url) {
|
|||||||
element.append(label);
|
element.append(label);
|
||||||
|
|
||||||
//if (DEBUG_TONY_SAMA_FORK_MODE)
|
//if (DEBUG_TONY_SAMA_FORK_MODE)
|
||||||
// assetUrl = assetUrl.replace("https://github.com/SillyTavern/","https://github.com/Tony-sama/"); // DBG
|
// asset["url"] = asset["url"].replace("https://github.com/SillyTavern/","https://github.com/Tony-sama/"); // DBG
|
||||||
|
|
||||||
console.debug(DEBUG_PREFIX, "Checking asset", asset["id"], asset["url"]);
|
console.debug(DEBUG_PREFIX, "Checking asset", asset["id"], asset["url"]);
|
||||||
|
|
||||||
@@ -71,18 +83,18 @@ function downloadAssetsList(url) {
|
|||||||
label.addClass("fa-check");
|
label.addClass("fa-check");
|
||||||
this.classList.remove('asset-download-button-loading');
|
this.classList.remove('asset-download-button-loading');
|
||||||
element.on("click", assetDelete);
|
element.on("click", assetDelete);
|
||||||
element.on("mouseenter", function(){
|
element.on("mouseenter", function () {
|
||||||
label.removeClass("fa-check");
|
label.removeClass("fa-check");
|
||||||
label.addClass("fa-trash");
|
label.addClass("fa-trash");
|
||||||
label.addClass("redOverlayGlow");
|
label.addClass("redOverlayGlow");
|
||||||
}).on("mouseleave", function(){
|
}).on("mouseleave", function () {
|
||||||
label.addClass("fa-check");
|
label.addClass("fa-check");
|
||||||
label.removeClass("fa-trash");
|
label.removeClass("fa-trash");
|
||||||
label.removeClass("redOverlayGlow");
|
label.removeClass("redOverlayGlow");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const assetDelete = async function() {
|
const assetDelete = async function () {
|
||||||
element.off("click");
|
element.off("click");
|
||||||
await deleteAsset(assetType, asset["id"]);
|
await deleteAsset(assetType, asset["id"]);
|
||||||
label.removeClass("fa-check");
|
label.removeClass("fa-check");
|
||||||
@@ -98,11 +110,11 @@ function downloadAssetsList(url) {
|
|||||||
label.toggleClass("fa-download");
|
label.toggleClass("fa-download");
|
||||||
label.toggleClass("fa-check");
|
label.toggleClass("fa-check");
|
||||||
element.on("click", assetDelete);
|
element.on("click", assetDelete);
|
||||||
element.on("mouseenter", function(){
|
element.on("mouseenter", function () {
|
||||||
label.removeClass("fa-check");
|
label.removeClass("fa-check");
|
||||||
label.addClass("fa-trash");
|
label.addClass("fa-trash");
|
||||||
label.addClass("redOverlayGlow");
|
label.addClass("redOverlayGlow");
|
||||||
}).on("mouseleave", function(){
|
}).on("mouseleave", function () {
|
||||||
label.addClass("fa-check");
|
label.addClass("fa-check");
|
||||||
label.removeClass("fa-trash");
|
label.removeClass("fa-trash");
|
||||||
label.removeClass("redOverlayGlow");
|
label.removeClass("redOverlayGlow");
|
||||||
@@ -114,14 +126,28 @@ function downloadAssetsList(url) {
|
|||||||
element.on("click", assetInstall);
|
element.on("click", assetInstall);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug(DEBUG_PREFIX, "Created element for BGM", asset["id"])
|
console.debug(DEBUG_PREFIX, "Created element for ", asset["id"])
|
||||||
|
|
||||||
|
const displayName = DOMPurify.sanitize(asset["name"] || asset["id"]);
|
||||||
|
const description = DOMPurify.sanitize(asset["description"] || "");
|
||||||
|
const url = isValidUrl(asset["url"]) ? asset["url"] : "";
|
||||||
|
const previewIcon = assetType == 'extension' ? 'fa-arrow-up-right-from-square' : 'fa-headphones-simple';
|
||||||
|
|
||||||
$(`<i></i>`)
|
$(`<i></i>`)
|
||||||
.append(element)
|
.append(element)
|
||||||
.append(`<span>${asset["id"]}</span>`)
|
.append(`<div class="flex-container flexFlowColumn">
|
||||||
|
<span class="flex-container alignitemscenter">
|
||||||
|
<b>${displayName}</b>
|
||||||
|
<a class="asset_preview" href="${url}" target="_blank" title="Preview in browser">
|
||||||
|
<i class="fa-solid fa-sm ${previewIcon}"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span>${description}</span>
|
||||||
|
</div>`)
|
||||||
.appendTo(assetTypeMenu);
|
.appendTo(assetTypeMenu);
|
||||||
}
|
}
|
||||||
assetTypeMenu.appendTo("#assets_menu");
|
assetTypeMenu.appendTo("#assets_menu");
|
||||||
|
assetTypeMenu.on('click', 'a.asset_preview', previewAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#assets_menu").show();
|
$("#assets_menu").show();
|
||||||
@@ -135,8 +161,37 @@ function downloadAssetsList(url) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function previewAsset(e) {
|
||||||
|
const href = $(this).attr('href');
|
||||||
|
const audioExtensions = ['.mp3', '.ogg', '.wav'];
|
||||||
|
|
||||||
|
if (audioExtensions.some(ext => href.endsWith(ext))) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (previewAudio) {
|
||||||
|
previewAudio.pause();
|
||||||
|
|
||||||
|
if (previewAudio.src === href) {
|
||||||
|
previewAudio = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previewAudio = new Audio(href);
|
||||||
|
previewAudio.play();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isAssetInstalled(assetType, filename) {
|
function isAssetInstalled(assetType, filename) {
|
||||||
for (const i of currentAssets[assetType]) {
|
let assetList = currentAssets[assetType];
|
||||||
|
|
||||||
|
if (assetType == 'extension') {
|
||||||
|
const thirdPartyMarker = "third-party/";
|
||||||
|
assetList = extensionNames.filter(x => x.startsWith(thirdPartyMarker)).map(x => x.replace(thirdPartyMarker, ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const i of assetList) {
|
||||||
//console.debug(DEBUG_PREFIX,i,filename)
|
//console.debug(DEBUG_PREFIX,i,filename)
|
||||||
if (i.includes(filename))
|
if (i.includes(filename))
|
||||||
return true;
|
return true;
|
||||||
@@ -149,6 +204,13 @@ async function installAsset(url, assetType, filename) {
|
|||||||
console.debug(DEBUG_PREFIX, "Downloading ", url);
|
console.debug(DEBUG_PREFIX, "Downloading ", url);
|
||||||
const category = assetType;
|
const category = assetType;
|
||||||
try {
|
try {
|
||||||
|
if (category === 'extension') {
|
||||||
|
console.debug(DEBUG_PREFIX, "Installing extension ", url)
|
||||||
|
await installExtension(url);
|
||||||
|
console.debug(DEBUG_PREFIX, "Extension installed.")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const body = { url, category, filename };
|
const body = { url, category, filename };
|
||||||
const result = await fetch('/api/assets/download', {
|
const result = await fetch('/api/assets/download', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -170,6 +232,12 @@ async function deleteAsset(assetType, filename) {
|
|||||||
console.debug(DEBUG_PREFIX, "Deleting ", assetType, filename);
|
console.debug(DEBUG_PREFIX, "Deleting ", assetType, filename);
|
||||||
const category = assetType;
|
const category = assetType;
|
||||||
try {
|
try {
|
||||||
|
if (category === 'extension') {
|
||||||
|
console.debug(DEBUG_PREFIX, "Deleting extension ", filename)
|
||||||
|
await deleteExtension(filename);
|
||||||
|
console.debug(DEBUG_PREFIX, "Extension deleted.")
|
||||||
|
}
|
||||||
|
|
||||||
const body = { category, filename };
|
const body = { category, filename };
|
||||||
const result = await fetch('/api/assets/delete', {
|
const result = await fetch('/api/assets/delete', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -214,24 +282,35 @@ async function updateCurrentAssets() {
|
|||||||
// This function is called when the extension is loaded
|
// This function is called when the extension is loaded
|
||||||
jQuery(async () => {
|
jQuery(async () => {
|
||||||
// This is an example of loading HTML from a file
|
// This is an example of loading HTML from a file
|
||||||
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
|
const windowHtml = $(renderExtensionTemplate(MODULE_NAME, 'window', {}));
|
||||||
|
|
||||||
const assetsJsonUrl = windowHtml.find('#assets-json-url-field');
|
const assetsJsonUrl = windowHtml.find('#assets-json-url-field');
|
||||||
assetsJsonUrl.val(ASSETS_JSON_URL);
|
assetsJsonUrl.val(ASSETS_JSON_URL);
|
||||||
|
|
||||||
const connectButton = windowHtml.find('#assets-connect-button');
|
const connectButton = windowHtml.find('#assets-connect-button');
|
||||||
connectButton.on("click", async function () {
|
connectButton.on("click", async function () {
|
||||||
const confirmation = await callPopup(`Are you sure you want to connect to '${assetsJsonUrl.val()}'?`, 'confirm')
|
const url = String(assetsJsonUrl.val());
|
||||||
|
const rememberKey = `Assets_SkipConfirm_${getStringHash(url)}`;
|
||||||
|
const skipConfirm = localStorage.getItem(rememberKey) === 'true';
|
||||||
|
|
||||||
|
const template = renderExtensionTemplate(MODULE_NAME, 'confirm', { url });
|
||||||
|
const confirmation = skipConfirm || await callPopup(template, 'confirm');
|
||||||
|
|
||||||
if (confirmation) {
|
if (confirmation) {
|
||||||
try {
|
try {
|
||||||
|
if (!skipConfirm) {
|
||||||
|
const rememberValue = Boolean($('#assets-remember').prop('checked'));
|
||||||
|
localStorage.setItem(rememberKey, String(rememberValue));
|
||||||
|
}
|
||||||
|
|
||||||
console.debug(DEBUG_PREFIX, "Confimation, loading assets...");
|
console.debug(DEBUG_PREFIX, "Confimation, loading assets...");
|
||||||
downloadAssetsList(assetsJsonUrl.val());
|
downloadAssetsList(url);
|
||||||
connectButton.removeClass("fa-plug-circle-exclamation");
|
connectButton.removeClass("fa-plug-circle-exclamation");
|
||||||
connectButton.removeClass("redOverlayGlow");
|
connectButton.removeClass("redOverlayGlow");
|
||||||
connectButton.addClass("fa-plug-circle-check");
|
connectButton.addClass("fa-plug-circle-check");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
toastr.error(`Cannot get assets list from ${assetsJsonUrl.val()}`);
|
toastr.error(`Cannot get assets list from ${url}`);
|
||||||
connectButton.removeClass("fa-plug-circle-check");
|
connectButton.removeClass("fa-plug-circle-check");
|
||||||
connectButton.addClass("fa-plug-circle-exclamation");
|
connectButton.addClass("fa-plug-circle-exclamation");
|
||||||
connectButton.removeClass("redOverlayGlow");
|
connectButton.removeClass("redOverlayGlow");
|
||||||
|
@@ -13,18 +13,37 @@
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.assets-list-git {
|
||||||
|
font-size: calc(var(--mainFontSize) * 0.8);
|
||||||
|
opacity: 0.8;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assets-list-div h3 {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assets-list-div i a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.assets-list-div i {
|
.assets-list-div i {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.assets-list-div i span{
|
.assets-list-div i span {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.assets-list-div i span:first-of-type {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.asset-download-button {
|
.asset-download-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@@ -33,8 +52,8 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.asset-download-button:active {
|
.asset-download-button:active {
|
||||||
background: #007a63;
|
background: #007a63;
|
||||||
}
|
}
|
||||||
@@ -67,13 +86,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes asset-download-button-loading-spinner {
|
@keyframes asset-download-button-loading-spinner {
|
||||||
from {
|
from {
|
||||||
transform: rotate(0turn);
|
transform: rotate(0turn);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: rotate(1turn);
|
transform: rotate(1turn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -1,7 +1,7 @@
|
|||||||
<div id="assets_ui">
|
<div id="assets_ui">
|
||||||
<div class="inline-drawer">
|
<div class="inline-drawer">
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
<div class="inline-drawer-toggle inline-drawer-header">
|
||||||
<b>Assets</b>
|
<b>Download Extensions & Assets</b>
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-drawer-content">
|
<div class="inline-drawer-content">
|
||||||
|
@@ -1,917 +0,0 @@
|
|||||||
/*
|
|
||||||
Ideas:
|
|
||||||
- Clean design of new ui
|
|
||||||
- change select text versus options for playing: audio
|
|
||||||
- cross fading between bgm / start a different time
|
|
||||||
- fading should appear before end when switching randomly
|
|
||||||
- Background based ambient sounds
|
|
||||||
- import option on background UI ?
|
|
||||||
- Allow background music edition using background menu
|
|
||||||
- https://fontawesome.com/icons/music?f=classic&s=solid
|
|
||||||
- https://codepen.io/noirsociety/pen/rNQxQwm
|
|
||||||
- https://codepen.io/xrocker/pen/abdKVGy
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { saveSettingsDebounced, getRequestHeaders } from "../../../script.js";
|
|
||||||
import { getContext, extension_settings, ModuleWorkerWrapper } from "../../extensions.js";
|
|
||||||
import { isDataURL } from "../../utils.js";
|
|
||||||
export { MODULE_NAME };
|
|
||||||
|
|
||||||
const extensionName = "audio";
|
|
||||||
const extensionFolderPath = `scripts/extensions/${extensionName}`;
|
|
||||||
|
|
||||||
const MODULE_NAME = 'Audio';
|
|
||||||
const DEBUG_PREFIX = "<Audio module> ";
|
|
||||||
const UPDATE_INTERVAL = 1000;
|
|
||||||
|
|
||||||
const ASSETS_BGM_FOLDER = "bgm";
|
|
||||||
const ASSETS_AMBIENT_FOLDER = "ambient";
|
|
||||||
const CHARACTER_BGM_FOLDER = "bgm"
|
|
||||||
|
|
||||||
const FALLBACK_EXPRESSION = "neutral";
|
|
||||||
const DEFAULT_EXPRESSIONS = [
|
|
||||||
//"talkinghead",
|
|
||||||
"admiration",
|
|
||||||
"amusement",
|
|
||||||
"anger",
|
|
||||||
"annoyance",
|
|
||||||
"approval",
|
|
||||||
"caring",
|
|
||||||
"confusion",
|
|
||||||
"curiosity",
|
|
||||||
"desire",
|
|
||||||
"disappointment",
|
|
||||||
"disapproval",
|
|
||||||
"disgust",
|
|
||||||
"embarrassment",
|
|
||||||
"excitement",
|
|
||||||
"fear",
|
|
||||||
"gratitude",
|
|
||||||
"grief",
|
|
||||||
"joy",
|
|
||||||
"love",
|
|
||||||
"nervousness",
|
|
||||||
"optimism",
|
|
||||||
"pride",
|
|
||||||
"realization",
|
|
||||||
"relief",
|
|
||||||
"remorse",
|
|
||||||
"sadness",
|
|
||||||
"surprise",
|
|
||||||
"neutral"
|
|
||||||
];
|
|
||||||
const SPRITE_DOM_ID = "#expression-image";
|
|
||||||
|
|
||||||
let current_chat_id = null
|
|
||||||
|
|
||||||
let fallback_BGMS = null; // Initialized only once with module workers
|
|
||||||
let ambients = null; // Initialized only once with module workers
|
|
||||||
let characterMusics = {}; // Updated with module workers
|
|
||||||
|
|
||||||
let currentCharacterBGM = null;
|
|
||||||
let currentExpressionBGM = null;
|
|
||||||
let currentBackground = null;
|
|
||||||
|
|
||||||
let cooldownBGM = 0;
|
|
||||||
|
|
||||||
let bgmEnded = true;
|
|
||||||
|
|
||||||
//#############################//
|
|
||||||
// Extension UI and Settings //
|
|
||||||
//#############################//
|
|
||||||
|
|
||||||
const defaultSettings = {
|
|
||||||
enabled: false,
|
|
||||||
dynamic_bgm_enabled: false,
|
|
||||||
//dynamic_ambient_enabled: false,
|
|
||||||
|
|
||||||
bgm_locked: true,
|
|
||||||
bgm_muted: true,
|
|
||||||
bgm_volume: 50,
|
|
||||||
bgm_selected: null,
|
|
||||||
|
|
||||||
ambient_locked: true,
|
|
||||||
ambient_muted: true,
|
|
||||||
ambient_volume: 50,
|
|
||||||
ambient_selected: null,
|
|
||||||
|
|
||||||
bgm_cooldown: 30
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadSettings() {
|
|
||||||
if (extension_settings.audio === undefined)
|
|
||||||
extension_settings.audio = {};
|
|
||||||
|
|
||||||
if (Object.keys(extension_settings.audio).length === 0) {
|
|
||||||
Object.assign(extension_settings.audio, defaultSettings)
|
|
||||||
}
|
|
||||||
$("#audio_enabled").prop('checked', extension_settings.audio.enabled);
|
|
||||||
$("#audio_dynamic_bgm_enabled").prop('checked', extension_settings.audio.dynamic_bgm_enabled);
|
|
||||||
//$("#audio_dynamic_ambient_enabled").prop('checked', extension_settings.audio.dynamic_ambient_enabled);
|
|
||||||
|
|
||||||
$("#audio_bgm_volume").text(extension_settings.audio.bgm_volume);
|
|
||||||
$("#audio_ambient_volume").text(extension_settings.audio.ambient_volume);
|
|
||||||
|
|
||||||
$("#audio_bgm_volume_slider").val(extension_settings.audio.bgm_volume);
|
|
||||||
$("#audio_ambient_volume_slider").val(extension_settings.audio.ambient_volume);
|
|
||||||
|
|
||||||
if (extension_settings.audio.bgm_muted) {
|
|
||||||
$("#audio_bgm_mute_icon").removeClass("fa-volume-high");
|
|
||||||
$("#audio_bgm_mute_icon").addClass("fa-volume-mute");
|
|
||||||
$("#audio_bgm_mute").addClass("redOverlayGlow");
|
|
||||||
$("#audio_bgm").prop("muted", true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#audio_bgm_mute_icon").addClass("fa-volume-high");
|
|
||||||
$("#audio_bgm_mute_icon").removeClass("fa-volume-mute");
|
|
||||||
$("#audio_bgm_mute").removeClass("redOverlayGlow");
|
|
||||||
$("#audio_bgm").prop("muted", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extension_settings.audio.bgm_locked) {
|
|
||||||
//$("#audio_bgm_lock_icon").removeClass("fa-lock-open");
|
|
||||||
//$("#audio_bgm_lock_icon").addClass("fa-lock");
|
|
||||||
$("#audio_bgm").attr("loop", true);
|
|
||||||
$("#audio_bgm_lock").addClass("redOverlayGlow");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//$("#audio_bgm_lock_icon").removeClass("fa-lock");
|
|
||||||
//$("#audio_bgm_lock_icon").addClass("fa-lock-open");
|
|
||||||
$("#audio_bgm").attr("loop", false);
|
|
||||||
$("#audio_bgm_lock").removeClass("redOverlayGlow");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (extension_settings.audio.bgm_selected !== null) {
|
|
||||||
$("#audio_bgm_select").append(new Option(extension_settings.audio.bgm_selected, extension_settings.audio.bgm_selected));
|
|
||||||
$("#audio_bgm_select").val(extension_settings.audio.bgm_selected);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (extension_settings.audio.ambient_locked) {
|
|
||||||
$("#audio_ambient_lock_icon").removeClass("fa-lock-open");
|
|
||||||
$("#audio_ambient_lock_icon").addClass("fa-lock");
|
|
||||||
$("#audio_ambient_lock").addClass("redOverlayGlow");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#audio_ambient_lock_icon").removeClass("fa-lock");
|
|
||||||
$("#audio_ambient_lock_icon").addClass("fa-lock-open");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (extension_settings.audio.ambient_selected !== null) {
|
|
||||||
$("#audio_ambient_select").append(new Option(extension_settings.audio.ambient_selected, extension_settings.audio.ambient_selected));
|
|
||||||
$("#audio_ambient_select").val(extension_settings.audio.ambient_selected);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (extension_settings.audio.ambient_muted) {
|
|
||||||
$("#audio_ambient_mute_icon").removeClass("fa-volume-high");
|
|
||||||
$("#audio_ambient_mute_icon").addClass("fa-volume-mute");
|
|
||||||
$("#audio_ambient_mute").addClass("redOverlayGlow");
|
|
||||||
$("#audio_ambient").prop("muted", true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#audio_ambient_mute_icon").addClass("fa-volume-high");
|
|
||||||
$("#audio_ambient_mute_icon").removeClass("fa-volume-mute");
|
|
||||||
$("#audio_ambient_mute").removeClass("redOverlayGlow");
|
|
||||||
$("#audio_ambient").prop("muted", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#audio_bgm_cooldown").val(extension_settings.audio.bgm_cooldown);
|
|
||||||
|
|
||||||
$("#audio_debug_div").hide(); // DBG: comment to see debug mode
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onEnabledClick() {
|
|
||||||
extension_settings.audio.enabled = $('#audio_enabled').is(':checked');
|
|
||||||
if (extension_settings.audio.enabled) {
|
|
||||||
if ($("#audio_bgm").attr("src") != "")
|
|
||||||
$("#audio_bgm")[0].play();
|
|
||||||
if ($("#audio_ambient").attr("src") != "")
|
|
||||||
$("#audio_ambient")[0].play();
|
|
||||||
} else {
|
|
||||||
$("#audio_bgm")[0].pause();
|
|
||||||
$("#audio_ambient")[0].pause();
|
|
||||||
}
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onDynamicBGMEnabledClick() {
|
|
||||||
extension_settings.audio.dynamic_bgm_enabled = $('#audio_dynamic_bgm_enabled').is(':checked');
|
|
||||||
currentCharacterBGM = null;
|
|
||||||
currentExpressionBGM = null;
|
|
||||||
cooldownBGM = 0;
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
async function onDynamicAmbientEnabledClick() {
|
|
||||||
extension_settings.audio.dynamic_ambient_enabled = $('#audio_dynamic_ambient_enabled').is(':checked');
|
|
||||||
currentBackground = null;
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
async function onBGMLockClick() {
|
|
||||||
extension_settings.audio.bgm_locked = !extension_settings.audio.bgm_locked;
|
|
||||||
if (extension_settings.audio.bgm_locked) {
|
|
||||||
extension_settings.audio.bgm_selected = $("#audio_bgm_select").val();
|
|
||||||
$("#audio_bgm").attr("loop", true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#audio_bgm").attr("loop", false);
|
|
||||||
}
|
|
||||||
//$("#audio_bgm_lock_icon").toggleClass("fa-lock");
|
|
||||||
//$("#audio_bgm_lock_icon").toggleClass("fa-lock-open");
|
|
||||||
$("#audio_bgm_lock").toggleClass("redOverlayGlow");
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onBGMRandomClick() {
|
|
||||||
var select = document.getElementById('audio_bgm_select');
|
|
||||||
var items = select.getElementsByTagName('option');
|
|
||||||
|
|
||||||
if (items.length < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var index;
|
|
||||||
do {
|
|
||||||
index = Math.floor(Math.random() * items.length);
|
|
||||||
} while (index == select.selectedIndex);
|
|
||||||
|
|
||||||
select.selectedIndex = index;
|
|
||||||
onBGMSelectChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onBGMMuteClick() {
|
|
||||||
extension_settings.audio.bgm_muted = !extension_settings.audio.bgm_muted;
|
|
||||||
$("#audio_bgm_mute_icon").toggleClass("fa-volume-high");
|
|
||||||
$("#audio_bgm_mute_icon").toggleClass("fa-volume-mute");
|
|
||||||
$("#audio_bgm").prop("muted", !$("#audio_bgm").prop("muted"));
|
|
||||||
$("#audio_bgm_mute").toggleClass("redOverlayGlow");
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onAmbientLockClick() {
|
|
||||||
extension_settings.audio.ambient_locked = !extension_settings.audio.ambient_locked;
|
|
||||||
if (extension_settings.audio.ambient_locked)
|
|
||||||
extension_settings.audio.ambient_selected = $("#audio_ambient_select").val();
|
|
||||||
else {
|
|
||||||
extension_settings.audio.ambient_selected = null;
|
|
||||||
currentBackground = null;
|
|
||||||
}
|
|
||||||
$("#audio_ambient_lock_icon").toggleClass("fa-lock");
|
|
||||||
$("#audio_ambient_lock_icon").toggleClass("fa-lock-open");
|
|
||||||
$("#audio_ambient_lock").toggleClass("redOverlayGlow");
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onAmbientMuteClick() {
|
|
||||||
extension_settings.audio.ambient_muted = !extension_settings.audio.ambient_muted;
|
|
||||||
$("#audio_ambient_mute_icon").toggleClass("fa-volume-high");
|
|
||||||
$("#audio_ambient_mute_icon").toggleClass("fa-volume-mute");
|
|
||||||
$("#audio_ambient").prop("muted", !$("#audio_ambient").prop("muted"));
|
|
||||||
$("#audio_ambient_mute").toggleClass("redOverlayGlow");
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onBGMVolumeChange() {
|
|
||||||
extension_settings.audio.bgm_volume = ~~($("#audio_bgm_volume_slider").val());
|
|
||||||
$("#audio_bgm").prop("volume", extension_settings.audio.bgm_volume * 0.01);
|
|
||||||
$("#audio_bgm_volume").text(extension_settings.audio.bgm_volume);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
//console.debug(DEBUG_PREFIX,"UPDATED BGM MAX TO",extension_settings.audio.bgm_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onAmbientVolumeChange() {
|
|
||||||
extension_settings.audio.ambient_volume = ~~($("#audio_ambient_volume_slider").val());
|
|
||||||
$("#audio_ambient").prop("volume", extension_settings.audio.ambient_volume * 0.01);
|
|
||||||
$("#audio_ambient_volume").text(extension_settings.audio.ambient_volume);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
//console.debug(DEBUG_PREFIX,"UPDATED Ambient MAX TO",extension_settings.audio.ambient_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onBGMSelectChange() {
|
|
||||||
extension_settings.audio.bgm_selected = $("#audio_bgm_select").val();
|
|
||||||
updateBGM(true);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
//console.debug(DEBUG_PREFIX,"UPDATED BGM MAX TO",extension_settings.audio.bgm_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onAmbientSelectChange() {
|
|
||||||
extension_settings.audio.ambient_selected = $("#audio_ambient_select").val();
|
|
||||||
updateAmbient(true);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
//console.debug(DEBUG_PREFIX,"UPDATED BGM MAX TO",extension_settings.audio.bgm_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onBGMCooldownInput() {
|
|
||||||
extension_settings.audio.bgm_cooldown = ~~($("#audio_bgm_cooldown").val());
|
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
|
||||||
saveSettingsDebounced();
|
|
||||||
console.debug(DEBUG_PREFIX, "UPDATED BGM cooldown to", extension_settings.audio.bgm_cooldown);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#############################//
|
|
||||||
// API Calls //
|
|
||||||
//#############################//
|
|
||||||
|
|
||||||
async function getAssetsList(type) {
|
|
||||||
console.debug(DEBUG_PREFIX, "getting assets of type", type);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await fetch(`/api/assets/get`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: getRequestHeaders(),
|
|
||||||
});
|
|
||||||
const assets = result.ok ? (await result.json()) : { type: [] };
|
|
||||||
console.debug(DEBUG_PREFIX, "Found assets:", assets);
|
|
||||||
return assets[type];
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCharacterBgmList(name) {
|
|
||||||
console.debug(DEBUG_PREFIX, "getting bgm list for", name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await fetch(`/api/assets/character?name=${encodeURIComponent(name)}&category=${CHARACTER_BGM_FOLDER}`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: getRequestHeaders(),
|
|
||||||
});
|
|
||||||
let musics = result.ok ? (await result.json()) : [];
|
|
||||||
return musics;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#############################//
|
|
||||||
// Module Worker //
|
|
||||||
//#############################//
|
|
||||||
|
|
||||||
function fillBGMSelect() {
|
|
||||||
let found_last_selected_bgm = false;
|
|
||||||
// Update bgm list in UI
|
|
||||||
$("#audio_bgm_select")
|
|
||||||
.find('option')
|
|
||||||
.remove();
|
|
||||||
|
|
||||||
for (const file of fallback_BGMS) {
|
|
||||||
$('#audio_bgm_select').append(new Option("asset: " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
|
||||||
if (file === extension_settings.audio.bgm_selected) {
|
|
||||||
$('#audio_bgm_select').val(extension_settings.audio.bgm_selected);
|
|
||||||
found_last_selected_bgm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update bgm list in UI
|
|
||||||
for (const char in characterMusics)
|
|
||||||
for (const e in characterMusics[char])
|
|
||||||
for (const file of characterMusics[char][e]) {
|
|
||||||
$('#audio_bgm_select').append(new Option(char + ": " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
|
||||||
if (file === extension_settings.audio.bgm_selected) {
|
|
||||||
$('#audio_bgm_select').val(extension_settings.audio.bgm_selected);
|
|
||||||
found_last_selected_bgm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_last_selected_bgm) {
|
|
||||||
$('#audio_bgm_select').val($("#audio_bgm_select option:first").val());
|
|
||||||
extension_settings.audio.bgm_selected = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- Update ambient sound
|
|
||||||
- Update character BGM
|
|
||||||
- Solo dynamique expression
|
|
||||||
- Group only neutral bgm
|
|
||||||
*/
|
|
||||||
async function moduleWorker() {
|
|
||||||
const moduleEnabled = extension_settings.audio.enabled;
|
|
||||||
|
|
||||||
if (moduleEnabled) {
|
|
||||||
|
|
||||||
if (cooldownBGM > 0)
|
|
||||||
cooldownBGM -= UPDATE_INTERVAL;
|
|
||||||
|
|
||||||
if (fallback_BGMS == null) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Updating audio bgm assets...");
|
|
||||||
fallback_BGMS = await getAssetsList(ASSETS_BGM_FOLDER);
|
|
||||||
fallback_BGMS = fallback_BGMS.filter((filename) => filename != ".placeholder")
|
|
||||||
console.debug(DEBUG_PREFIX, "Detected assets:", fallback_BGMS);
|
|
||||||
|
|
||||||
fillBGMSelect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ambients == null) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Updating audio ambient assets...");
|
|
||||||
ambients = await getAssetsList(ASSETS_AMBIENT_FOLDER);
|
|
||||||
ambients = ambients.filter((filename) => filename != ".placeholder")
|
|
||||||
console.debug(DEBUG_PREFIX, "Detected assets:", ambients);
|
|
||||||
|
|
||||||
// Update bgm list in UI
|
|
||||||
$("#audio_ambient_select")
|
|
||||||
.find('option')
|
|
||||||
.remove();
|
|
||||||
|
|
||||||
if (extension_settings.audio.ambient_selected !== null) {
|
|
||||||
let ambient_label = extension_settings.audio.ambient_selected;
|
|
||||||
if (ambient_label.includes("assets"))
|
|
||||||
ambient_label = "asset: " + ambient_label.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "");
|
|
||||||
else {
|
|
||||||
ambient_label = ambient_label.substring("/characters/".length);
|
|
||||||
ambient_label = ambient_label.substring(0, ambient_label.indexOf("/")) + ": " + ambient_label.substring(ambient_label.indexOf("/") + "/bgm/".length);
|
|
||||||
ambient_label = ambient_label.replace(/\.[^/.]+$/, "");
|
|
||||||
}
|
|
||||||
$('#audio_ambient_select').append(new Option(ambient_label, extension_settings.audio.ambient_selected));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const file of ambients) {
|
|
||||||
if (file !== extension_settings.audio.ambient_selected)
|
|
||||||
$("#audio_ambient_select").append(new Option("asset: " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1) Update ambient audio
|
|
||||||
// ---------------------------
|
|
||||||
//if (extension_settings.audio.dynamic_ambient_enabled) {
|
|
||||||
let newBackground = $("#bg1").css("background-image");
|
|
||||||
const custom_background = getContext()["chatMetadata"]["custom_background"];
|
|
||||||
|
|
||||||
if (custom_background !== undefined)
|
|
||||||
newBackground = custom_background
|
|
||||||
|
|
||||||
if (!isDataURL(newBackground)) {
|
|
||||||
newBackground = newBackground.substring(newBackground.lastIndexOf("/") + 1).replace(/\.[^/.]+$/, "").replaceAll("%20", "-").replaceAll(" ", "-"); // remove path and spaces
|
|
||||||
|
|
||||||
//console.debug(DEBUG_PREFIX,"Current backgroung:",newBackground);
|
|
||||||
|
|
||||||
if (currentBackground !== newBackground) {
|
|
||||||
currentBackground = newBackground;
|
|
||||||
|
|
||||||
console.debug(DEBUG_PREFIX, "Changing ambient audio for", currentBackground);
|
|
||||||
updateAmbient();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
|
|
||||||
const context = getContext();
|
|
||||||
//console.debug(DEBUG_PREFIX,context);
|
|
||||||
|
|
||||||
if (context.chat.length == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let chatIsGroup = context.chat[0].is_group;
|
|
||||||
let newCharacter = null;
|
|
||||||
|
|
||||||
// 1) Update BGM (single chat)
|
|
||||||
// -----------------------------
|
|
||||||
if (!chatIsGroup) {
|
|
||||||
|
|
||||||
// Reset bgm list on new chat
|
|
||||||
if (context.chatId != current_chat_id) {
|
|
||||||
current_chat_id = context.chatId;
|
|
||||||
characterMusics = {};
|
|
||||||
cooldownBGM = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCharacter = context.name2;
|
|
||||||
|
|
||||||
//console.log(DEBUG_PREFIX,"SOLO CHAT MODE"); // DBG
|
|
||||||
|
|
||||||
// 1.1) First time loading chat
|
|
||||||
if (characterMusics[newCharacter] === undefined) {
|
|
||||||
await loadCharacterBGM(newCharacter);
|
|
||||||
currentExpressionBGM = FALLBACK_EXPRESSION;
|
|
||||||
//currentCharacterBGM = newCharacter;
|
|
||||||
|
|
||||||
//updateBGM();
|
|
||||||
//cooldownBGM = BGM_UPDATE_COOLDOWN;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.2) Switched chat
|
|
||||||
if (currentCharacterBGM !== newCharacter) {
|
|
||||||
currentCharacterBGM = newCharacter;
|
|
||||||
try {
|
|
||||||
await updateBGM(false, true);
|
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Error while trying to update BGM character, will try again");
|
|
||||||
currentCharacterBGM = null
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newExpression = getNewExpression();
|
|
||||||
|
|
||||||
// 1.3) Same character but different expression
|
|
||||||
if (currentExpressionBGM !== newExpression) {
|
|
||||||
|
|
||||||
// Check cooldown
|
|
||||||
if (cooldownBGM > 0) {
|
|
||||||
//console.debug(DEBUG_PREFIX,"(SOLO) BGM switch on cooldown:",cooldownBGM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
currentExpressionBGM = newExpression;
|
|
||||||
await updateBGM();
|
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
|
||||||
console.debug(DEBUG_PREFIX, "(SOLO) Updated current character expression to", currentExpressionBGM, "cooldown", cooldownBGM);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Error while trying to update BGM expression, will try again");
|
|
||||||
currentCharacterBGM = null
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) Update BGM (group chat)
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// Load current chat character bgms
|
|
||||||
// Reset bgm list on new chat
|
|
||||||
if (context.chatId != current_chat_id) {
|
|
||||||
current_chat_id = context.chatId;
|
|
||||||
characterMusics = {};
|
|
||||||
cooldownBGM = 0;
|
|
||||||
for (const message of context.chat) {
|
|
||||||
if (characterMusics[message.name] === undefined)
|
|
||||||
await loadCharacterBGM(message.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
newCharacter = context.chat[context.chat.length - 1].name;
|
|
||||||
currentCharacterBGM = newCharacter;
|
|
||||||
await updateBGM(false, true);
|
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
|
||||||
currentCharacterBGM = newCharacter;
|
|
||||||
currentExpressionBGM = FALLBACK_EXPRESSION;
|
|
||||||
console.debug(DEBUG_PREFIX, "(GROUP) Updated current character BGM to", currentExpressionBGM, "cooldown", cooldownBGM);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Error while trying to update BGM group, will try again");
|
|
||||||
currentCharacterBGM = null
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newCharacter = context.chat[context.chat.length - 1].name;
|
|
||||||
const userName = context.name1;
|
|
||||||
|
|
||||||
if (newCharacter !== undefined && newCharacter != userName) {
|
|
||||||
|
|
||||||
//console.log(DEBUG_PREFIX,"GROUP CHAT MODE"); // DBG
|
|
||||||
|
|
||||||
// 2.1) New character appear
|
|
||||||
if (characterMusics[newCharacter] === undefined) {
|
|
||||||
await loadCharacterBGM(newCharacter);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.2) Switched char
|
|
||||||
if (currentCharacterBGM !== newCharacter) {
|
|
||||||
// Check cooldown
|
|
||||||
if (cooldownBGM > 0) {
|
|
||||||
console.debug(DEBUG_PREFIX, "(GROUP) BGM switch on cooldown:", cooldownBGM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
currentCharacterBGM = newCharacter;
|
|
||||||
await updateBGM();
|
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
|
||||||
currentCharacterBGM = newCharacter;
|
|
||||||
currentExpressionBGM = FALLBACK_EXPRESSION;
|
|
||||||
console.debug(DEBUG_PREFIX, "(GROUP) Updated current character BGM to", currentExpressionBGM, "cooldown", cooldownBGM);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.debug(DEBUG_PREFIX, "Error while trying to update BGM group, will try again");
|
|
||||||
currentCharacterBGM = null
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
const newExpression = getNewExpression();
|
|
||||||
|
|
||||||
// 1.3) Same character but different expression
|
|
||||||
if (currentExpressionBGM !== newExpression) {
|
|
||||||
|
|
||||||
// Check cooldown
|
|
||||||
if (cooldownBGM > 0) {
|
|
||||||
console.debug(DEBUG_PREFIX,"BGM switch on cooldown:",cooldownBGM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cooldownBGM = BGM_UPDATE_COOLDOWN;
|
|
||||||
currentExpressionBGM = newExpression;
|
|
||||||
console.debug(DEBUG_PREFIX,"Updated current character expression to",currentExpressionBGM);
|
|
||||||
updateBGM();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case 3: Same character/expression or BGM switch on cooldown keep playing same BGM
|
|
||||||
//console.debug(DEBUG_PREFIX,"Nothing to do for",currentCharacterBGM, newCharacter, currentExpressionBGM, cooldownBGM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadCharacterBGM(newCharacter) {
|
|
||||||
console.debug(DEBUG_PREFIX, "New character detected, loading BGM folder of", newCharacter);
|
|
||||||
|
|
||||||
// 1.1) First time character appear, load its music folder
|
|
||||||
const audio_file_paths = await getCharacterBgmList(newCharacter);
|
|
||||||
//console.debug(DEBUG_PREFIX, "Recieved", audio_file_paths);
|
|
||||||
|
|
||||||
// Initialise expression/files mapping
|
|
||||||
characterMusics[newCharacter] = {};
|
|
||||||
for (const e of DEFAULT_EXPRESSIONS)
|
|
||||||
characterMusics[newCharacter][e] = [];
|
|
||||||
|
|
||||||
for (const i of audio_file_paths) {
|
|
||||||
//console.debug(DEBUG_PREFIX,"File found:",i);
|
|
||||||
for (const e of DEFAULT_EXPRESSIONS)
|
|
||||||
if (i.includes(e))
|
|
||||||
characterMusics[newCharacter][e].push(i);
|
|
||||||
}
|
|
||||||
console.debug(DEBUG_PREFIX, "Updated BGM map of", newCharacter, "to", characterMusics[newCharacter]);
|
|
||||||
|
|
||||||
fillBGMSelect();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNewExpression() {
|
|
||||||
let newExpression;
|
|
||||||
|
|
||||||
// HACK: use sprite file name as expression detection
|
|
||||||
if (!$(SPRITE_DOM_ID).length) {
|
|
||||||
console.error(DEBUG_PREFIX, "ERROR: expression sprite does not exist, cannot extract expression from ", SPRITE_DOM_ID)
|
|
||||||
return FALLBACK_EXPRESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
const spriteFile = $("#expression-image").attr("src");
|
|
||||||
newExpression = spriteFile.substring(spriteFile.lastIndexOf("/") + 1).replace(/\.[^/.]+$/, "");
|
|
||||||
//
|
|
||||||
|
|
||||||
// No sprite to detect expression
|
|
||||||
if (newExpression == "") {
|
|
||||||
//console.info(DEBUG_PREFIX,"Warning: no expression extracted from sprite, switch to",FALLBACK_EXPRESSION);
|
|
||||||
newExpression = FALLBACK_EXPRESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DEFAULT_EXPRESSIONS.includes(newExpression)) {
|
|
||||||
console.info(DEBUG_PREFIX, "Warning:", newExpression, " is not a handled expression, expected one of", FALLBACK_EXPRESSION);
|
|
||||||
return FALLBACK_EXPRESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateBGM(isUserInput = false, newChat = false) {
|
|
||||||
if (!isUserInput && !extension_settings.audio.dynamic_bgm_enabled && $("#audio_bgm").attr("src") != "" && !bgmEnded && !newChat) {
|
|
||||||
console.debug(DEBUG_PREFIX, "BGM already playing and dynamic switch disabled, no update done");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let audio_file_path = ""
|
|
||||||
if (isUserInput || (extension_settings.audio.bgm_locked && extension_settings.audio.bgm_selected !== null)) {
|
|
||||||
audio_file_path = extension_settings.audio.bgm_selected;
|
|
||||||
|
|
||||||
if (isUserInput)
|
|
||||||
console.debug(DEBUG_PREFIX, "User selected BGM", audio_file_path);
|
|
||||||
if (extension_settings.audio.bgm_locked)
|
|
||||||
console.debug(DEBUG_PREFIX, "BGM locked keeping current audio", audio_file_path);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
let audio_files = null;
|
|
||||||
|
|
||||||
if (extension_settings.audio.dynamic_bgm_enabled) {
|
|
||||||
extension_settings.audio.bgm_selected = null;
|
|
||||||
saveSettingsDebounced();
|
|
||||||
audio_files = characterMusics[currentCharacterBGM][currentExpressionBGM];// Try char expression BGM
|
|
||||||
|
|
||||||
if (audio_files === undefined || audio_files.length == 0) {
|
|
||||||
console.debug(DEBUG_PREFIX, "No BGM for", currentCharacterBGM, currentExpressionBGM);
|
|
||||||
audio_files = characterMusics[currentCharacterBGM][FALLBACK_EXPRESSION]; // Try char FALLBACK BGM
|
|
||||||
if (audio_files === undefined || audio_files.length == 0) {
|
|
||||||
console.debug(DEBUG_PREFIX, "No default BGM for", currentCharacterBGM, FALLBACK_EXPRESSION, "switch to ST BGM");
|
|
||||||
audio_files = fallback_BGMS; // ST FALLBACK BGM
|
|
||||||
|
|
||||||
if (audio_files.length == 0) {
|
|
||||||
console.debug(DEBUG_PREFIX, "No default BGM file found, bgm folder may be empty.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
audio_files = [];
|
|
||||||
$("#audio_bgm_select option").each(function () { audio_files.push($(this).val()); });
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_file_path = audio_files[Math.floor(Math.random() * audio_files.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(DEBUG_PREFIX, "Updating BGM");
|
|
||||||
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
|
||||||
try {
|
|
||||||
const response = await fetch(audio_file_path);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
console.log(DEBUG_PREFIX, "File not found!")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(DEBUG_PREFIX, "Switching BGM to", currentExpressionBGM);
|
|
||||||
$("#audio_bgm_select").val(audio_file_path);
|
|
||||||
const audio = $("#audio_bgm");
|
|
||||||
|
|
||||||
if (audio.attr("src") == audio_file_path && !bgmEnded) {
|
|
||||||
console.log(DEBUG_PREFIX, "Already playing, ignored");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fade_time = 2000;
|
|
||||||
bgmEnded = false;
|
|
||||||
|
|
||||||
if (isUserInput || extension_settings.audio.bgm_locked) {
|
|
||||||
audio.attr("src", audio_file_path);
|
|
||||||
audio[0].play();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
audio.animate({ volume: 0.0 }, fade_time, function () {
|
|
||||||
audio.attr("src", audio_file_path);
|
|
||||||
audio[0].play();
|
|
||||||
audio.volume = extension_settings.audio.bgm_volume * 0.01;
|
|
||||||
audio.animate({ volume: extension_settings.audio.bgm_volume * 0.01 }, fade_time);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log(DEBUG_PREFIX, "Error while trying to fetch", audio_file_path, ":", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateAmbient(isUserInput = false) {
|
|
||||||
let audio_file_path = null;
|
|
||||||
|
|
||||||
if (isUserInput || extension_settings.audio.ambient_locked) {
|
|
||||||
audio_file_path = extension_settings.audio.ambient_selected;
|
|
||||||
|
|
||||||
if (isUserInput)
|
|
||||||
console.debug(DEBUG_PREFIX, "User selected Ambient", audio_file_path);
|
|
||||||
if (extension_settings.audio.bgm_locked)
|
|
||||||
console.debug(DEBUG_PREFIX, "Ambient locked keeping current audio", audio_file_path);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
extension_settings.audio.ambient_selected = null;
|
|
||||||
for (const i of ambients) {
|
|
||||||
console.debug(i)
|
|
||||||
if (i.includes(currentBackground)) {
|
|
||||||
audio_file_path = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audio_file_path === null) {
|
|
||||||
console.debug(DEBUG_PREFIX, "No bgm file found for background", currentBackground);
|
|
||||||
const audio = $("#audio_ambient");
|
|
||||||
audio.attr("src", "");
|
|
||||||
audio[0].pause();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//const audio_file_path = AMBIENT_FOLDER+currentBackground+".mp3";
|
|
||||||
console.log(DEBUG_PREFIX, "Updating ambient");
|
|
||||||
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
|
||||||
$("#audio_ambient_select").val(audio_file_path);
|
|
||||||
|
|
||||||
let fade_time = 2000;
|
|
||||||
if (isUserInput)
|
|
||||||
fade_time = 0;
|
|
||||||
|
|
||||||
const audio = $("#audio_ambient");
|
|
||||||
|
|
||||||
if (audio.attr("src") == audio_file_path) {
|
|
||||||
console.log(DEBUG_PREFIX, "Already playing, ignored");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
audio.animate({ volume: 0.0 }, fade_time, function () {
|
|
||||||
audio.attr("src", audio_file_path);
|
|
||||||
audio[0].play();
|
|
||||||
audio.volume = extension_settings.audio.ambient_volume * 0.01;
|
|
||||||
audio.animate({ volume: extension_settings.audio.ambient_volume * 0.01 }, fade_time);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles wheel events on volume sliders.
|
|
||||||
* @param {WheelEvent} e Event
|
|
||||||
*/
|
|
||||||
function onVolumeSliderWheelEvent(e) {
|
|
||||||
const slider = $(this);
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const delta = e.deltaY / 20;
|
|
||||||
const sliderVal = Number(slider.val());
|
|
||||||
|
|
||||||
let newVal = sliderVal - delta;
|
|
||||||
if (newVal < 0) {
|
|
||||||
newVal = 0;
|
|
||||||
} else if (newVal > 100) {
|
|
||||||
newVal = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
slider.val(newVal).trigger('input');
|
|
||||||
}
|
|
||||||
|
|
||||||
//#############################//
|
|
||||||
// Extension load //
|
|
||||||
//#############################//
|
|
||||||
|
|
||||||
// This function is called when the extension is loaded
|
|
||||||
jQuery(async () => {
|
|
||||||
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
|
|
||||||
|
|
||||||
$('#extensions_settings').append(windowHtml);
|
|
||||||
loadSettings();
|
|
||||||
|
|
||||||
$("#audio_enabled").on("click", onEnabledClick);
|
|
||||||
$("#audio_dynamic_bgm_enabled").on("click", onDynamicBGMEnabledClick);
|
|
||||||
//$("#audio_dynamic_ambient_enabled").on("click", onDynamicAmbientEnabledClick);
|
|
||||||
|
|
||||||
//$("#audio_bgm").attr("loop", false);
|
|
||||||
$("#audio_ambient").attr("loop", true);
|
|
||||||
|
|
||||||
$("#audio_bgm").hide();
|
|
||||||
$("#audio_bgm_lock").on("click", onBGMLockClick);
|
|
||||||
$("#audio_bgm_mute").on("click", onBGMMuteClick);
|
|
||||||
$("#audio_bgm_volume_slider").on("input", onBGMVolumeChange);
|
|
||||||
$("#audio_bgm_random").on("click", onBGMRandomClick);
|
|
||||||
|
|
||||||
$("#audio_ambient").hide();
|
|
||||||
$("#audio_ambient_lock").on("click", onAmbientLockClick);
|
|
||||||
$("#audio_ambient_mute").on("click", onAmbientMuteClick);
|
|
||||||
$("#audio_ambient_volume_slider").on("input", onAmbientVolumeChange);
|
|
||||||
|
|
||||||
document.getElementById('audio_ambient_volume_slider').addEventListener('wheel', onVolumeSliderWheelEvent, { passive: false });
|
|
||||||
document.getElementById('audio_bgm_volume_slider').addEventListener('wheel', onVolumeSliderWheelEvent, { passive: false });
|
|
||||||
|
|
||||||
$("#audio_bgm_cooldown").on("input", onBGMCooldownInput);
|
|
||||||
|
|
||||||
// Reset assets container, will be redected like if ST restarted
|
|
||||||
$("#audio_refresh_assets").on("click", function () {
|
|
||||||
console.debug(DEBUG_PREFIX, "Refreshing audio assets");
|
|
||||||
current_chat_id = null
|
|
||||||
fallback_BGMS = null;
|
|
||||||
ambients = null;
|
|
||||||
characterMusics = {};
|
|
||||||
currentCharacterBGM = null;
|
|
||||||
currentExpressionBGM = null;
|
|
||||||
currentBackground = null;
|
|
||||||
})
|
|
||||||
|
|
||||||
$("#audio_bgm_select").on("change", onBGMSelectChange);
|
|
||||||
$("#audio_ambient_select").on("change", onAmbientSelectChange);
|
|
||||||
|
|
||||||
// DBG
|
|
||||||
$("#audio_debug").on("click", function () {
|
|
||||||
if ($("#audio_debug").is(':checked')) {
|
|
||||||
$("#audio_bgm").show();
|
|
||||||
$("#audio_ambient").show();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#audio_bgm").hide();
|
|
||||||
$("#audio_ambient").hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//
|
|
||||||
|
|
||||||
$("#audio_bgm").on("ended", function () {
|
|
||||||
console.debug(DEBUG_PREFIX, "END OF BGM")
|
|
||||||
if (!extension_settings.audio.bgm_locked) {
|
|
||||||
bgmEnded = true;
|
|
||||||
updateBGM();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
|
||||||
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
|
|
||||||
moduleWorker();
|
|
||||||
});
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "Dynamic Audio",
|
|
||||||
"loading_order": 14,
|
|
||||||
"requires": [],
|
|
||||||
"optional": ["classify"],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "Keij#6799 and Deffcolony",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,95 +0,0 @@
|
|||||||
.audio-ui-block {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-div {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 5px;
|
|
||||||
background-color: rgba(38, 38, 38, 0.5);
|
|
||||||
border: 1px rgb(75, 75, 75) solid;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-element {
|
|
||||||
height: 60px;
|
|
||||||
float: left;
|
|
||||||
margin-right: 10px;
|
|
||||||
label {
|
|
||||||
text-align: top;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 5px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-label {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-volume-div {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-lock-button {
|
|
||||||
padding: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-random-button {
|
|
||||||
padding: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mute-button {
|
|
||||||
padding: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-slider {
|
|
||||||
width: 100% !important;
|
|
||||||
vertical-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mute-button-muted {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
#audio_refresh_assets {
|
|
||||||
width: 50px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-mute {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-volume {
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-playlist {
|
|
||||||
width: 45%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-lock {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio-mixer-random {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
@@ -1,120 +0,0 @@
|
|||||||
<div id="audio_settings">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>Dynamic Audio</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<div>
|
|
||||||
<label class="checkbox_label" for="audio_enabled">
|
|
||||||
<input type="checkbox" id="audio_enabled" name="audio_enabled">
|
|
||||||
<small>Enabled</small>
|
|
||||||
</label>
|
|
||||||
<div id="audio_bgm_dynamic_enable_div">
|
|
||||||
<label class="checkbox_label" for="audio_dynamic_bgm_enabled">
|
|
||||||
<input type="checkbox" id="audio_dynamic_bgm_enabled" name="audio_dynamic_bgm_enabled">
|
|
||||||
<small>Enable expression BGM switch (req. character expression)</small>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
<div id="audio_ambient_dynamic_enable_div">
|
|
||||||
<label class="checkbox_label" for="audio_dynamic_ambient_enabled">
|
|
||||||
<input type="checkbox" id="audio_dynamic_ambient_enabled" name="audio_dynamic_ambient_enabled">
|
|
||||||
<small>Enable ambient background switch (req. chat background)</small>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<div id="audio_debug_div">
|
|
||||||
<label class="checkbox_label" for="audio_debug">
|
|
||||||
<input type="checkbox" id="audio_debug" name="audio_debug">
|
|
||||||
<small>Debug</small>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="audio_refresh_assets">Refresh assets</label>
|
|
||||||
<div id="audio_refresh_assets" class="menu_button">
|
|
||||||
<i class="fa-solid fa-refresh fa-lg"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="audio-ui-block">
|
|
||||||
<label for="audio_bgm_volume_slider">Music</label>
|
|
||||||
<div class="audio-mixer-div">
|
|
||||||
<div class="audio-mixer-element audio-mixer-mute">
|
|
||||||
<label for="audio_bgm_lock" class="audio-label">Mute</label>
|
|
||||||
<div id="audio_bgm_mute" class="menu_button audio-mute-button">
|
|
||||||
<i class="fa-solid fa-volume-high fa-lg" id="audio_bgm_mute_icon"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-volume">
|
|
||||||
<label for="audio_bgm_lock" class="audio-label">Vol <span id="audio_bgm_volume"></span></label>
|
|
||||||
<input type="range" class ="audio-slider" id ="audio_bgm_volume_slider" value = "0" maxlength ="100">
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-playlist">
|
|
||||||
<label for="audio_bgm_lock" class="audio-label">Playlist</label>
|
|
||||||
<select id="audio_bgm_select">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-lock">
|
|
||||||
<label for="audio_bgm_lock" class="audio-label">Loop</label>
|
|
||||||
<div id="audio_bgm_lock" class="menu_button audio-lock-button">
|
|
||||||
<i class="fa-solid fa-repeat fa-lg" id="audio_bgm_lock_icon"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-random">
|
|
||||||
<label for="audio_bgm_random" class="audio-label">Roll</label>
|
|
||||||
<div id="audio_bgm_random" class="menu_button audio-random-button">
|
|
||||||
<i class="fa-solid fa-random fa-lg" id="audio_bgm_random_icon"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<audio id="audio_bgm" controls src="">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="audio_ambient_volume_slider">Ambient</label>
|
|
||||||
<div class="audio-mixer-div">
|
|
||||||
<div class="audio-mixer-element audio-mixer-mute">
|
|
||||||
<label for="audio_ambient_lock" class="audio-label">Mute</label>
|
|
||||||
<div id="audio_ambient_mute" class="menu_button audio-mute-button">
|
|
||||||
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-volume">
|
|
||||||
<label for="audio_ambient_lock" class="audio-label">Vol <span id="audio_ambient_volume"></span></label>
|
|
||||||
<input type="range" class ="audio-slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element audio-mixer-playlist">
|
|
||||||
<label for="audio_ambient_lock" class="audio-label">Playlist</label>
|
|
||||||
<select id="audio_ambient_select">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="audio-mixer-element">
|
|
||||||
<label for="audio_ambient_lock audio-mixer-lock" class="audio-label">Lock</label>
|
|
||||||
<div id="audio_ambient_lock" class="menu_button audio-lock-button">
|
|
||||||
<i class="fa-solid fa-lock-open fa-lg" id="audio_ambient_lock_icon"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<audio id="audio_ambient" controls src="">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="audio_bgm_cooldown">Music update cooldown (in seconds)</label>
|
|
||||||
<input id="audio_bgm_cooldown" class="text_pole wide30p">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<b>Hint:</b>
|
|
||||||
<i>
|
|
||||||
Create new folder in the
|
|
||||||
<b>public/characters/</b>
|
|
||||||
folder and name it as the name of the character.
|
|
||||||
Create a folder name <b>bgm</b> inside of it.
|
|
||||||
Put bgm music with expressions there. File names should follow the pattern:
|
|
||||||
<it>[expression_label]_[number].mp3</it>
|
|
||||||
By default one of the <it>neutral_[number].mp3</it> will play if classify module is not active.
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,178 +0,0 @@
|
|||||||
import { eventSource, event_types, generateQuietPrompt } from "../../../script.js";
|
|
||||||
import { getContext, saveMetadataDebounced } from "../../extensions.js";
|
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
|
||||||
import { stringFormat } from "../../utils.js";
|
|
||||||
export { MODULE_NAME };
|
|
||||||
|
|
||||||
const MODULE_NAME = 'backgrounds';
|
|
||||||
const METADATA_KEY = 'custom_background';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} background
|
|
||||||
*/
|
|
||||||
function forceSetBackground(background) {
|
|
||||||
saveBackgroundMetadata(background);
|
|
||||||
setCustomBackground();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function moduleWorker() {
|
|
||||||
if (hasCustomBackground()) {
|
|
||||||
$('#unlock_background').show();
|
|
||||||
$('#lock_background').hide();
|
|
||||||
setCustomBackground();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('#unlock_background').hide();
|
|
||||||
$('#lock_background').show();
|
|
||||||
unsetCustomBackground();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLockBackgroundClick() {
|
|
||||||
const bgImage = window.getComputedStyle(document.getElementById('bg1')).backgroundImage;
|
|
||||||
|
|
||||||
// Extract the URL from the CSS string
|
|
||||||
const urlRegex = /url\((['"])?(.*?)\1\)/;
|
|
||||||
const matches = bgImage.match(urlRegex);
|
|
||||||
const url = matches[2];
|
|
||||||
|
|
||||||
// Remove the protocol and host, leaving the relative URL
|
|
||||||
const relativeUrl = new URL(url).pathname;
|
|
||||||
const relativeBgImage = `url("${relativeUrl}")`
|
|
||||||
|
|
||||||
saveBackgroundMetadata(relativeBgImage);
|
|
||||||
setCustomBackground();
|
|
||||||
$('#unlock_background').show();
|
|
||||||
$('#lock_background').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUnlockBackgroundClick() {
|
|
||||||
removeBackgroundMetadata();
|
|
||||||
unsetCustomBackground();
|
|
||||||
$('#unlock_background').hide();
|
|
||||||
$('#lock_background').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasCustomBackground() {
|
|
||||||
const context = getContext();
|
|
||||||
return !!context.chatMetadata[METADATA_KEY];
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveBackgroundMetadata(file) {
|
|
||||||
const context = getContext();
|
|
||||||
context.chatMetadata[METADATA_KEY] = file;
|
|
||||||
saveMetadataDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeBackgroundMetadata() {
|
|
||||||
const context = getContext();
|
|
||||||
delete context.chatMetadata[METADATA_KEY];
|
|
||||||
saveMetadataDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setCustomBackground() {
|
|
||||||
const context = getContext();
|
|
||||||
const file = context.chatMetadata[METADATA_KEY];
|
|
||||||
|
|
||||||
// bg already set
|
|
||||||
if (document.getElementById("bg_custom").style.backgroundImage == file) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#bg_custom").css("background-image", file);
|
|
||||||
$("#custom_bg_preview").css("background-image", file);
|
|
||||||
}
|
|
||||||
|
|
||||||
function unsetCustomBackground() {
|
|
||||||
$("#bg_custom").css("background-image", 'none');
|
|
||||||
$("#custom_bg_preview").css("background-image", 'none');
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelectBackgroundClick() {
|
|
||||||
const bgfile = $(this).attr("bgfile");
|
|
||||||
|
|
||||||
if (hasCustomBackground()) {
|
|
||||||
saveBackgroundMetadata(`url("backgrounds/${bgfile}")`);
|
|
||||||
setCustomBackground();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const autoBgPrompt = `Pause your roleplay and choose a location ONLY from the provided list that is the most suitable for the current scene. Do not output any other text:\n{0}`;
|
|
||||||
|
|
||||||
async function autoBackgroundCommand() {
|
|
||||||
const options = Array.from(document.querySelectorAll('.BGSampleTitle')).map(x => ({ element: x, text: x.innerText.trim() })).filter(x => x.text.length > 0);
|
|
||||||
if (options.length == 0) {
|
|
||||||
toastr.warning('No backgrounds to choose from. Please upload some images to the "backgrounds" folder.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const list = options.map(option => `- ${option.text}`).join('\n');
|
|
||||||
const prompt = stringFormat(autoBgPrompt, list);
|
|
||||||
const reply = await generateQuietPrompt(prompt);
|
|
||||||
const fuse = new Fuse(options, { keys: ['text'] });
|
|
||||||
const bestMatch = fuse.search(reply, { limit: 1 });
|
|
||||||
|
|
||||||
if (bestMatch.length == 0) {
|
|
||||||
toastr.warning('No match found. Please try again.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('Automatically choosing background:', bestMatch);
|
|
||||||
bestMatch[0].item.element.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
function addSettings() {
|
|
||||||
const html = `
|
|
||||||
<div class="background_settings">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>Chat Backgrounds</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<div class="background_controls">
|
|
||||||
<div id="lock_background" class="menu_button">
|
|
||||||
<i class="fa-solid fa-lock"></i>
|
|
||||||
Lock
|
|
||||||
</div>
|
|
||||||
<div id="unlock_background" class="menu_button">
|
|
||||||
<i class="fa-solid fa-unlock"></i>
|
|
||||||
Unlock
|
|
||||||
</div>
|
|
||||||
<small>
|
|
||||||
Press "Lock" to assign a currently selected background to a character or group chat.<br>
|
|
||||||
Any background image selected while lock is engaged will be saved automatically.
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<div class="background_controls">
|
|
||||||
<div id="auto_background" class="menu_button">
|
|
||||||
<i class="fa-solid fa-wand-magic"></i>
|
|
||||||
Auto
|
|
||||||
</div>
|
|
||||||
<small>
|
|
||||||
Automatically select a background based on the chat context.<br>
|
|
||||||
Respects the "Lock" setting state.
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<div>Preview</div>
|
|
||||||
<div id="custom_bg_preview">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
$('#extensions_settings').append(html);
|
|
||||||
$('#lock_background').on('click', onLockBackgroundClick);
|
|
||||||
$('#unlock_background').on('click', onUnlockBackgroundClick);
|
|
||||||
$(document).on("click", ".bg_example", onSelectBackgroundClick);
|
|
||||||
$('#auto_background').on("click", autoBackgroundCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
addSettings();
|
|
||||||
registerSlashCommand('lockbg', onLockBackgroundClick, ['bglock'], " – locks a background for the currently selected chat", true, true);
|
|
||||||
registerSlashCommand('unlockbg', onUnlockBackgroundClick, ['bgunlock'], ' – unlocks a background for the currently selected chat', true, true);
|
|
||||||
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' – automatically changes the background based on the chat context using the AI request prompt', true, true);
|
|
||||||
eventSource.on(event_types.FORCE_SET_BACKGROUND, forceSetBackground);
|
|
||||||
eventSource.on(event_types.CHAT_CHANGED, moduleWorker);
|
|
||||||
});
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "Chat Backgrounds",
|
|
||||||
"loading_order": 7,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "Cohee#1207",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,45 +0,0 @@
|
|||||||
#custom_bg_preview {
|
|
||||||
width: 160px;
|
|
||||||
height: 90px;
|
|
||||||
background-color: var(--grey30a);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-size: cover;
|
|
||||||
border-radius: 20px;
|
|
||||||
border: 1px solid var(--SmartThemeBorderColor);
|
|
||||||
box-shadow: 0 0 7px var(--black50a);
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom_bg_preview::before {
|
|
||||||
content: 'No Background';
|
|
||||||
color: white;
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom_bg_preview:not([style*="background-image: none"])::before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background_controls .menu_button {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
column-gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background_controls {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
column-gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background_controls small {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "Bulk Card Editor",
|
|
||||||
"loading_order": 9,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "city-unit",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/city-unit"
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
.bulk_select_checkbox {
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#rm_print_characters_block.bulk_select .wide100pLess70px {
|
|
||||||
width: calc(100% - 85px);
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "CFG",
|
|
||||||
"loading_order": 1,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "kingbri",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
<a id="option_toggle_CFG">
|
|
||||||
<i class="fa-lg fa-solid fa-scale-balanced"></i>
|
|
||||||
<span data-i18n="CFG Scale">CFG Scale</span>
|
|
||||||
</a>
|
|
@@ -1,90 +0,0 @@
|
|||||||
import { chat_metadata, substituteParams, this_chid } from "../../../script.js";
|
|
||||||
import { extension_settings, getContext } from "../../extensions.js"
|
|
||||||
import { selected_group } from "../../group-chats.js";
|
|
||||||
import { getCharaFilename } from "../../utils.js";
|
|
||||||
|
|
||||||
export const cfgType = {
|
|
||||||
chat: 0,
|
|
||||||
chara: 1,
|
|
||||||
global: 2
|
|
||||||
}
|
|
||||||
export const metadataKeys = {
|
|
||||||
guidance_scale: "cfg_guidance_scale",
|
|
||||||
negative_prompt: "cfg_negative_prompt",
|
|
||||||
positive_prompt: "cfg_positive_prompt",
|
|
||||||
prompt_combine: "cfg_prompt_combine",
|
|
||||||
groupchat_individual_chars: "cfg_groupchat_individual_chars",
|
|
||||||
prompt_insertion_depth: "cfg_prompt_insertion_depth",
|
|
||||||
prompt_separator: "cfg_prompt_separator"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the CFG guidance scale
|
|
||||||
// If the guidance scale is 1, ignore the CFG prompt(s) since it won't be used anyways
|
|
||||||
export function getGuidanceScale() {
|
|
||||||
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
|
|
||||||
const chatGuidanceScale = chat_metadata[metadataKeys.guidance_scale];
|
|
||||||
const groupchatCharOverride = chat_metadata[metadataKeys.groupchat_individual_chars] ?? false;
|
|
||||||
|
|
||||||
if (chatGuidanceScale && chatGuidanceScale !== 1 && !groupchatCharOverride) {
|
|
||||||
return {
|
|
||||||
type: cfgType.chat,
|
|
||||||
value: chatGuidanceScale
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!selected_group && charaCfg || groupchatCharOverride) && charaCfg?.guidance_scale !== 1) {
|
|
||||||
return {
|
|
||||||
type: cfgType.chara,
|
|
||||||
value: charaCfg.guidance_scale
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extension_settings.cfg.global && extension_settings.cfg.global?.guidance_scale !== 1) {
|
|
||||||
return {
|
|
||||||
type: cfgType.global,
|
|
||||||
value: extension_settings.cfg.global.guidance_scale
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the CFG prompt
|
|
||||||
export function getCfgPrompt(guidanceScale, isNegative) {
|
|
||||||
let splitCfgPrompt = [];
|
|
||||||
|
|
||||||
const cfgPromptCombine = chat_metadata[metadataKeys.prompt_combine] ?? [];
|
|
||||||
if (guidanceScale.type === cfgType.chat || cfgPromptCombine.includes(cfgType.chat)) {
|
|
||||||
splitCfgPrompt.unshift(
|
|
||||||
substituteParams(
|
|
||||||
chat_metadata[isNegative ? metadataKeys.negative_prompt : metadataKeys.positive_prompt]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const charaCfg = extension_settings.cfg.chara?.find((e) => e.name === getCharaFilename(this_chid));
|
|
||||||
if (guidanceScale.type === cfgType.chara || cfgPromptCombine.includes(cfgType.chara)) {
|
|
||||||
splitCfgPrompt.unshift(
|
|
||||||
substituteParams(
|
|
||||||
isNegative ? charaCfg.negative_prompt : charaCfg.positive_prompt
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guidanceScale.type === cfgType.global || cfgPromptCombine.includes(cfgType.global)) {
|
|
||||||
splitCfgPrompt.unshift(
|
|
||||||
substituteParams(
|
|
||||||
isNegative ? extension_settings.cfg.global.negative_prompt : extension_settings.cfg.global.positive_prompt
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This line is a bit hacky with a JSON.stringify and JSON.parse. Fix this if possible.
|
|
||||||
const customSeparator = JSON.parse(chat_metadata[metadataKeys.prompt_separator] || JSON.stringify("\n")) ?? "\n";
|
|
||||||
const combinedCfgPrompt = splitCfgPrompt.filter((e) => e.length > 0).join(customSeparator);
|
|
||||||
const insertionDepth = chat_metadata[metadataKeys.prompt_insertion_depth] ?? 1;
|
|
||||||
console.log(`Setting CFG with guidance scale: ${guidanceScale.value}, negatives: ${combinedCfgPrompt}`);
|
|
||||||
|
|
||||||
return {
|
|
||||||
value: combinedCfgPrompt,
|
|
||||||
depth: insertionDepth
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,172 +0,0 @@
|
|||||||
<div id="cfgConfig" class="drawer-content flexGap5">
|
|
||||||
<div class="panelControlBar flex-container">
|
|
||||||
<div id="cfgConfigHeader" class="fa-solid fa-grip drag-grabber"></div>
|
|
||||||
<div id="CFGClose" class="fa-solid fa-circle-xmark"></div>
|
|
||||||
</div>
|
|
||||||
<div name="cfgConfigHolder" class="scrollY">
|
|
||||||
<div id="chat_cfg_container">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div id="CFGBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>Chat CFG</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<small>
|
|
||||||
<b>Unique to this chat.</b><br>
|
|
||||||
</small>
|
|
||||||
<label for="chat_cfg_guidance_scale">
|
|
||||||
<span data-i18n="Scale">Scale</span>
|
|
||||||
<small data-i18n="1 = disabled">1 = disabled</small>
|
|
||||||
</label>
|
|
||||||
<div class="range-block-range-and-counter">
|
|
||||||
<div class="range-block-range">
|
|
||||||
<input type="range" id="chat_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
|
|
||||||
</div>
|
|
||||||
<div class="range-block-counter">
|
|
||||||
<div contenteditable="true" data-for="chat_cfg_guidance_scale" id="chat_cfg_guidance_scale_counter">
|
|
||||||
select
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="chat_cfg_negative_prompt">
|
|
||||||
<span data-i18n="Negative Prompt">Negative Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="chat_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
|
|
||||||
<label for="chat_cfg_positive_prompt">
|
|
||||||
<span data-i18n="Positive Prompt">Positive Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="chat_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
</div>
|
|
||||||
<div id="groupchat_cfg_use_chara_container">
|
|
||||||
<label class="checkbox_label" for="groupchat_cfg_use_chara">
|
|
||||||
<input type="checkbox" id="groupchat_cfg_use_chara" />
|
|
||||||
<span data-i18n="Use character CFG scales">Use character CFG scales</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="chara_cfg_container" style="display: none;">
|
|
||||||
<hr class="sysHR">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>Character CFG</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<small><b>Will be automatically added as the CFG for this character.</b></small>
|
|
||||||
<br />
|
|
||||||
<label for="chara_cfg_guidance_scale">
|
|
||||||
<span data-i18n="Scale">Scale</span>
|
|
||||||
<small data-i18n="1 = disabled">1 = disabled</small>
|
|
||||||
</label>
|
|
||||||
<div class="range-block-range-and-counter">
|
|
||||||
<div class="range-block-range">
|
|
||||||
<input type="range" id="chara_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
|
|
||||||
</div>
|
|
||||||
<div class="range-block-counter">
|
|
||||||
<div contenteditable="true" data-for="chara_cfg_guidance_scale" id="chara_cfg_guidance_scale_counter">
|
|
||||||
select
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="chara_cfg_negative_prompt">
|
|
||||||
<span data-i18n="Negative Prompt">Negative Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="chara_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
|
|
||||||
<label for="chara_cfg_positive_prompt">
|
|
||||||
<span data-i18n="Positive Prompt">Positive Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="chara_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="global_cfg_container">
|
|
||||||
<hr class="sysHR">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>Global CFG</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<small><b>Will be used as the default CFG options for every chat unless overridden.</b></small>
|
|
||||||
<br />
|
|
||||||
<label for="global_cfg_guidance_scale">
|
|
||||||
<span data-i18n="Scale">Scale</span>
|
|
||||||
<small data-i18n="1 = disabled">1 = disabled</small>
|
|
||||||
</label>
|
|
||||||
<div class="range-block-range-and-counter">
|
|
||||||
<div class="range-block-range">
|
|
||||||
<input type="range" id="global_cfg_guidance_scale" name="volume" min="0.10" max="4.00" step="0.05">
|
|
||||||
</div>
|
|
||||||
<div class="range-block-counter">
|
|
||||||
<div contenteditable="true" data-for="global_cfg_guidance_scale" id="global_cfg_guidance_scale_counter">
|
|
||||||
select
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="global_cfg_negative_prompt">
|
|
||||||
<span data-i18n="Negative Prompt">Negative Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="global_cfg_negative_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
|
|
||||||
<label for="global_cfg_positive_prompt">
|
|
||||||
<span data-i18n="Positive Prompt">Positive Prompt</span>
|
|
||||||
</label>
|
|
||||||
<textarea id="global_cfg_positive_prompt" rows="2" class="text_pole textarea_compact" data-i18n="[placeholder]write short replies, write replies using past tense" placeholder="write short replies, write replies using past tense"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="cfg_prompt_combine_container">
|
|
||||||
<hr class="sysHR">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>CFG Prompt Cascading</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<div class="flex-container flexFlowColumn">
|
|
||||||
<small>
|
|
||||||
<b>Combine positive/negative prompts from other boxes.</b>
|
|
||||||
<br />
|
|
||||||
For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<div class="flex-container flexFlowColumn">
|
|
||||||
<label for="cfg_prompt_combine">
|
|
||||||
<span data-i18n="Scale">Always Include</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label">
|
|
||||||
<input type="checkbox" name="cfg_prompt_combine" value="0" />
|
|
||||||
<span data-i18n="Chat Negatives">Chat Negatives</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label">
|
|
||||||
<input type="checkbox" name="cfg_prompt_combine" value="1" />
|
|
||||||
<span data-i18n="Character Negatives">Character Negatives</span>
|
|
||||||
</label>
|
|
||||||
<label class="checkbox_label">
|
|
||||||
<input type="checkbox" name="cfg_prompt_combine" value="2" />
|
|
||||||
<span data-i18n="Global Negatives">Global Negatives</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="flex-container flexFlowColumn">
|
|
||||||
<label>
|
|
||||||
Custom Separator: <input id="cfg_prompt_separator" class="text_pole textarea_compact widthUnset" placeholder=""\n"" type="text" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
Insertion Depth: <input id="cfg_prompt_insertion_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,88 +0,0 @@
|
|||||||
import { callPopup } from "../../../script.js";
|
|
||||||
import { getContext } from "../../extensions.js";
|
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
|
||||||
export { MODULE_NAME };
|
|
||||||
|
|
||||||
const MODULE_NAME = 'dice';
|
|
||||||
const UPDATE_INTERVAL = 1000;
|
|
||||||
|
|
||||||
async function doDiceRoll(customDiceFormula) {
|
|
||||||
let value = typeof customDiceFormula === 'string' ? customDiceFormula.trim() : $(this).data('value');
|
|
||||||
|
|
||||||
if (value == 'custom') {
|
|
||||||
value = await callPopup('Enter the dice formula:<br><i>(for example, <tt>2d6</tt>)</i>', 'input');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isValid = droll.validate(value);
|
|
||||||
|
|
||||||
if (isValid) {
|
|
||||||
const result = droll.roll(value);
|
|
||||||
const context = getContext();
|
|
||||||
context.sendSystemMessage('generic', `${context.name1} rolls a ${value}. The result is: ${result.total} (${result.rolls})`, { isSmallSys: true });
|
|
||||||
} else {
|
|
||||||
toastr.warning('Invalid dice formula');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addDiceRollButton() {
|
|
||||||
const buttonHtml = `
|
|
||||||
<div id="roll_dice" class="list-group-item flex-container flexGap5">
|
|
||||||
<div class="fa-solid fa-dice extensionsMenuExtensionButton" title="Roll Dice" /></div>
|
|
||||||
Roll Dice
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
const dropdownHtml = `
|
|
||||||
<div id="dice_dropdown">
|
|
||||||
<ul class="list-group">
|
|
||||||
<li class="list-group-item" data-value="d4">d4</li>
|
|
||||||
<li class="list-group-item" data-value="d6">d6</li>
|
|
||||||
<li class="list-group-item" data-value="d8">d8</li>
|
|
||||||
<li class="list-group-item" data-value="d10">d10</li>
|
|
||||||
<li class="list-group-item" data-value="d12">d12</li>
|
|
||||||
<li class="list-group-item" data-value="d20">d20</li>
|
|
||||||
<li class="list-group-item" data-value="d100">d100</li>
|
|
||||||
<li class="list-group-item" data-value="custom">...</li>
|
|
||||||
</ul>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
$('#extensionsMenu').prepend(buttonHtml);
|
|
||||||
|
|
||||||
$(document.body).append(dropdownHtml)
|
|
||||||
$('#dice_dropdown li').on('click', doDiceRoll);
|
|
||||||
const button = $('#roll_dice');
|
|
||||||
const dropdown = $('#dice_dropdown');
|
|
||||||
dropdown.hide();
|
|
||||||
button.hide();
|
|
||||||
|
|
||||||
let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
|
|
||||||
placement: 'top',
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click touchend', function (e) {
|
|
||||||
const target = $(e.target);
|
|
||||||
if (target.is(dropdown)) return;
|
|
||||||
if (target.is(button) && !dropdown.is(":visible")) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
dropdown.fadeIn(250);
|
|
||||||
popper.update();
|
|
||||||
} else {
|
|
||||||
dropdown.fadeOut(250);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function moduleWorker() {
|
|
||||||
$('#roll_dice').toggle(getContext().onlineStatus !== 'no_connection');
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery(function () {
|
|
||||||
addDiceRollButton();
|
|
||||||
moduleWorker();
|
|
||||||
setInterval(moduleWorker, UPDATE_INTERVAL);
|
|
||||||
registerSlashCommand('roll', (_, value) => doDiceRoll(value), ['r'], "<span class='monospace'>(dice formula)</span> – roll the dice. For example, /roll 2d6", false, true);
|
|
||||||
});
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "D&D Dice",
|
|
||||||
"loading_order": 5,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "Cohee#1207",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,26 +0,0 @@
|
|||||||
#roll_dice {
|
|
||||||
/* order: 100; */
|
|
||||||
/* width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 1px; */
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.3s;
|
|
||||||
opacity: 0.7;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
/* justify-content: center; */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#roll_dice:hover {
|
|
||||||
opacity: 1;
|
|
||||||
filter: brightness(1.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#dice_dropdown {
|
|
||||||
z-index: 30000;
|
|
||||||
backdrop-filter: blur(--SmartThemeBlurStrength);
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced } from "../../../script.js";
|
import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced, this_chid } from "../../../script.js";
|
||||||
import { dragElement, isMobile } from "../../RossAscends-mods.js";
|
import { dragElement, isMobile } from "../../RossAscends-mods.js";
|
||||||
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplate } from "../../extensions.js";
|
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplate } from "../../extensions.js";
|
||||||
import { loadMovingUIState, power_user } from "../../power-user.js";
|
import { loadMovingUIState, power_user } from "../../power-user.js";
|
||||||
@@ -493,24 +493,6 @@ async function moduleWorker() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// character changed
|
|
||||||
if (context.groupId !== lastCharacter && context.characterId !== lastCharacter) {
|
|
||||||
removeExpression();
|
|
||||||
spriteCache = {};
|
|
||||||
|
|
||||||
//clear expression
|
|
||||||
let imgElement = document.getElementById('expression-image');
|
|
||||||
if (imgElement && imgElement instanceof HTMLImageElement) {
|
|
||||||
imgElement.src = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//set checkbox to global var
|
|
||||||
$('#image_type_toggle').prop('checked', extension_settings.expressions.talkinghead);
|
|
||||||
if (extension_settings.expressions.talkinghead) {
|
|
||||||
setTalkingHeadState(extension_settings.expressions.talkinghead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const vnMode = isVisualNovelMode();
|
const vnMode = isVisualNovelMode();
|
||||||
const vnWrapperVisible = $('#visual-novel-wrapper').is(':visible');
|
const vnWrapperVisible = $('#visual-novel-wrapper').is(':visible');
|
||||||
|
|
||||||
@@ -531,7 +513,7 @@ async function moduleWorker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentLastMessage = getLastCharacterMessage();
|
const currentLastMessage = getLastCharacterMessage();
|
||||||
let spriteFolderName = getSpriteFolderName(currentLastMessage, currentLastMessage.name);
|
let spriteFolderName = context.groupId ? getSpriteFolderName(currentLastMessage, currentLastMessage.name) : getSpriteFolderName();
|
||||||
|
|
||||||
// character has no expressions or it is not loaded
|
// character has no expressions or it is not loaded
|
||||||
if (Object.keys(spriteCache).length === 0) {
|
if (Object.keys(spriteCache).length === 0) {
|
||||||
@@ -563,6 +545,11 @@ async function moduleWorker() {
|
|||||||
await forceUpdateVisualNovelMode();
|
await forceUpdateVisualNovelMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.groupId && !Array.isArray(spriteCache[spriteFolderName])) {
|
||||||
|
await validateImages(spriteFolderName, true);
|
||||||
|
await forceUpdateVisualNovelMode();
|
||||||
|
}
|
||||||
|
|
||||||
offlineMode.css('display', 'none');
|
offlineMode.css('display', 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +571,7 @@ async function moduleWorker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Throttle classification requests during streaming
|
// Throttle classification requests during streaming
|
||||||
if (context.streamingProcessor && !context.streamingProcessor.isFinished) {
|
if (!context.groupId && context.streamingProcessor && !context.streamingProcessor.isFinished) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timeSinceLastServerResponse = now - lastServerResponseTime;
|
const timeSinceLastServerResponse = now - lastServerResponseTime;
|
||||||
|
|
||||||
@@ -777,7 +764,7 @@ function sampleClassifyText(text) {
|
|||||||
// Remove asterisks and quotes
|
// Remove asterisks and quotes
|
||||||
let result = text.replace(/[\*\"]/g, '');
|
let result = text.replace(/[\*\"]/g, '');
|
||||||
|
|
||||||
const SAMPLE_THRESHOLD = 300;
|
const SAMPLE_THRESHOLD = 500;
|
||||||
const HALF_SAMPLE_THRESHOLD = SAMPLE_THRESHOLD / 2;
|
const HALF_SAMPLE_THRESHOLD = SAMPLE_THRESHOLD / 2;
|
||||||
|
|
||||||
if (text.length < SAMPLE_THRESHOLD) {
|
if (text.length < SAMPLE_THRESHOLD) {
|
||||||
@@ -1487,14 +1474,35 @@ function setExpressionOverrideHtml(forceClear = false) {
|
|||||||
moduleWorker();
|
moduleWorker();
|
||||||
dragElement($("#expression-holder"))
|
dragElement($("#expression-holder"))
|
||||||
eventSource.on(event_types.CHAT_CHANGED, () => {
|
eventSource.on(event_types.CHAT_CHANGED, () => {
|
||||||
|
// character changed
|
||||||
|
const context = getContext();
|
||||||
|
if (context.groupId !== lastCharacter && context.characterId !== lastCharacter) {
|
||||||
|
removeExpression();
|
||||||
|
spriteCache = {};
|
||||||
|
|
||||||
|
//clear expression
|
||||||
|
let imgElement = document.getElementById('expression-image');
|
||||||
|
if (imgElement && imgElement instanceof HTMLImageElement) {
|
||||||
|
imgElement.src = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//set checkbox to global var
|
||||||
|
$('#image_type_toggle').prop('checked', extension_settings.expressions.talkinghead);
|
||||||
|
if (extension_settings.expressions.talkinghead) {
|
||||||
|
setTalkingHeadState(extension_settings.expressions.talkinghead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setExpressionOverrideHtml();
|
setExpressionOverrideHtml();
|
||||||
|
|
||||||
if (isVisualNovelMode()) {
|
if (isVisualNovelMode()) {
|
||||||
$('#visual-novel-wrapper').empty();
|
$('#visual-novel-wrapper').empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateFunction();
|
||||||
});
|
});
|
||||||
eventSource.on(event_types.MOVABLE_PANELS_RESET, updateVisualNovelModeDebounced);
|
eventSource.on(event_types.MOVABLE_PANELS_RESET, updateVisualNovelModeDebounced);
|
||||||
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
|
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
|
||||||
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">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);
|
||||||
})();
|
})();
|
||||||
|
@@ -5,7 +5,7 @@ import {
|
|||||||
getRequestHeaders,
|
getRequestHeaders,
|
||||||
} from "../../../script.js";
|
} from "../../../script.js";
|
||||||
import { selected_group } from "../../group-chats.js";
|
import { selected_group } from "../../group-chats.js";
|
||||||
import { loadFileToDocument } from "../../utils.js";
|
import { loadFileToDocument, delay } from "../../utils.js";
|
||||||
import { loadMovingUIState } from '../../power-user.js';
|
import { loadMovingUIState } from '../../power-user.js';
|
||||||
import { dragElement } from '../../RossAscends-mods.js';
|
import { dragElement } from '../../RossAscends-mods.js';
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
import { registerSlashCommand } from "../../slash-commands.js";
|
||||||
@@ -109,6 +109,13 @@ async function initGallery(items, url) {
|
|||||||
let file = e.originalEvent.dataTransfer.files[0];
|
let file = e.originalEvent.dataTransfer.files[0];
|
||||||
uploadFile(file, url); // Added url parameter to know where to upload
|
uploadFile(file, url); // Added url parameter to know where to upload
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//let images populate first
|
||||||
|
await delay(100)
|
||||||
|
//unset the height (which must be getting set by the gallery library at some point)
|
||||||
|
$("#dragGallery").css('height', 'unset');
|
||||||
|
//force a resize to make images display correctly
|
||||||
|
jQuery("#dragGallery").nanogallery2('resize');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,14 +254,16 @@ $(document).ready(function () {
|
|||||||
* The cloned element has its attributes set, a new child div appended, and is made visible on the body.
|
* The cloned element has its attributes set, a new child div appended, and is made visible on the body.
|
||||||
* Additionally, it sets up the element to prevent dragging on its images.
|
* Additionally, it sets up the element to prevent dragging on its images.
|
||||||
*/
|
*/
|
||||||
function makeMovable(id="gallery"){
|
function makeMovable(id = "gallery") {
|
||||||
|
|
||||||
console.debug('making new container from template')
|
console.debug('making new container from template')
|
||||||
const template = $('#generic_draggable_template').html();
|
const template = $('#generic_draggable_template').html();
|
||||||
const newElement = $(template);
|
const newElement = $(template);
|
||||||
|
newElement.css('background-color', 'var(--SmartThemeBlurTintColor)');
|
||||||
newElement.attr('forChar', id);
|
newElement.attr('forChar', id);
|
||||||
newElement.attr('id', `${id}`);
|
newElement.attr('id', `${id}`);
|
||||||
newElement.find('.drag-grabber').attr('id', `${id}header`);
|
newElement.find('.drag-grabber').attr('id', `${id}header`);
|
||||||
|
newElement.find('.dragTitle').text('Image Gallery')
|
||||||
//add a div for the gallery
|
//add a div for the gallery
|
||||||
newElement.append(`<div id="dragGallery"></div>`);
|
newElement.append(`<div id="dragGallery"></div>`);
|
||||||
// add no-scrollbar class to this element
|
// add no-scrollbar class to this element
|
||||||
@@ -326,6 +335,8 @@ function makeDragImg(id, url) {
|
|||||||
|
|
||||||
// Ensure that the newly added element is displayed as block
|
// Ensure that the newly added element is displayed as block
|
||||||
draggableElem.style.display = 'block';
|
draggableElem.style.display = 'block';
|
||||||
|
//and has no padding unlike other non-zoomed-avatar draggables
|
||||||
|
draggableElem.style.padding = '0';
|
||||||
|
|
||||||
// Add an id to the close button
|
// Add an id to the close button
|
||||||
// If the close button exists, set related-id
|
// If the close button exists, set related-id
|
||||||
@@ -375,11 +386,11 @@ function makeDragImg(id, url) {
|
|||||||
* @param {string} id - The ID to be sanitized.
|
* @param {string} id - The ID to be sanitized.
|
||||||
* @returns {string} - The sanitized ID.
|
* @returns {string} - The sanitized ID.
|
||||||
*/
|
*/
|
||||||
function sanitizeHTMLId(id){
|
function sanitizeHTMLId(id) {
|
||||||
// Replace spaces and non-word characters
|
// Replace spaces and non-word characters
|
||||||
id = id.replace(/\s+/g, '-')
|
id = id.replace(/\s+/g, '-')
|
||||||
.replace(/[^\x00-\x7F]/g, '-')
|
.replace(/[^\x00-\x7F]/g, '-')
|
||||||
.replace(/\W/g, '');
|
.replace(/\W/g, '');
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -404,7 +415,7 @@ function viewWithDragbox(items) {
|
|||||||
|
|
||||||
|
|
||||||
// Registers a simple command for opening the char gallery.
|
// Registers a simple command for opening the char gallery.
|
||||||
registerSlashCommand("show-gallery", showGalleryCommand, ["sg"], "Shows the gallery", true, true);
|
registerSlashCommand("show-gallery", showGalleryCommand, ["sg"], "– shows the gallery", true, true);
|
||||||
|
|
||||||
function showGalleryCommand(args) {
|
function showGalleryCommand(args) {
|
||||||
showCharGallery();
|
showCharGallery();
|
||||||
|
@@ -1,210 +0,0 @@
|
|||||||
import { eventSource, event_types, getRequestHeaders, is_send_press, saveSettingsDebounced } from "../../../script.js";
|
|
||||||
import { extension_settings, getContext, renderExtensionTemplate } from "../../extensions.js";
|
|
||||||
import { SECRET_KEYS, secret_state } from "../../secrets.js";
|
|
||||||
import { collapseNewlines } from "../../power-user.js";
|
|
||||||
import { bufferToBase64, debounce } from "../../utils.js";
|
|
||||||
import { decodeTextTokens, getTextTokens, tokenizers } from "../../tokenizers.js";
|
|
||||||
|
|
||||||
const MODULE_NAME = 'hypebot';
|
|
||||||
const WAITING_VERBS = ['thinking', 'typing', 'brainstorming', 'cooking', 'conjuring'];
|
|
||||||
const MAX_PROMPT = 1024;
|
|
||||||
const MAX_LENGTH = 50;
|
|
||||||
const MAX_STRING_LENGTH = MAX_PROMPT * 4;
|
|
||||||
|
|
||||||
const settings = {
|
|
||||||
enabled: false,
|
|
||||||
name: 'Goose',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a random waiting verb
|
|
||||||
* @returns {string} Random waiting verb
|
|
||||||
*/
|
|
||||||
function getWaitingVerb() {
|
|
||||||
return WAITING_VERBS[Math.floor(Math.random() * WAITING_VERBS.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a random verb based on the text
|
|
||||||
* @param {string} text Text to generate a verb for
|
|
||||||
* @returns {string} Random verb
|
|
||||||
*/
|
|
||||||
function getVerb(text) {
|
|
||||||
let verbList = ['says', 'notes', 'states', 'whispers', 'murmurs', 'mumbles'];
|
|
||||||
|
|
||||||
if (text.endsWith('!')) {
|
|
||||||
verbList = ['proclaims', 'declares', 'salutes', 'exclaims', 'cheers'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (text.endsWith('?')) {
|
|
||||||
verbList = ['asks', 'suggests', 'ponders', 'wonders', 'inquires', 'questions'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return verbList[Math.floor(Math.random() * verbList.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the HypeBot reply text
|
|
||||||
* @param {string} text HypeBot output text
|
|
||||||
* @returns {string} Formatted HTML text
|
|
||||||
*/
|
|
||||||
function formatReply(text) {
|
|
||||||
return `<span class="hypebot_name">${settings.name} ${getVerb(text)}:</span> <span class="hypebot_text">${text}</span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let hypeBotBar;
|
|
||||||
let abortController;
|
|
||||||
|
|
||||||
const generateDebounced = debounce(() => generateHypeBot(), 500);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the HypeBot text. Preserves scroll position of the chat.
|
|
||||||
* @param {string} text Text to set
|
|
||||||
*/
|
|
||||||
function setHypeBotText(text) {
|
|
||||||
const chatBlock = $('#chat');
|
|
||||||
const originalScrollBottom = chatBlock[0].scrollHeight - (chatBlock.scrollTop() + chatBlock.outerHeight());
|
|
||||||
hypeBotBar.html(DOMPurify.sanitize(text));
|
|
||||||
const newScrollTop = chatBlock[0].scrollHeight - (chatBlock.outerHeight() + originalScrollBottom);
|
|
||||||
chatBlock.scrollTop(newScrollTop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a chat event occurs to generate a HypeBot reply.
|
|
||||||
* @param {boolean} clear Clear the hypebot bar.
|
|
||||||
*/
|
|
||||||
function onChatEvent(clear) {
|
|
||||||
if (clear) {
|
|
||||||
setHypeBotText('');
|
|
||||||
}
|
|
||||||
|
|
||||||
abortController?.abort();
|
|
||||||
generateDebounced();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a HypeBot reply.
|
|
||||||
*/
|
|
||||||
async function generateHypeBot() {
|
|
||||||
if (!settings.enabled || is_send_press) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!secret_state[SECRET_KEYS.NOVEL]) {
|
|
||||||
setHypeBotText('<div class="hypebot_nokey">No API key found. Please enter your API key in the NovelAI API Settings to use the HypeBot.</div>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('Generating HypeBot reply');
|
|
||||||
setHypeBotText(`<span class="hypebot_name">${settings.name}</span> is ${getWaitingVerb()}...`);
|
|
||||||
|
|
||||||
const context = getContext();
|
|
||||||
const chat = context.chat.slice();
|
|
||||||
let prompt = '';
|
|
||||||
|
|
||||||
for (let index = chat.length - 1; index >= 0; index--) {
|
|
||||||
const message = chat[index];
|
|
||||||
|
|
||||||
if (message.is_system || !message.mes) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt = `\n${message.mes}\n${prompt}`;
|
|
||||||
|
|
||||||
if (prompt.length >= MAX_STRING_LENGTH) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt = collapseNewlines(prompt.replaceAll(/[\*\[\]\{\}]/g, ''));
|
|
||||||
|
|
||||||
if (!prompt) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sliceLength = MAX_PROMPT - MAX_LENGTH;
|
|
||||||
const encoded = getTextTokens(tokenizers.GPT2, prompt).slice(-sliceLength);
|
|
||||||
|
|
||||||
// Add a stop string token to the end of the prompt
|
|
||||||
encoded.push(49527);
|
|
||||||
|
|
||||||
const base64String = await bufferToBase64(new Uint16Array(encoded).buffer);
|
|
||||||
|
|
||||||
const parameters = {
|
|
||||||
input: base64String,
|
|
||||||
model: "hypebot",
|
|
||||||
streaming: false,
|
|
||||||
temperature: 1,
|
|
||||||
max_length: MAX_LENGTH,
|
|
||||||
min_length: 1,
|
|
||||||
top_k: 0,
|
|
||||||
top_p: 1,
|
|
||||||
tail_free_sampling: 0.95,
|
|
||||||
repetition_penalty: 1,
|
|
||||||
repetition_penalty_range: 2048,
|
|
||||||
repetition_penalty_slope: 0.18,
|
|
||||||
repetition_penalty_frequency: 0,
|
|
||||||
repetition_penalty_presence: 0,
|
|
||||||
phrase_rep_pen: "off",
|
|
||||||
bad_words_ids: [],
|
|
||||||
stop_sequences: [[48585]],
|
|
||||||
generate_until_sentence: true,
|
|
||||||
use_cache: false,
|
|
||||||
use_string: false,
|
|
||||||
return_full_text: false,
|
|
||||||
prefix: "vanilla",
|
|
||||||
logit_bias_exp: [],
|
|
||||||
order: [0, 1, 2, 3],
|
|
||||||
};
|
|
||||||
|
|
||||||
abortController = new AbortController();
|
|
||||||
|
|
||||||
const response = await fetch('/api/novelai/generate', {
|
|
||||||
headers: getRequestHeaders(),
|
|
||||||
body: JSON.stringify(parameters),
|
|
||||||
method: 'POST',
|
|
||||||
signal: abortController.signal,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
const data = await response.json();
|
|
||||||
const ids = Array.from(new Uint16Array(Uint8Array.from(atob(data.output), c => c.charCodeAt(0)).buffer));
|
|
||||||
const output = decodeTextTokens(tokenizers.GPT2, ids).replace(/<2F>/g, '').trim();
|
|
||||||
|
|
||||||
setHypeBotText(formatReply(output));
|
|
||||||
} else {
|
|
||||||
setHypeBotText('<div class="hypebot_error">Something went wrong while generating a HypeBot reply. Please try again.</div>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery(() => {
|
|
||||||
if (!extension_settings.hypebot) {
|
|
||||||
extension_settings.hypebot = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(settings, extension_settings.hypebot);
|
|
||||||
$('#extensions_settings2').append(renderExtensionTemplate(MODULE_NAME, 'settings'));
|
|
||||||
hypeBotBar = $(`<div id="hypeBotBar"></div>`).toggle(settings.enabled);
|
|
||||||
$('#send_form').append(hypeBotBar);
|
|
||||||
|
|
||||||
$('#hypebot_enabled').prop('checked', settings.enabled).on('input', () => {
|
|
||||||
settings.enabled = $('#hypebot_enabled').prop('checked');
|
|
||||||
hypeBotBar.toggle(settings.enabled);
|
|
||||||
abortController?.abort();
|
|
||||||
Object.assign(extension_settings.hypebot, settings);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#hypebot_name').val(settings.name).on('input', () => {
|
|
||||||
settings.name = String($('#hypebot_name').val());
|
|
||||||
Object.assign(extension_settings.hypebot, settings);
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
eventSource.on(event_types.CHAT_CHANGED, () => onChatEvent(true));
|
|
||||||
eventSource.on(event_types.MESSAGE_DELETED, () => onChatEvent(true));
|
|
||||||
eventSource.on(event_types.MESSAGE_EDITED, () => onChatEvent(true));
|
|
||||||
eventSource.on(event_types.MESSAGE_SENT, () => onChatEvent(false));
|
|
||||||
eventSource.on(event_types.MESSAGE_RECEIVED, () => onChatEvent(false));
|
|
||||||
eventSource.on(event_types.MESSAGE_SWIPED, () => onChatEvent(false));
|
|
||||||
});
|
|
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "HypeBot",
|
|
||||||
"loading_order": 1000,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "Cohee#1207",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
<div class="hypebot_settings">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
|
||||||
<b>HypeBot</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<div>Show personalized suggestions based on your recent chats using the NovelAI's HypeBot engine.</div>
|
|
||||||
<small><i>Hint: Save an API key in the NovelAI API settings to use it here.</i></small>
|
|
||||||
<label class="checkbox_label" for="hypebot_enabled">
|
|
||||||
<input id="hypebot_enabled" type="checkbox" class="checkbox">
|
|
||||||
Enabled
|
|
||||||
</label>
|
|
||||||
<label>Name:</label>
|
|
||||||
<input id="hypebot_name" type="text" class="text_pole" placeholder="Goose">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,17 +0,0 @@
|
|||||||
#hypeBotBar {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
padding: 0.5em;
|
|
||||||
white-space: normal;
|
|
||||||
font-size: calc(var(--mainFontSize) * 0.85);
|
|
||||||
order: 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hypebot_nokey {
|
|
||||||
text-align: center;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hypebot_name {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
@@ -1,54 +0,0 @@
|
|||||||
<div class="idle-settings">
|
|
||||||
<div class="inline-drawer">
|
|
||||||
<div class="inline-drawer-toggle inline-drawer-header" title="Indicates the settings for the idle feature.">
|
|
||||||
<b>Idle</b>
|
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="inline-drawer-content">
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_enabled" type="checkbox" title="Toggle to enable or disable the idle feature." />
|
|
||||||
<label for="idle_enabled">Enabled</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_repeats" class="text_pole widthUnset" type="number" min="0" max="100000" step="1" title="The number of times the idle action will be prompted." />
|
|
||||||
<label for="idle_repeats">Idle Prompt Count</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container" style="display: none;">
|
|
||||||
<input id="idle_timer_min" class="text_pole widthUnset" type="number" min="0" max="600000" step="1" title="The minimum amount of time in seconds before the idle action is triggered." />
|
|
||||||
<label for="idle_timer_min">Idle Timer Minimum (seconds)</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_timer" class="text_pole widthUnset" type="number" min="0" max="600000" step="1" title="The amount of time in seconds before the idle action is triggered." />
|
|
||||||
<label for="idle_timer">Idle Timer (seconds)</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<label for="idle_prompts">Idle Prompts</label>
|
|
||||||
<textarea id="idle_prompts" class="text_pole textarea_compact" rows="6" title="The prompts to be sent to initial the idle reply (newline seperated)."></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_use_continuation" type="checkbox" title="Indicates whether the idle action will just use the 'Continue' function instead of a prompt." />
|
|
||||||
<label for="idle_use_continuation">Use Continuation</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_random_time" type="checkbox" title="Indicates if the idle time should be randomized between a min/max value." />
|
|
||||||
<label for="idle_random_time">Randomize Time</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<input id="idle_include_prompt" type="checkbox" title="Indicates if the idle prompting should be included in context. (Sends as user)" />
|
|
||||||
<label for="idle_include_prompt">Include Idle Prompt</label>
|
|
||||||
</div>
|
|
||||||
<div class="idle_block flex-container">
|
|
||||||
<label for="idle_sendAs">Send As</label>
|
|
||||||
<select id="idle_sendAs" class="text_pole" title="Determines how the idle message prompting is sent; as a user, character, system, or raw message.">
|
|
||||||
<option value="user">User</option>
|
|
||||||
<option value="char">Character</option>
|
|
||||||
<option value="sys">System</option>
|
|
||||||
<option value="raw">Raw</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="sysHR" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,329 +0,0 @@
|
|||||||
import {
|
|
||||||
saveSettingsDebounced,
|
|
||||||
substituteParams
|
|
||||||
} from "../../../script.js";
|
|
||||||
import { debounce } from "../../utils.js";
|
|
||||||
import { promptQuietForLoudResponse, sendMessageAs, sendNarratorMessage } from "../../slash-commands.js";
|
|
||||||
import { extension_settings, getContext, renderExtensionTemplate } from "../../extensions.js";
|
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
|
||||||
const extensionName = "idle";
|
|
||||||
|
|
||||||
let idleTimer = null;
|
|
||||||
let repeatCount = 0;
|
|
||||||
|
|
||||||
let defaultSettings = {
|
|
||||||
enabled: false,
|
|
||||||
timer: 120,
|
|
||||||
prompts: [
|
|
||||||
"*stands silently, looking deep in thought*",
|
|
||||||
"*pauses, eyes wandering over the surroundings*",
|
|
||||||
"*hesitates, appearing lost for a moment*",
|
|
||||||
"*takes a deep breath, collecting their thoughts*",
|
|
||||||
"*gazes into the distance, seemingly distracted*",
|
|
||||||
"*remains still, absorbing the ambiance*",
|
|
||||||
"*lingers in silence, a contemplative look on their face*",
|
|
||||||
"*stops, fingers brushing against an old memory*",
|
|
||||||
"*seems to drift into a momentary daydream*",
|
|
||||||
"*waits quietly, allowing the weight of the moment to settle*",
|
|
||||||
],
|
|
||||||
useContinuation: true,
|
|
||||||
repeats: 2, // 0 = infinite
|
|
||||||
sendAs: "user",
|
|
||||||
randomTime: false,
|
|
||||||
timeMin: 60,
|
|
||||||
includePrompt: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: Can we make this a generic function?
|
|
||||||
/**
|
|
||||||
* Load the extension settings and set defaults if they don't exist.
|
|
||||||
*/
|
|
||||||
async function loadSettings() {
|
|
||||||
if (!extension_settings.idle) {
|
|
||||||
console.log("Creating extension_settings.idle");
|
|
||||||
extension_settings.idle = {};
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(defaultSettings)) {
|
|
||||||
if (!extension_settings.idle.hasOwnProperty(key)) {
|
|
||||||
console.log(`Setting default for: ${key}`);
|
|
||||||
extension_settings.idle[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
populateUIWithSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Can we make this a generic function too?
|
|
||||||
/**
|
|
||||||
* Populate the UI components with values from the extension settings.
|
|
||||||
*/
|
|
||||||
function populateUIWithSettings() {
|
|
||||||
$("#idle_timer").val(extension_settings.idle.timer).trigger("input");
|
|
||||||
$("#idle_prompts").val(extension_settings.idle.prompts.join("\n")).trigger("input");
|
|
||||||
$("#idle_use_continuation").prop("checked", extension_settings.idle.useContinuation).trigger("input");
|
|
||||||
$("#idle_enabled").prop("checked", extension_settings.idle.enabled).trigger("input");
|
|
||||||
$("#idle_repeats").val(extension_settings.idle.repeats).trigger("input");
|
|
||||||
$("#idle_sendAs").val(extension_settings.idle.sendAs).trigger("input");
|
|
||||||
$("#idle_random_time").prop("checked", extension_settings.idle.randomTime).trigger("input");
|
|
||||||
$("#idle_timer_min").val(extension_settings.idle.timerMin).trigger("input");
|
|
||||||
$("#idle_include_prompt").prop("checked", extension_settings.idle.includePrompt).trigger("input");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the idle timer based on the extension settings and context.
|
|
||||||
*/
|
|
||||||
function resetIdleTimer() {
|
|
||||||
console.debug("Resetting idle timer");
|
|
||||||
if (idleTimer) clearTimeout(idleTimer);
|
|
||||||
let context = getContext();
|
|
||||||
if (!context.characterId && !context.groupID) return;
|
|
||||||
if (!extension_settings.idle.enabled) return;
|
|
||||||
if (extension_settings.idle.randomTime) {
|
|
||||||
// ensure these are ints
|
|
||||||
let min = extension_settings.idle.timerMin;
|
|
||||||
let max = extension_settings.idle.timer;
|
|
||||||
min = parseInt(min);
|
|
||||||
max = parseInt(max);
|
|
||||||
let randomTime = (Math.random() * (max - min + 1)) + min;
|
|
||||||
idleTimer = setTimeout(sendIdlePrompt, 1000 * randomTime);
|
|
||||||
} else {
|
|
||||||
idleTimer = setTimeout(sendIdlePrompt, 1000 * extension_settings.idle.timer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a random idle prompt to the AI based on the extension settings.
|
|
||||||
* Checks conditions like if the extension is enabled and repeat conditions.
|
|
||||||
*/
|
|
||||||
async function sendIdlePrompt() {
|
|
||||||
if (!extension_settings.idle.enabled) return;
|
|
||||||
|
|
||||||
// Check repeat conditions and waiting for a response
|
|
||||||
if (repeatCount >= extension_settings.idle.repeats || $('#mes_stop').is(':visible')) {
|
|
||||||
//console.debug("Not sending idle prompt due to repeat conditions or waiting for a response.");
|
|
||||||
resetIdleTimer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const randomPrompt = extension_settings.idle.prompts[
|
|
||||||
Math.floor(Math.random() * extension_settings.idle.prompts.length)
|
|
||||||
];
|
|
||||||
|
|
||||||
sendPrompt(randomPrompt);
|
|
||||||
repeatCount++;
|
|
||||||
resetIdleTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add our prompt to the chat and then send the chat to the backend.
|
|
||||||
* @param {string} sendAs - The type of message to send. "user", "char", or "sys".
|
|
||||||
* @param {string} prompt - The prompt text to send to the AI.
|
|
||||||
*/
|
|
||||||
function sendLoud(sendAs, prompt) {
|
|
||||||
if (sendAs === "user") {
|
|
||||||
prompt = substituteParams(prompt);
|
|
||||||
|
|
||||||
$("#send_textarea").val(prompt);
|
|
||||||
|
|
||||||
// Set the focus back to the textarea
|
|
||||||
$("#send_textarea").focus();
|
|
||||||
|
|
||||||
$("#send_but").trigger('click');
|
|
||||||
} else if (sendAs === "char") {
|
|
||||||
sendMessageAs("", `${getContext().name2}\n${prompt}`);
|
|
||||||
promptQuietForLoudResponse(sendAs, "");
|
|
||||||
} else if (sendAs === "sys") {
|
|
||||||
sendNarratorMessage("", prompt);
|
|
||||||
promptQuietForLoudResponse(sendAs, "");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(`Unknown sendAs value: ${sendAs}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the provided prompt to the AI. Determines method based on continuation setting.
|
|
||||||
* @param {string} prompt - The prompt text to send to the AI.
|
|
||||||
*/
|
|
||||||
function sendPrompt(prompt) {
|
|
||||||
clearTimeout(idleTimer);
|
|
||||||
$("#send_textarea").off("input");
|
|
||||||
|
|
||||||
if (extension_settings.idle.useContinuation) {
|
|
||||||
$('#option_continue').trigger('click');
|
|
||||||
console.debug("Sending idle prompt with continuation");
|
|
||||||
} else {
|
|
||||||
console.debug("Sending idle prompt");
|
|
||||||
console.log(extension_settings.idle);
|
|
||||||
if (extension_settings.idle.includePrompt) {
|
|
||||||
sendLoud(extension_settings.idle.sendAs, prompt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
promptQuietForLoudResponse(extension_settings.idle.sendAs, prompt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the settings HTML and append to the designated area.
|
|
||||||
*/
|
|
||||||
async function loadSettingsHTML() {
|
|
||||||
const settingsHtml = renderExtensionTemplate(extensionName, "dropdown");
|
|
||||||
$("#extensions_settings2").append(settingsHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a specific setting based on user input.
|
|
||||||
* @param {string} elementId - The HTML element ID tied to the setting.
|
|
||||||
* @param {string} property - The property name in the settings object.
|
|
||||||
* @param {boolean} [isCheckbox=false] - Whether the setting is a checkbox.
|
|
||||||
*/
|
|
||||||
function updateSetting(elementId, property, isCheckbox = false) {
|
|
||||||
let value = $(`#${elementId}`).val();
|
|
||||||
if (isCheckbox) {
|
|
||||||
value = $(`#${elementId}`).prop('checked');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (property === "prompts") {
|
|
||||||
value = value.split("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
extension_settings.idle[property] = value;
|
|
||||||
saveSettingsDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attach an input listener to a UI component to update the corresponding setting.
|
|
||||||
* @param {string} elementId - The HTML element ID tied to the setting.
|
|
||||||
* @param {string} property - The property name in the settings object.
|
|
||||||
* @param {boolean} [isCheckbox=false] - Whether the setting is a checkbox.
|
|
||||||
*/
|
|
||||||
function attachUpdateListener(elementId, property, isCheckbox = false) {
|
|
||||||
$(`#${elementId}`).on('input', debounce(() => {
|
|
||||||
updateSetting(elementId, property, isCheckbox);
|
|
||||||
}, 250));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the enabling or disabling of the idle extension.
|
|
||||||
* Adds or removes the idle listeners based on the checkbox's state.
|
|
||||||
*/
|
|
||||||
function handleIdleEnabled() {
|
|
||||||
if (!extension_settings.idle.enabled) {
|
|
||||||
clearTimeout(idleTimer);
|
|
||||||
removeIdleListeners();
|
|
||||||
} else {
|
|
||||||
resetIdleTimer();
|
|
||||||
attachIdleListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup input listeners for the various settings and actions related to the idle extension.
|
|
||||||
*/
|
|
||||||
function setupListeners() {
|
|
||||||
const settingsToWatch = [
|
|
||||||
['idle_timer', 'timer'],
|
|
||||||
['idle_prompts', 'prompts'],
|
|
||||||
['idle_use_continuation', 'useContinuation', true],
|
|
||||||
['idle_enabled', 'enabled', true],
|
|
||||||
['idle_repeats', 'repeats'],
|
|
||||||
['idle_sendAs', 'sendAs'],
|
|
||||||
['idle_random_time', 'randomTime', true],
|
|
||||||
['idle_timer_min', 'timerMin'],
|
|
||||||
['idle_include_prompt', 'includePrompt', true]
|
|
||||||
];
|
|
||||||
settingsToWatch.forEach(setting => {
|
|
||||||
attachUpdateListener(...setting);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Idleness listeners, could be made better
|
|
||||||
$('#idle_enabled').on('input', debounce(handleIdleEnabled, 250));
|
|
||||||
|
|
||||||
// Add the idle listeners initially if the idle feature is enabled
|
|
||||||
if (extension_settings.idle.enabled) {
|
|
||||||
attachIdleListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
//show/hide timer min parent div
|
|
||||||
$('#idle_random_time').on('input', function () {
|
|
||||||
if ($(this).prop('checked')) {
|
|
||||||
$('#idle_timer_min').parent().show();
|
|
||||||
} else {
|
|
||||||
$('#idle_timer_min').parent().hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#idle_timer').trigger('input');
|
|
||||||
});
|
|
||||||
|
|
||||||
// if we're including the prompt, hide raw from the sendAs dropdown
|
|
||||||
$('#idle_include_prompt').on('input', function () {
|
|
||||||
if ($(this).prop('checked')) {
|
|
||||||
$('#idle_sendAs option[value="raw"]').hide();
|
|
||||||
} else {
|
|
||||||
$('#idle_sendAs option[value="raw"]').show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//make sure timer min is less than timer
|
|
||||||
$('#idle_timer').on('input', function () {
|
|
||||||
if ($('#idle_random_time').prop('checked')) {
|
|
||||||
if ($(this).val() < $('#idle_timer_min').val()) {
|
|
||||||
$('#idle_timer_min').val($(this).val());
|
|
||||||
$('#idle_timer_min').trigger('input');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const debouncedActivityHandler = debounce((event) => {
|
|
||||||
// Check if the event target (or any of its parents) has the id "option_continue"
|
|
||||||
if ($(event.target).closest('#option_continue').length) {
|
|
||||||
return; // Do not proceed if the click was on (or inside) an element with id "option_continue"
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug("Activity detected, resetting idle timer");
|
|
||||||
resetIdleTimer();
|
|
||||||
repeatCount = 0;
|
|
||||||
}, 250);
|
|
||||||
|
|
||||||
function attachIdleListeners() {
|
|
||||||
$(document).on("click keypress", debouncedActivityHandler);
|
|
||||||
document.addEventListener('keydown', debouncedActivityHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove idle-specific listeners.
|
|
||||||
*/
|
|
||||||
function removeIdleListeners() {
|
|
||||||
$(document).off("click keypress", debouncedActivityHandler);
|
|
||||||
document.removeEventListener('keydown', debouncedActivityHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleIdle() {
|
|
||||||
extension_settings.idle.enabled = !extension_settings.idle.enabled;
|
|
||||||
$('#idle_enabled').prop('checked', extension_settings.idle.enabled);
|
|
||||||
$('#idle_enabled').trigger('input');
|
|
||||||
toastr.info(`Idle mode ${extension_settings.idle.enabled ? "enabled" : "disabled"}.`);
|
|
||||||
resetIdleTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
jQuery(async () => {
|
|
||||||
await loadSettingsHTML();
|
|
||||||
loadSettings();
|
|
||||||
setupListeners();
|
|
||||||
if (extension_settings.idle.enabled) {
|
|
||||||
resetIdleTimer();
|
|
||||||
}
|
|
||||||
// once the doc is ready, check if random time is checked and hide/show timer min
|
|
||||||
if ($('#idle_random_time').prop('checked')) {
|
|
||||||
$('#idle_timer_min').parent().show();
|
|
||||||
}
|
|
||||||
registerSlashCommand('idle', toggleIdle, [], ' – toggles idle mode', true, true);
|
|
||||||
});
|
|
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"display_name": "Idle",
|
|
||||||
"loading_order": 6,
|
|
||||||
"requires": [],
|
|
||||||
"optional": [
|
|
||||||
],
|
|
||||||
"js": "index.js",
|
|
||||||
"css": "style.css",
|
|
||||||
"author": "City-Unit",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
.idle_block {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user