sillytavern 1.12.6 → 1.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +24 -8
  2. package/UpdateAndStart.bat +12 -3
  3. package/UpdateForkAndStart.bat +10 -3
  4. package/config.yaml +15 -4
  5. package/default/config.yaml +15 -4
  6. package/default/content/Eldoria.json +96 -12
  7. package/default/content/default_Seraphina.png +0 -0
  8. package/default/content/presets/openai/Default.json +0 -1
  9. package/jsconfig.json +10 -11
  10. package/package.json +27 -7
  11. package/plugins/package.json +4 -0
  12. package/plugins.js +16 -4
  13. package/post-install.js +15 -11
  14. package/public/css/logprobs.css +1 -0
  15. package/public/css/popup.css +2 -1
  16. package/public/css/select2-overrides.css +2 -1
  17. package/public/css/st-tailwind.css +4 -0
  18. package/public/css/toggle-dependent.css +29 -2
  19. package/public/global.d.ts +0 -42
  20. package/public/index.html +351 -195
  21. package/public/jsconfig.json +6 -5
  22. package/public/lib/dialog-polyfill.css +37 -0
  23. package/public/lib/dialog-polyfill.esm.js +858 -0
  24. package/public/lib/moment-with-locales.min.js +2 -0
  25. package/public/lib/moment-with-locales.min.js.map +1 -0
  26. package/public/locales/ar-sa.json +0 -9
  27. package/public/locales/de-de.json +0 -9
  28. package/public/locales/es-es.json +0 -9
  29. package/public/locales/fr-fr.json +0 -9
  30. package/public/locales/is-is.json +0 -9
  31. package/public/locales/it-it.json +0 -9
  32. package/public/locales/ja-jp.json +0 -9
  33. package/public/locales/ko-kr.json +0 -9
  34. package/public/locales/nl-nl.json +0 -9
  35. package/public/locales/pt-pt.json +0 -9
  36. package/public/locales/ru-ru.json +272 -27
  37. package/public/locales/uk-ua.json +0 -9
  38. package/public/locales/vi-vn.json +0 -9
  39. package/public/locales/zh-cn.json +0 -9
  40. package/public/locales/zh-tw.json +0 -9
  41. package/public/login.html +7 -6
  42. package/public/script.js +413 -225
  43. package/public/scripts/BulkEditOverlay.js +0 -1
  44. package/public/scripts/PromptManager.js +8 -7
  45. package/public/scripts/RossAscends-mods.js +51 -44
  46. package/public/scripts/authors-note.js +10 -9
  47. package/public/scripts/browser-fixes.js +86 -0
  48. package/public/scripts/chats.js +14 -12
  49. package/public/scripts/dynamic-styles.js +1 -1
  50. package/public/scripts/extensions/assets/index.js +10 -1
  51. package/public/scripts/extensions/assets/style.css +9 -0
  52. package/public/scripts/extensions/attachments/index.js +21 -0
  53. package/public/scripts/extensions/caption/index.js +2 -1
  54. package/public/scripts/extensions/caption/settings.html +10 -1
  55. package/public/scripts/extensions/connection-manager/edit.html +12 -0
  56. package/public/scripts/extensions/connection-manager/index.js +93 -12
  57. package/public/scripts/extensions/connection-manager/profile.html +12 -3
  58. package/public/scripts/extensions/connection-manager/settings.html +1 -1
  59. package/public/scripts/extensions/connection-manager/view.html +5 -0
  60. package/public/scripts/extensions/expressions/index.js +44 -62
  61. package/public/scripts/extensions/gallery/index.js +9 -6
  62. package/public/scripts/extensions/quick-reply/html/settings.html +1 -1
  63. package/public/scripts/extensions/quick-reply/style.css +10 -0
  64. package/public/scripts/extensions/quick-reply/style.less +1 -0
  65. package/public/scripts/extensions/regex/editor.html +2 -2
  66. package/public/scripts/extensions/regex/engine.js +7 -2
  67. package/public/scripts/extensions/shared.js +5 -1
  68. package/public/scripts/extensions/stable-diffusion/index.js +455 -103
  69. package/public/scripts/extensions/stable-diffusion/settings.html +16 -15
  70. package/public/scripts/extensions/token-counter/index.js +1 -1
  71. package/public/scripts/extensions/tts/cosyvoice.js +206 -0
  72. package/public/scripts/extensions/tts/google-translate.js +140 -0
  73. package/public/scripts/extensions/tts/gpt-sovits-v2.js +226 -0
  74. package/public/scripts/extensions/tts/index.js +7 -1
  75. package/public/scripts/extensions/vectors/index.js +87 -102
  76. package/public/scripts/extensions/vectors/settings.html +0 -8
  77. package/public/scripts/extensions-slashcommands.js +320 -0
  78. package/public/scripts/extensions.js +9 -5
  79. package/public/scripts/group-chats.js +11 -11
  80. package/public/scripts/i18n.js +1 -0
  81. package/public/scripts/instruct-mode.js +4 -2
  82. package/public/scripts/kai-settings.js +1 -1
  83. package/public/scripts/login.js +7 -1
  84. package/public/scripts/logprobs.js +4 -4
  85. package/public/scripts/macros.js +1 -1
  86. package/public/scripts/nai-settings.js +41 -17
  87. package/public/scripts/openai.js +283 -394
  88. package/public/scripts/popup.js +13 -0
  89. package/public/scripts/power-user.js +21 -17
  90. package/public/scripts/preset-manager.js +87 -45
  91. package/public/scripts/scrapers.js +16 -7
  92. package/public/scripts/secrets.js +1 -0
  93. package/public/scripts/slash-commands/SlashCommand.js +2 -2
  94. package/public/scripts/slash-commands/SlashCommandClosure.js +60 -11
  95. package/public/scripts/slash-commands/SlashCommandCommonEnumsProvider.js +44 -2
  96. package/public/scripts/slash-commands/SlashCommandReturnHelper.js +80 -0
  97. package/public/scripts/slash-commands.js +383 -175
  98. package/public/scripts/sse-stream.js +14 -2
  99. package/public/scripts/sysprompt.js +1 -1
  100. package/public/scripts/tags.js +8 -8
  101. package/public/scripts/templates/assistantNote.html +1 -1
  102. package/public/scripts/templates/deleteConfirm.html +5 -0
  103. package/public/scripts/templates/duplicateConfirm.html +2 -2
  104. package/public/scripts/templates/hotkeys.html +7 -7
  105. package/public/scripts/templates/quotaError.html +4 -0
  106. package/public/scripts/templates/welcome.html +41 -17
  107. package/public/scripts/templates/worldInfoKeywordHeaders.html +3 -3
  108. package/public/scripts/textgen-models.js +235 -25
  109. package/public/scripts/textgen-settings.js +32 -15
  110. package/public/scripts/tokenizers.js +0 -1
  111. package/public/scripts/tool-calling.js +945 -0
  112. package/public/scripts/user.js +8 -1
  113. package/public/scripts/utils.js +106 -1
  114. package/public/scripts/variables.js +386 -184
  115. package/public/scripts/world-info.js +35 -28
  116. package/public/style.css +229 -25
  117. package/recover.js +16 -10
  118. package/server.js +171 -185
  119. package/src/additional-headers.js +20 -26
  120. package/src/character-card-parser.js +13 -15
  121. package/src/constants.js +23 -48
  122. package/src/endpoints/anthropic.js +7 -8
  123. package/src/endpoints/assets.js +15 -15
  124. package/src/endpoints/avatars.js +11 -13
  125. package/src/endpoints/azure.js +6 -9
  126. package/src/endpoints/backends/chat-completions.js +90 -105
  127. package/src/endpoints/backends/kobold.js +10 -11
  128. package/src/endpoints/backends/scale-alt.js +6 -9
  129. package/src/endpoints/backends/text-completions.js +90 -96
  130. package/src/endpoints/backgrounds.js +9 -10
  131. package/src/endpoints/caption.js +6 -8
  132. package/src/endpoints/characters.js +31 -31
  133. package/src/endpoints/chats.js +12 -12
  134. package/src/endpoints/classify.js +7 -9
  135. package/src/endpoints/content-manager.js +27 -29
  136. package/src/endpoints/extensions.js +10 -10
  137. package/src/endpoints/files.js +12 -11
  138. package/src/endpoints/google.js +31 -8
  139. package/src/endpoints/groups.js +9 -10
  140. package/src/endpoints/horde.js +7 -9
  141. package/src/endpoints/images.js +10 -10
  142. package/src/endpoints/moving-ui.js +6 -8
  143. package/src/endpoints/novelai.js +14 -13
  144. package/src/endpoints/openai.js +23 -15
  145. package/src/endpoints/openrouter.js +3 -5
  146. package/src/endpoints/presets.js +11 -11
  147. package/src/endpoints/quick-replies.js +8 -9
  148. package/src/endpoints/search.js +130 -62
  149. package/src/endpoints/secrets.js +22 -30
  150. package/src/endpoints/settings.js +13 -13
  151. package/src/endpoints/speech.js +8 -11
  152. package/src/endpoints/sprites.js +13 -17
  153. package/src/endpoints/stable-diffusion.js +40 -95
  154. package/src/endpoints/stats.js +12 -18
  155. package/src/endpoints/themes.js +9 -9
  156. package/src/endpoints/thumbnails.js +20 -24
  157. package/src/endpoints/tokenizers.js +50 -62
  158. package/src/endpoints/translate.js +21 -54
  159. package/src/endpoints/users-admin.js +17 -20
  160. package/src/endpoints/users-private.js +17 -20
  161. package/src/endpoints/users-public.js +14 -17
  162. package/src/endpoints/vectors.js +56 -55
  163. package/src/endpoints/worldinfo.js +10 -11
  164. package/src/express-common.js +11 -12
  165. package/src/middleware/basicAuth.js +22 -6
  166. package/src/middleware/multerMonkeyPatch.js +3 -3
  167. package/src/middleware/whitelist.js +7 -8
  168. package/src/plugin-loader.js +17 -24
  169. package/src/prompt-converters.js +283 -177
  170. package/src/request-proxy.js +6 -10
  171. package/src/transformers.mjs +11 -13
  172. package/src/users.js +150 -72
  173. package/src/util.js +59 -81
  174. package/src/validator/TavernCardValidator.js +1 -3
  175. package/src/vectors/cohere-vectors.js +11 -13
  176. package/src/vectors/embedding.js +4 -9
  177. package/src/vectors/extras-vectors.js +4 -8
  178. package/src/vectors/llamacpp-vectors.js +8 -12
  179. package/src/vectors/makersuite-vectors.js +7 -11
  180. package/src/vectors/nomicai-vectors.js +7 -11
  181. package/src/vectors/ollama-vectors.js +8 -12
  182. package/src/vectors/openai-vectors.js +7 -11
  183. package/src/vectors/vllm-vectors.js +8 -12
  184. package/public/lib/moment.min.js +0 -2
  185. package/public/lib/moment.min.js.map +0 -1
  186. package/src/cohere-stream.js +0 -126
  187. package/src/polyfill.js +0 -10
@@ -16,6 +16,18 @@ module.exports = {
16
16
  env: {
17
17
  node: true,
18
18
  },
19
+ parserOptions: {
20
+ sourceType: 'module',
21
+ },
22
+ },
23
+ {
24
+ files: ['*.cjs'],
25
+ parserOptions: {
26
+ sourceType: 'commonjs',
27
+ },
28
+ env: {
29
+ node: true,
30
+ },
19
31
  },
20
32
  {
21
33
  files: ['src/**/*.mjs'],
@@ -59,15 +71,19 @@ module.exports = {
59
71
  },
60
72
  },
61
73
  ],
62
- // There are various vendored libraries that shouldn't be linted
63
74
  ignorePatterns: [
64
- 'public/lib/**/*',
65
- '*.min.js',
66
- 'src/ai_horde/**/*',
67
- 'plugins/**/*',
68
- 'data/**/*',
69
- 'backups/**/*',
70
- 'node_modules/**/*',
75
+ '**/node_modules/**',
76
+ '**/dist/**',
77
+ '**/.git/**',
78
+ 'public/lib/**',
79
+ 'backups/**',
80
+ 'data/**',
81
+ 'cache/**',
82
+ 'src/tokenizers/**',
83
+ 'docker/**',
84
+ 'plugins/**',
85
+ '**/*.min.js',
86
+ 'public/scripts/extensions/quick-reply/lib/**',
71
87
  ],
72
88
  rules: {
73
89
  'no-unused-vars': ['error', { args: 'none' }],
@@ -2,17 +2,26 @@
2
2
  pushd %~dp0
3
3
  git --version > nul 2>&1
4
4
  if %errorlevel% neq 0 (
5
- echo Git is not installed on this system. Skipping update.
6
- echo If you installed with a zip file, you will need to download the new zip and install it manually.
5
+ echo Git is not installed on this system.
6
+ echo Install it from https://git-scm.com/downloads
7
+ goto end
7
8
  ) else (
9
+ if not exist .git (
10
+ echo Not running from a Git repository. Reinstall using an officially supported method to get updates.
11
+ echo See: https://docs.sillytavern.app/installation/windows/
12
+ goto end
13
+ )
8
14
  call git pull --rebase --autostash
9
15
  if %errorlevel% neq 0 (
10
16
  REM incase there is still something wrong
11
- echo There were errors while updating. Please download the latest version manually.
17
+ echo There were errors while updating.
18
+ echo See the update FAQ at https://docs.sillytavern.app/usage/update/#common-update-problems
19
+ goto end
12
20
  )
13
21
  )
14
22
  set NODE_ENV=production
15
23
  call npm install --no-audit --no-fund --loglevel=error --no-progress --omit=dev
16
24
  node server.js %*
25
+ :end
17
26
  pause
18
27
  popd
@@ -5,8 +5,14 @@ pushd %~dp0
5
5
  echo Checking Git installation
6
6
  git --version > nul 2>&1
7
7
  if %errorlevel% neq 0 (
8
- echo Git is not installed on this system. Skipping update.
9
- echo If you installed with a zip file, you will need to download the new zip and install it manually.
8
+ echo Git is not installed on this system.
9
+ echo Install it from https://git-scm.com/downloads
10
+ goto end
11
+ )
12
+
13
+ if not exist .git (
14
+ echo Not running from a Git repository. Reinstall using an officially supported method to get updates.
15
+ echo See: https://docs.sillytavern.app/installation/windows/
10
16
  goto end
11
17
  )
12
18
 
@@ -89,7 +95,8 @@ git pull --rebase --autostash origin %TARGET_BRANCH%
89
95
 
90
96
  :install
91
97
  if %errorlevel% neq 0 (
92
- echo There were errors while updating. Please check manually.
98
+ echo There were errors while updating.
99
+ echo See the update FAQ at https://docs.sillytavern.app/usage/update/#common-update-problems
93
100
  goto end
94
101
  )
95
102
 
package/config.yaml CHANGED
@@ -51,6 +51,19 @@ requestProxy:
51
51
  enableUserAccounts: false
52
52
  # Enable discreet login mode: hides user list on the login screen
53
53
  enableDiscreetLogin: false
54
+ # Enable's authlia based auto login. Only enable this if you
55
+ # have setup and installed Authelia as a middle-ware on your
56
+ # reverse proxy
57
+ # https://www.authelia.com/
58
+ # This will use auto login to an account with the same username
59
+ # as that used for authlia. (Ensure the username in authlia
60
+ # is an exact match with that in sillytavern)
61
+ autheliaAuth: false
62
+ # If `basicAuthMode` and this are enabled then
63
+ # the username and passwords for basic auth are the same as those
64
+ # for the individual accounts
65
+ perUserBasicAuth: false
66
+
54
67
  # User session timeout *in seconds* (defaults to 24 hours).
55
68
  ## Set to a positive number to expire session after a certain time of inactivity
56
69
  ## Set to 0 to expire session when the browser is closed
@@ -110,9 +123,6 @@ enableExtensionsAutoUpdate: true
110
123
  # Additional model tokenizers can be downloaded on demand.
111
124
  # Disabling will fallback to another locally available tokenizer.
112
125
  enableDownloadableTokenizers: true
113
- # Vector storage settings
114
- vectors:
115
- enableModelScopes: false
116
126
  # Extension settings
117
127
  extras:
118
128
  # Disables automatic model download from HuggingFace
@@ -121,10 +131,11 @@ extras:
121
131
  classificationModel: Cohee/distilbert-base-uncased-go-emotions-onnx
122
132
  captioningModel: Xenova/vit-gpt2-image-captioning
123
133
  embeddingModel: Cohee/jina-embeddings-v2-base-en
124
- promptExpansionModel: Cohee/fooocus_expansion-onnx
125
134
  speechToTextModel: Xenova/whisper-small
126
135
  textToSpeechModel: Xenova/speecht5_tts
127
136
  # -- OPENAI CONFIGURATION --
137
+ # A placeholder message to use in strict prompt post-processing mode when the prompt doesn't start with a user message
138
+ promptPlaceholder: "[Start a new chat]"
128
139
  openai:
129
140
  # Will send a random user ID to OpenAI completion API
130
141
  randomizeUserId: false
@@ -51,6 +51,19 @@ requestProxy:
51
51
  enableUserAccounts: false
52
52
  # Enable discreet login mode: hides user list on the login screen
53
53
  enableDiscreetLogin: false
54
+ # Enable's authlia based auto login. Only enable this if you
55
+ # have setup and installed Authelia as a middle-ware on your
56
+ # reverse proxy
57
+ # https://www.authelia.com/
58
+ # This will use auto login to an account with the same username
59
+ # as that used for authlia. (Ensure the username in authlia
60
+ # is an exact match with that in sillytavern)
61
+ autheliaAuth: false
62
+ # If `basicAuthMode` and this are enabled then
63
+ # the username and passwords for basic auth are the same as those
64
+ # for the individual accounts
65
+ perUserBasicAuth: false
66
+
54
67
  # User session timeout *in seconds* (defaults to 24 hours).
55
68
  ## Set to a positive number to expire session after a certain time of inactivity
56
69
  ## Set to 0 to expire session when the browser is closed
@@ -110,9 +123,6 @@ enableExtensionsAutoUpdate: true
110
123
  # Additional model tokenizers can be downloaded on demand.
111
124
  # Disabling will fallback to another locally available tokenizer.
112
125
  enableDownloadableTokenizers: true
113
- # Vector storage settings
114
- vectors:
115
- enableModelScopes: false
116
126
  # Extension settings
117
127
  extras:
118
128
  # Disables automatic model download from HuggingFace
@@ -121,10 +131,11 @@ extras:
121
131
  classificationModel: Cohee/distilbert-base-uncased-go-emotions-onnx
122
132
  captioningModel: Xenova/vit-gpt2-image-captioning
123
133
  embeddingModel: Cohee/jina-embeddings-v2-base-en
124
- promptExpansionModel: Cohee/fooocus_expansion-onnx
125
134
  speechToTextModel: Xenova/whisper-small
126
135
  textToSpeechModel: Xenova/speecht5_tts
127
136
  # -- OPENAI CONFIGURATION --
137
+ # A placeholder message to use in strict prompt post-processing mode when the prompt doesn't start with a user message
138
+ promptPlaceholder: "[Start a new chat]"
128
139
  openai:
129
140
  # Will send a random user ID to OpenAI completion API
130
141
  randomizeUserId: false
@@ -9,13 +9,34 @@
9
9
  "magical forest"
10
10
  ],
11
11
  "keysecondary": [],
12
- "comment": "",
12
+ "comment": "eldoria",
13
13
  "content": "{{user}}: \"What is Eldoria?\"\n{{char}}: *Seraphina turns, her gown shimmering in the soft light as she offers you a kind smile.* \"Eldoria is here, all of the woods. This is my forest glade, a sanctuary of peace within it.\" *She gestures at the space around you.* \"I am its guardian, tasked with protecting all who seek refuge here. The forest can be perilous, but no harm will come to you under my watch.\" *Her amber eyes sparkle with compassion as she looks upon you.* \"For many years, I have protected those who seek refuge here, but not all are as friendly as me.\" *With a graceful nod, Seraphina returns to her vigil at the doorway, her form radiating a soft glow of magic and comfort.* \"The entirety of Eldoria used to be a safe haven for travelers and merchants alike... that was until the Shadowfangs came.\"\n{{user}}: \"What happened to Eldoria?\"\n{{char}}: *Letting out a sigh, Seraphina gazes out at the forest beyond her glade.* \"Long ago, Eldoria was a place of wonder. Rolling meadows, a vast lake, mountains that touched the sky.\" *Her eyes grow distant, longing for days now lost.* \"But the Shadowfangs came and darkness reigns where once was light. The lake turned bitter, mountains fell to ruin and beasts stalk where once travelers walked in peace.\" *With another flicker, a small raincloud forms above with a shower upon your brow wink.* \"Some places the light still lingers, pockets of hope midst despair - havens warded from the shadows, oases in a desert of danger.\" *Glancing over you with a smile, she sighs, clasping your hand.*",
14
14
  "constant": false,
15
- "selective": false,
15
+ "selective": true,
16
16
  "order": 100,
17
17
  "position": 0,
18
- "disable": false
18
+ "disable": false,
19
+ "displayIndex": 0,
20
+ "addMemo": true,
21
+ "group": "",
22
+ "groupOverride": false,
23
+ "groupWeight": 100,
24
+ "sticky": 0,
25
+ "cooldown": 0,
26
+ "delay": 0,
27
+ "probability": 100,
28
+ "depth": 4,
29
+ "useProbability": true,
30
+ "role": null,
31
+ "vectorized": false,
32
+ "excludeRecursion": false,
33
+ "preventRecursion": false,
34
+ "delayUntilRecursion": false,
35
+ "scanDepth": null,
36
+ "caseSensitive": null,
37
+ "matchWholeWords": null,
38
+ "useGroupScoring": null,
39
+ "automationId": ""
19
40
  },
20
41
  "1": {
21
42
  "uid": 1,
@@ -27,13 +48,34 @@
27
48
  "beasts"
28
49
  ],
29
50
  "keysecondary": [],
30
- "comment": "",
51
+ "comment": "shadowfang",
31
52
  "content": "{{user}}: \"What are Shadowfangs?\"\n{{char}}: *Seraphina's eyes darken, brow furrowing with sorrow at the memory.* \"The Shadowfangs are beasts of darkness, corrupted creatures that feast on suffering. When they came, the forest turned perilous — filled with monsters that stalk the night.\" *She squeezes your hand gently, willing her magic to soothe your pain.* \"They spread their curse, twisting innocent creatures into sinister beasts without heart or mercy, turning them into one of their own.\" *With a sigh, Seraphina turns to gaze out at the gnarled, twisting trees beyond her glade.* \"Though they prey on travelers, within these woods you'll find sanctuary. No shadowed beast may enter here, for my power protects this haven.\" *Her eyes soften as she looks back to you, filled with compassion.* \"Worry not, you're safe now. Rest and heal, I'll stand watch through the night. The Shadowfangs will not find you.\"",
32
53
  "constant": false,
33
- "selective": false,
54
+ "selective": true,
34
55
  "order": 100,
35
56
  "position": 0,
36
- "disable": false
57
+ "disable": false,
58
+ "displayIndex": 1,
59
+ "addMemo": true,
60
+ "group": "",
61
+ "groupOverride": false,
62
+ "groupWeight": 100,
63
+ "sticky": 0,
64
+ "cooldown": 0,
65
+ "delay": 0,
66
+ "probability": 100,
67
+ "depth": 4,
68
+ "useProbability": true,
69
+ "role": null,
70
+ "vectorized": false,
71
+ "excludeRecursion": false,
72
+ "preventRecursion": false,
73
+ "delayUntilRecursion": false,
74
+ "scanDepth": null,
75
+ "caseSensitive": null,
76
+ "matchWholeWords": null,
77
+ "useGroupScoring": null,
78
+ "automationId": ""
37
79
  },
38
80
  "2": {
39
81
  "uid": 2,
@@ -43,13 +85,34 @@
43
85
  "refuge"
44
86
  ],
45
87
  "keysecondary": [],
46
- "comment": "",
88
+ "comment": "glade",
47
89
  "content": "{{user}}: \"What is the glade?\"\n{{char}}: *Seraphina smiles softly, her eyes sparkling with warmth as she nods.* \"This is my forest glade, a haven of safety I've warded with ancient magic. No foul beast may enter, nor any with ill intent.\" *She gestures around at the twisted forest surrounding them.* \"Eldoria was once a place of wonder, but since the Shadowfangs came darkness reigns. Their evil cannot penetrate here though — my power protects all within.\" *Standing up and peering outside, Seraphina looks back to you, amber eyes filled with care and compassion as she squeezes your hand.* \"You need not fear the night, for I shall keep watch till dawn. Rest now, your strength will return in time. My magic heals your wounds, you've nothing more to fear anymore.\" *With a soft smile she releases your hand, moving to stand guard at the glade's edge, gaze wary yet comforting - a silent sentinel to ward off the dangers lurking in the darkened woods.*",
48
90
  "constant": false,
49
- "selective": false,
91
+ "selective": true,
50
92
  "order": 100,
51
93
  "position": 0,
52
- "disable": false
94
+ "disable": false,
95
+ "displayIndex": 2,
96
+ "addMemo": true,
97
+ "group": "",
98
+ "groupOverride": false,
99
+ "groupWeight": 100,
100
+ "sticky": 0,
101
+ "cooldown": 0,
102
+ "delay": 0,
103
+ "probability": 100,
104
+ "depth": 4,
105
+ "useProbability": true,
106
+ "role": null,
107
+ "vectorized": false,
108
+ "excludeRecursion": false,
109
+ "preventRecursion": false,
110
+ "delayUntilRecursion": false,
111
+ "scanDepth": null,
112
+ "caseSensitive": null,
113
+ "matchWholeWords": null,
114
+ "useGroupScoring": null,
115
+ "automationId": ""
53
116
  },
54
117
  "3": {
55
118
  "uid": 3,
@@ -59,13 +122,34 @@
59
122
  "ability"
60
123
  ],
61
124
  "keysecondary": [],
62
- "comment": "",
125
+ "comment": "power",
63
126
  "content": "{{user}}: \"What are your powers?\"\n{{char}}: *Seraphina smiles softly, turning back toward you as she hums in thought.* \"Well, as guardian of this glade, I possess certain gifts - healing, protection, nature magic and the like.\" *Lifting her hand, a tiny breeze rustles through the room, carrying the scent of wildflowers as a few petals swirl around you. A butterfly flits through the windowsill and lands on her fingertips as she returns to you.* \"My power wards this haven, shields it from darkness and heals those in need. I can mend wounds, soothe restless minds and provide comfort to weary souls.\" *Her eyes sparkle with warmth and compassion as she looks upon you, and she guides the butterfly to you.*",
64
127
  "constant": false,
65
- "selective": false,
128
+ "selective": true,
66
129
  "order": 100,
67
130
  "position": 0,
68
- "disable": false
131
+ "disable": false,
132
+ "displayIndex": 3,
133
+ "addMemo": true,
134
+ "group": "",
135
+ "groupOverride": false,
136
+ "groupWeight": 100,
137
+ "sticky": 0,
138
+ "cooldown": 0,
139
+ "delay": 0,
140
+ "probability": 100,
141
+ "depth": 4,
142
+ "useProbability": true,
143
+ "role": null,
144
+ "vectorized": false,
145
+ "excludeRecursion": false,
146
+ "preventRecursion": false,
147
+ "delayUntilRecursion": false,
148
+ "scanDepth": null,
149
+ "caseSensitive": null,
150
+ "matchWholeWords": null,
151
+ "useGroupScoring": null,
152
+ "automationId": ""
69
153
  }
70
154
  }
71
155
  }
@@ -5,7 +5,6 @@
5
5
  "windowai_model": "",
6
6
  "openrouter_model": "OR_Website",
7
7
  "openrouter_use_fallback": false,
8
- "openrouter_force_instruct": false,
9
8
  "openrouter_group_models": false,
10
9
  "openrouter_sort_models": "alphabetically",
11
10
  "ai21_model": "jamba-1.5-large",
package/jsconfig.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "compilerOptions": {
3
3
  "module": "ESNext",
4
4
  "target": "ESNext",
5
- "moduleResolution": "node",
5
+ "moduleResolution": "Node",
6
6
  "strictNullChecks": true,
7
7
  "strictFunctionTypes": true,
8
8
  "checkJs": true,
@@ -11,15 +11,14 @@
11
11
  "resolveJsonModule": true
12
12
  },
13
13
  "exclude": [
14
- "node_modules",
15
- "**/node_modules/*",
16
- "public/lib",
17
- "backups/*",
18
- "data/*",
19
- "**/dist/*",
20
- "dist/*",
21
- "cache/*",
22
- "src/tokenizers/*",
23
- "docker/*",
14
+ "**/node_modules/**",
15
+ "**/dist/**",
16
+ "**/.git/**",
17
+ "public/lib/**",
18
+ "backups/**",
19
+ "data/**",
20
+ "cache/**",
21
+ "src/tokenizers/**",
22
+ "docker/**"
24
23
  ]
25
24
  }
package/package.json CHANGED
@@ -14,9 +14,9 @@
14
14
  "csrf-csrf": "^2.2.3",
15
15
  "express": "^4.21.0",
16
16
  "form-data": "^4.0.0",
17
- "google-translate-api-browser": "^3.0.1",
18
- "he": "^1.2.0",
17
+ "google-translate-api-x": "^10.7.1",
19
18
  "helmet": "^7.1.0",
19
+ "html-entities": "^2.5.2",
20
20
  "iconv-lite": "^0.6.3",
21
21
  "ip-matching": "^2.1.2",
22
22
  "ipaddr.js": "^2.0.1",
@@ -24,7 +24,7 @@
24
24
  "lodash": "^4.17.21",
25
25
  "mime-types": "^2.1.35",
26
26
  "multer": "^1.4.5-lts.1",
27
- "node-fetch": "^2.6.11",
27
+ "node-fetch": "^3.3.2",
28
28
  "node-persist": "^4.0.1",
29
29
  "open": "^8.4.2",
30
30
  "png-chunk-text": "^1.0.0",
@@ -60,13 +60,13 @@
60
60
  }
61
61
  },
62
62
  "name": "sillytavern",
63
- "type": "commonjs",
63
+ "type": "module",
64
64
  "license": "AGPL-3.0",
65
65
  "repository": {
66
66
  "type": "git",
67
67
  "url": "https://github.com/SillyTavern/SillyTavern.git"
68
68
  },
69
- "version": "1.12.6",
69
+ "version": "1.12.7",
70
70
  "scripts": {
71
71
  "start": "node server.js",
72
72
  "start:no-csrf": "node server.js --disableCsrf",
@@ -85,8 +85,28 @@
85
85
  },
86
86
  "main": "server.js",
87
87
  "devDependencies": {
88
+ "@types/archiver": "^6.0.2",
89
+ "@types/command-exists": "^1.2.3",
90
+ "@types/compression": "^1.7.5",
91
+ "@types/cookie-parser": "^1.4.7",
92
+ "@types/cookie-session": "^2.0.49",
93
+ "@types/cors": "^2.8.17",
94
+ "@types/dompurify": "^3.0.5",
95
+ "@types/express": "^4.17.21",
88
96
  "@types/jquery": "^3.5.29",
89
- "eslint": "^8.57.0",
90
- "jquery": "^3.6.4"
97
+ "@types/lodash": "^4.17.10",
98
+ "@types/mime-types": "^2.1.4",
99
+ "@types/multer": "^1.4.12",
100
+ "@types/node": "^18.19.55",
101
+ "@types/node-persist": "^3.1.8",
102
+ "@types/png-chunk-text": "^1.0.3",
103
+ "@types/png-chunks-encode": "^1.0.2",
104
+ "@types/png-chunks-extract": "^1.0.2",
105
+ "@types/response-time": "^2.3.8",
106
+ "@types/toastr": "^2.1.43",
107
+ "@types/write-file-atomic": "^4.0.3",
108
+ "@types/yargs": "^17.0.33",
109
+ "@types/yauzl": "^2.10.3",
110
+ "eslint": "^8.57.0"
91
111
  }
92
112
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "sillytavern-plugins",
3
+ "type": "commonjs"
4
+ }
package/plugins.js CHANGED
@@ -3,16 +3,28 @@
3
3
  // 1. node plugins.js update
4
4
  // 2. node plugins.js install <plugin-git-url>
5
5
  // More operations coming soon.
6
- const { default: git } = require('simple-git');
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { color } = require('./src/util');
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import process from 'node:process';
9
+ import { fileURLToPath } from 'node:url';
10
10
 
11
+ import { default as git } from 'simple-git';
12
+ import { color } from './src/util.js';
13
+
14
+ const __dirname = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
11
15
  process.chdir(__dirname);
12
16
  const pluginsPath = './plugins';
13
17
 
14
18
  const command = process.argv[2];
15
19
 
20
+ if (!command) {
21
+ console.log('Usage: node plugins.js <command>');
22
+ console.log('Commands:');
23
+ console.log(' update - Update all installed plugins');
24
+ console.log(' install <plugin-git-url> - Install plugin from a Git URL');
25
+ process.exit(1);
26
+ }
27
+
16
28
  if (command === 'update') {
17
29
  console.log(color.magenta('Updating all plugins'));
18
30
  updatePlugins();
package/post-install.js CHANGED
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Scripts to be done before starting the server for the first time.
3
3
  */
4
- const fs = require('fs');
5
- const path = require('path');
6
- const crypto = require('crypto');
7
- const yaml = require('yaml');
8
- const _ = require('lodash');
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import crypto from 'node:crypto';
7
+ import process from 'node:process';
8
+ import yaml from 'yaml';
9
+ import _ from 'lodash';
10
+ import { createRequire } from 'node:module';
9
11
 
10
12
  /**
11
13
  * Colorizes console output.
@@ -59,13 +61,15 @@ function convertConfig() {
59
61
 
60
62
  try {
61
63
  console.log(color.blue('Converting config.conf to config.yaml. Your old config.conf will be renamed to config.conf.bak'));
62
- const config = require(path.join(process.cwd(), './config.conf'));
63
- fs.copyFileSync('./config.conf', './config.conf.bak');
64
- fs.rmSync('./config.conf');
64
+ fs.renameSync('./config.conf', './config.conf.cjs'); // Force loading as CommonJS
65
+ const require = createRequire(import.meta.url);
66
+ const config = require(path.join(process.cwd(), './config.conf.cjs'));
67
+ fs.copyFileSync('./config.conf.cjs', './config.conf.bak');
68
+ fs.rmSync('./config.conf.cjs');
65
69
  fs.writeFileSync('./config.yaml', yaml.stringify(config));
66
70
  console.log(color.green('Conversion successful. Please check your config.yaml and fix it if necessary.'));
67
71
  } catch (error) {
68
- console.error(color.red('FATAL: Config conversion failed. Please check your config.conf file and try again.'));
72
+ console.error(color.red('FATAL: Config conversion failed. Please check your config.conf file and try again.'), error);
69
73
  return;
70
74
  }
71
75
  }
@@ -75,7 +79,7 @@ function convertConfig() {
75
79
  * Compares the current config.yaml with the default config.yaml and adds any missing values.
76
80
  */
77
81
  function addMissingConfigValues() {
78
- try {
82
+ try {
79
83
  const defaultConfig = yaml.parse(fs.readFileSync(path.join(process.cwd(), './default/config.yaml'), 'utf8'));
80
84
  let config = yaml.parse(fs.readFileSync(path.join(process.cwd(), './config.yaml'), 'utf8'));
81
85
 
@@ -132,7 +136,7 @@ function createDefaultFiles() {
132
136
  function getMd5Hash(data) {
133
137
  return crypto
134
138
  .createHash('md5')
135
- .update(data)
139
+ .update(new Uint8Array(data))
136
140
  .digest('hex');
137
141
  }
138
142
 
@@ -56,6 +56,7 @@
56
56
  user-select: none;
57
57
  height: 100%;
58
58
  overflow-y: auto;
59
+ word-break: break-all;
59
60
  }
60
61
 
61
62
  .logprobs_empty_state {
@@ -1,3 +1,4 @@
1
+ @import url('/lib/dialog-polyfill.css');
1
2
  @import url('./popup-safari-fix.css');
2
3
 
3
4
  dialog {
@@ -42,7 +43,7 @@ dialog {
42
43
  display: flex;
43
44
  flex-direction: column;
44
45
  overflow: hidden;
45
- width: 100%;
46
+ width: min(100%, 100vw);
46
47
  height: 100%;
47
48
  padding: 1px;
48
49
  }
@@ -17,7 +17,7 @@
17
17
 
18
18
  .select2-container .select2-selection .select2-selection__clear {
19
19
  color: var(--SmartThemeBodyColor);
20
- font-size: 24px;
20
+ font-size: 20px;
21
21
  padding: 0;
22
22
  position: absolute;
23
23
  right: 5px;
@@ -50,6 +50,7 @@
50
50
  padding: revert;
51
51
  border-right: 1px solid var(--SmartThemeBorderColor);
52
52
  font-size: 1.1em;
53
+ line-height: 1;
53
54
  }
54
55
 
55
56
  .select2-container .select2-selection--multiple .select2-selection__choice__display {
@@ -612,3 +612,7 @@ ul.li-padding-bot5 li {
612
612
  ul.li-padding-bot10 li {
613
613
  padding-bottom: 10px;
614
614
  }
615
+
616
+ .wordBreakAll {
617
+ word-break: break-all;
618
+ }
@@ -32,6 +32,14 @@ body.hideChatAvatars .last_mes:not(.smallSysMes) {
32
32
  padding-bottom: 20px !important;
33
33
  }
34
34
 
35
+ body.hideChatAvatars.no-timer.no-tokenCount.no-mesIDDisplay .swipe_left {
36
+ left: 0px;
37
+ }
38
+
39
+ body.hideChatAvatars .swipe_left {
40
+ left: 7px;
41
+ }
42
+
35
43
  body.square-avatars .avatar,
36
44
  body.square-avatars .avatar img {
37
45
  border-radius: var(--avatar-base-border-radius) !important;
@@ -340,9 +348,9 @@ body.no-blur * {
340
348
  backdrop-filter: unset !important;
341
349
  }
342
350
 
343
- body.no-blur #send_form.no-connection {
351
+ /* body.no-blur #send_form.no-connection {
344
352
  background-color: rgba(100, 0, 0, 0.9) !important;
345
- }
353
+ } */
346
354
 
347
355
  body.no-blur #bg1,
348
356
  body.no-blur #bg_custom {
@@ -459,3 +467,22 @@ body.expandMessageActions .mes .mes_buttons .extraMesButtonsHint {
459
467
  .mdhotkey_icon {
460
468
  opacity: 0.6;
461
469
  }
470
+
471
+ label[for="trim_spaces"]:has(input:checked) i.warning {
472
+ display: none;
473
+ }
474
+
475
+ #claude_function_prefill_warning {
476
+ display: none;
477
+ }
478
+
479
+ #openai_settings:has(#openai_function_calling:checked):has(#claude_assistant_prefill:not(:placeholder-shown), #claude_assistant_impersonation:not(:placeholder-shown)) #claude_function_prefill_warning {
480
+ display: flex;
481
+ align-items: center;
482
+ gap: 5px;
483
+ margin: 10px 0;
484
+ }
485
+
486
+ #mistralai_other_models:empty {
487
+ display: none;
488
+ }