sillytavern 1.4.1

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 (259) hide show
  1. package/.dockerignore +4 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/workflows/npm-publish.yml +32 -0
  5. package/Dockerfile +49 -0
  6. package/Start.bat +3 -0
  7. package/colab/GPU.ipynb +339 -0
  8. package/colab/extras_server.py +40 -0
  9. package/colab/globals.py +2 -0
  10. package/colab/models.py +77 -0
  11. package/docker/docker-compose.yml +12 -0
  12. package/docker/docker-entrypoint.sh +28 -0
  13. package/faq.md +208 -0
  14. package/package.json +49 -0
  15. package/poe-client.js +638 -0
  16. package/poe-test.js +21 -0
  17. package/poe_graphql/AddHumanMessageMutation.graphql +52 -0
  18. package/poe_graphql/AddMessageBreakMutation.graphql +17 -0
  19. package/poe_graphql/AutoSubscriptionMutation.graphql +7 -0
  20. package/poe_graphql/BioFragment.graphql +8 -0
  21. package/poe_graphql/ChatAddedSubscription.graphql +5 -0
  22. package/poe_graphql/ChatFragment.graphql +6 -0
  23. package/poe_graphql/ChatListPaginationQuery.graphql +316 -0
  24. package/poe_graphql/ChatPaginationQuery.graphql +26 -0
  25. package/poe_graphql/ChatViewQuery.graphql +8 -0
  26. package/poe_graphql/DeleteHumanMessagesMutation.graphql +7 -0
  27. package/poe_graphql/DeleteMessageMutation.graphql +7 -0
  28. package/poe_graphql/HandleFragment.graphql +8 -0
  29. package/poe_graphql/LoginWithVerificationCodeMutation.graphql +13 -0
  30. package/poe_graphql/MessageAddedSubscription.graphql +115 -0
  31. package/poe_graphql/MessageDeletedSubscription.graphql +8 -0
  32. package/poe_graphql/MessageFragment.graphql +13 -0
  33. package/poe_graphql/MessageRemoveVoteMutation.graphql +7 -0
  34. package/poe_graphql/MessageSetVoteMutation.graphql +7 -0
  35. package/poe_graphql/SendVerificationCodeForLoginMutation.graphql +12 -0
  36. package/poe_graphql/ShareMessagesMutation.graphql +9 -0
  37. package/poe_graphql/SignupWithVerificationCodeMutation.graphql +13 -0
  38. package/poe_graphql/StaleChatUpdateMutation.graphql +7 -0
  39. package/poe_graphql/SubscriptionsMutation.graphql +9 -0
  40. package/poe_graphql/SummarizePlainPostQuery.graphql +3 -0
  41. package/poe_graphql/SummarizeQuotePostQuery.graphql +3 -0
  42. package/poe_graphql/SummarizeSharePostQuery.graphql +3 -0
  43. package/poe_graphql/UserSnippetFragment.graphql +14 -0
  44. package/poe_graphql/ViewerInfoQuery.graphql +21 -0
  45. package/poe_graphql/ViewerMessageLimitUpdatedSubscription.graphql +81 -0
  46. package/poe_graphql/ViewerStateFragment.graphql +30 -0
  47. package/poe_graphql/ViewerStateUpdatedSubscription.graphql +63 -0
  48. package/public/KoboldAI Settings/Ace of Spades 13B.settings +22 -0
  49. package/public/KoboldAI Settings/Adventurer-NeoX-20B-Erebus.settings +54 -0
  50. package/public/KoboldAI Settings/Basic Coherence 13B.settings +22 -0
  51. package/public/KoboldAI Settings/Best Guess 6B.settings +22 -0
  52. package/public/KoboldAI Settings/Calibrated-Pygmalion-6b.settings +47 -0
  53. package/public/KoboldAI Settings/Classic-Pygmalion-2.7b.settings +46 -0
  54. package/public/KoboldAI Settings/Classic-Pygmalion-6b.settings +47 -0
  55. package/public/KoboldAI Settings/Coherent Creativity 6B.settings +22 -0
  56. package/public/KoboldAI Settings/Default-TavernAI.settings +22 -0
  57. package/public/KoboldAI Settings/DragonSlayer-Pygmalion-6b.settings +47 -0
  58. package/public/KoboldAI Settings/GPU-Pygmalion-6b.settings +47 -0
  59. package/public/KoboldAI Settings/Genesis 13B.settings +22 -0
  60. package/public/KoboldAI Settings/Godlike.settings +22 -0
  61. package/public/KoboldAI Settings/Good Winds.settings +22 -0
  62. package/public/KoboldAI Settings/Lancer-OPT-2.7B-Erebus.settings +54 -0
  63. package/public/KoboldAI Settings/Liminal Drift.settings +22 -0
  64. package/public/KoboldAI Settings/Low Rider 13B.settings +22 -0
  65. package/public/KoboldAI Settings/Luna Moth 6B.settings +22 -0
  66. package/public/KoboldAI Settings/Mayday.settings +22 -0
  67. package/public/KoboldAI Settings/Ouroboros.settings +22 -0
  68. package/public/KoboldAI Settings/Pleasing Results 6B.settings +22 -0
  69. package/public/KoboldAI Settings/Pro Writer 13B.settings +22 -0
  70. package/public/KoboldAI Settings/RA - Pygmalion-1.3b.settings +46 -0
  71. package/public/KoboldAI Settings/Storywriter 6B.settings +22 -0
  72. package/public/NovelAI Settings/Classic-Euterpe.settings +14 -0
  73. package/public/NovelAI Settings/Classic-Krake.settings +14 -0
  74. package/public/OpenAI Settings/Default.settings +15 -0
  75. package/public/TextGen Settings/Beam Search.settings +15 -0
  76. package/public/TextGen Settings/Contrastive Search.settings +15 -0
  77. package/public/TextGen Settings/Default.settings +15 -0
  78. package/public/TextGen Settings/Deterministic.settings +15 -0
  79. package/public/TextGen Settings/Kobold (Godlike).settings +15 -0
  80. package/public/TextGen Settings/Kobold (Liminal Drift).settings +15 -0
  81. package/public/TextGen Settings/Naive.settings +15 -0
  82. package/public/TextGen Settings/NovelAI (Best Guess).settings +15 -0
  83. package/public/TextGen Settings/NovelAI (Decadence).settings +15 -0
  84. package/public/TextGen Settings/NovelAI (Genesis).settings +15 -0
  85. package/public/TextGen Settings/NovelAI (Lycaenidae).settings +15 -0
  86. package/public/TextGen Settings/NovelAI (Ouroboros).settings +15 -0
  87. package/public/TextGen Settings/NovelAI (Pleasing Results).settings +15 -0
  88. package/public/TextGen Settings/NovelAI (Sphinx Moth).settings +15 -0
  89. package/public/TextGen Settings/NovelAI (Storywriter).settings +15 -0
  90. package/public/TextGen Settings/Pygmalion.settings +15 -0
  91. package/public/css/fontawesome.css +8488 -0
  92. package/public/css/notes.css +46 -0
  93. package/public/css/solid.css +24 -0
  94. package/public/favicon.ico +0 -0
  95. package/public/img/No-Image-Placeholder.svg +309 -0
  96. package/public/img/addbg3.png +0 -0
  97. package/public/img/ai4.png +0 -0
  98. package/public/img/apple-icon-114x114.png +0 -0
  99. package/public/img/apple-icon-144x144.png +0 -0
  100. package/public/img/apple-icon-57x57.png +0 -0
  101. package/public/img/apple-icon-72x72.png +0 -0
  102. package/public/img/book2.png +0 -0
  103. package/public/img/default-expressions/admiration.png +0 -0
  104. package/public/img/default-expressions/amusement.png +0 -0
  105. package/public/img/default-expressions/anger.png +0 -0
  106. package/public/img/default-expressions/annoyance.png +0 -0
  107. package/public/img/default-expressions/approval.png +0 -0
  108. package/public/img/default-expressions/caring.png +0 -0
  109. package/public/img/default-expressions/confusion.png +0 -0
  110. package/public/img/default-expressions/curiosity.png +0 -0
  111. package/public/img/default-expressions/desire.png +0 -0
  112. package/public/img/default-expressions/desire1.png +0 -0
  113. package/public/img/default-expressions/desire2.png +0 -0
  114. package/public/img/default-expressions/disappointment.png +0 -0
  115. package/public/img/default-expressions/disapproval.png +0 -0
  116. package/public/img/default-expressions/disgust.png +0 -0
  117. package/public/img/default-expressions/embarrassment.png +0 -0
  118. package/public/img/default-expressions/excitement.png +0 -0
  119. package/public/img/default-expressions/fear.png +0 -0
  120. package/public/img/default-expressions/gratitude.png +0 -0
  121. package/public/img/default-expressions/grief.png +0 -0
  122. package/public/img/default-expressions/joy.png +0 -0
  123. package/public/img/default-expressions/love.png +0 -0
  124. package/public/img/default-expressions/nervousness.png +0 -0
  125. package/public/img/default-expressions/neutral.png +0 -0
  126. package/public/img/default-expressions/optimism.png +0 -0
  127. package/public/img/default-expressions/pride.png +0 -0
  128. package/public/img/default-expressions/realization.png +0 -0
  129. package/public/img/default-expressions/relief.png +0 -0
  130. package/public/img/default-expressions/remorse.png +0 -0
  131. package/public/img/default-expressions/sadness.png +0 -0
  132. package/public/img/default-expressions/surprise.png +0 -0
  133. package/public/img/five.png +0 -0
  134. package/public/img/times-circle.svg +1 -0
  135. package/public/img/you.png +0 -0
  136. package/public/index.html +1899 -0
  137. package/public/notes/1.html +44 -0
  138. package/public/notes/1.png +0 -0
  139. package/public/notes/10.html +20 -0
  140. package/public/notes/11.html +33 -0
  141. package/public/notes/12.html +27 -0
  142. package/public/notes/13.html +29 -0
  143. package/public/notes/13_1.html +24 -0
  144. package/public/notes/13_2.html +25 -0
  145. package/public/notes/13_3.html +89 -0
  146. package/public/notes/14.html +30 -0
  147. package/public/notes/2.html +37 -0
  148. package/public/notes/2.png +0 -0
  149. package/public/notes/3.html +37 -0
  150. package/public/notes/4.html +105 -0
  151. package/public/notes/6.html +33 -0
  152. package/public/notes/7.html +40 -0
  153. package/public/notes/8.html +19 -0
  154. package/public/notes/9.html +46 -0
  155. package/public/notes/advanced_formatting.html +91 -0
  156. package/public/notes/group_reply_strategy.html +63 -0
  157. package/public/notes/message_sound.html +33 -0
  158. package/public/notes/multigen.html +36 -0
  159. package/public/notes/oai_api_key.html +37 -0
  160. package/public/notes/textgen_streaming.html +29 -0
  161. package/public/notes/token-limits.html +68 -0
  162. package/public/script.js +5131 -0
  163. package/public/scripts/RossAscends-mods.js +750 -0
  164. package/public/scripts/bookmarks.js +130 -0
  165. package/public/scripts/extensions/backgrounds/index.js +129 -0
  166. package/public/scripts/extensions/backgrounds/manifest.json +11 -0
  167. package/public/scripts/extensions/backgrounds/style.css +45 -0
  168. package/public/scripts/extensions/caption/index.js +117 -0
  169. package/public/scripts/extensions/caption/manifest.json +13 -0
  170. package/public/scripts/extensions/caption/style.css +23 -0
  171. package/public/scripts/extensions/dice/droll.js +108 -0
  172. package/public/scripts/extensions/dice/index.js +96 -0
  173. package/public/scripts/extensions/dice/manifest.json +11 -0
  174. package/public/scripts/extensions/dice/style.css +26 -0
  175. package/public/scripts/extensions/expressions/index.js +387 -0
  176. package/public/scripts/extensions/expressions/manifest.json +13 -0
  177. package/public/scripts/extensions/expressions/style.css +115 -0
  178. package/public/scripts/extensions/floating-prompt/index.js +151 -0
  179. package/public/scripts/extensions/floating-prompt/manifest.json +11 -0
  180. package/public/scripts/extensions/floating-prompt/style.css +19 -0
  181. package/public/scripts/extensions/memory/index.js +358 -0
  182. package/public/scripts/extensions/memory/manifest.json +13 -0
  183. package/public/scripts/extensions/memory/style.css +34 -0
  184. package/public/scripts/extensions.js +288 -0
  185. package/public/scripts/f-localStorage.js +27 -0
  186. package/public/scripts/gpt-2-3-tokenizer/README.md +28 -0
  187. package/public/scripts/gpt-2-3-tokenizer/encoder.js +1 -0
  188. package/public/scripts/gpt-2-3-tokenizer/mod.js +169 -0
  189. package/public/scripts/gpt-2-3-tokenizer/vocab.bpe.js +1 -0
  190. package/public/scripts/gpt-3-tokenizer/array-keyed-map.js +210 -0
  191. package/public/scripts/gpt-3-tokenizer/gpt3-tokenizer.js +271 -0
  192. package/public/scripts/gpt-3-tokenizer/gpt3-tokenizer.js.map +1 -0
  193. package/public/scripts/group-chats.js +899 -0
  194. package/public/scripts/horde.js +214 -0
  195. package/public/scripts/jquery-3.5.1.min.js +2 -0
  196. package/public/scripts/jquery-cookie-1.4.1.min.js +2 -0
  197. package/public/scripts/jquery.transit.min.js +1 -0
  198. package/public/scripts/kai-settings.js +179 -0
  199. package/public/scripts/nai-settings.js +108 -0
  200. package/public/scripts/openai.js +973 -0
  201. package/public/scripts/poe.js +360 -0
  202. package/public/scripts/popper.js +2008 -0
  203. package/public/scripts/popper.js.map +1 -0
  204. package/public/scripts/power-user.js +571 -0
  205. package/public/scripts/purify.min.js +3 -0
  206. package/public/scripts/purify.min.js.map +1 -0
  207. package/public/scripts/showdown.min.js +3 -0
  208. package/public/scripts/showdown.min.js.map +1 -0
  209. package/public/scripts/swiped-events.js +165 -0
  210. package/public/scripts/textgen-settings.js +194 -0
  211. package/public/scripts/toolcool-color-picker.js +87 -0
  212. package/public/scripts/utils.js +109 -0
  213. package/public/scripts/world-info.js +661 -0
  214. package/public/sounds/message.mp3 +0 -0
  215. package/public/style.css +3633 -0
  216. package/public/webfonts/NotoSans/NotoSans-Black.woff +0 -0
  217. package/public/webfonts/NotoSans/NotoSans-Black.woff2 +0 -0
  218. package/public/webfonts/NotoSans/NotoSans-BlackItalic.woff +0 -0
  219. package/public/webfonts/NotoSans/NotoSans-BlackItalic.woff2 +0 -0
  220. package/public/webfonts/NotoSans/NotoSans-Bold.woff +0 -0
  221. package/public/webfonts/NotoSans/NotoSans-Bold.woff2 +0 -0
  222. package/public/webfonts/NotoSans/NotoSans-BoldItalic.woff +0 -0
  223. package/public/webfonts/NotoSans/NotoSans-BoldItalic.woff2 +0 -0
  224. package/public/webfonts/NotoSans/NotoSans-ExtraBold.woff +0 -0
  225. package/public/webfonts/NotoSans/NotoSans-ExtraBold.woff2 +0 -0
  226. package/public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff +0 -0
  227. package/public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff2 +0 -0
  228. package/public/webfonts/NotoSans/NotoSans-ExtraLight.woff +0 -0
  229. package/public/webfonts/NotoSans/NotoSans-ExtraLight.woff2 +0 -0
  230. package/public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff +0 -0
  231. package/public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff2 +0 -0
  232. package/public/webfonts/NotoSans/NotoSans-Italic.woff +0 -0
  233. package/public/webfonts/NotoSans/NotoSans-Italic.woff2 +0 -0
  234. package/public/webfonts/NotoSans/NotoSans-Light.woff +0 -0
  235. package/public/webfonts/NotoSans/NotoSans-Light.woff2 +0 -0
  236. package/public/webfonts/NotoSans/NotoSans-LightItalic.woff +0 -0
  237. package/public/webfonts/NotoSans/NotoSans-LightItalic.woff2 +0 -0
  238. package/public/webfonts/NotoSans/NotoSans-Medium.woff +0 -0
  239. package/public/webfonts/NotoSans/NotoSans-Medium.woff2 +0 -0
  240. package/public/webfonts/NotoSans/NotoSans-MediumItalic.woff +0 -0
  241. package/public/webfonts/NotoSans/NotoSans-MediumItalic.woff2 +0 -0
  242. package/public/webfonts/NotoSans/NotoSans-Regular.woff +0 -0
  243. package/public/webfonts/NotoSans/NotoSans-Regular.woff2 +0 -0
  244. package/public/webfonts/NotoSans/NotoSans-SemiBold.woff +0 -0
  245. package/public/webfonts/NotoSans/NotoSans-SemiBold.woff2 +0 -0
  246. package/public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff +0 -0
  247. package/public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff2 +0 -0
  248. package/public/webfonts/NotoSans/NotoSans-Thin.woff +0 -0
  249. package/public/webfonts/NotoSans/NotoSans-Thin.woff2 +0 -0
  250. package/public/webfonts/NotoSans/NotoSans-ThinItalic.woff +0 -0
  251. package/public/webfonts/NotoSans/NotoSans-ThinItalic.woff2 +0 -0
  252. package/public/webfonts/NotoSans/stylesheet.css +162 -0
  253. package/public/webfonts/fa-solid-900.ttf +0 -0
  254. package/public/webfonts/fa-solid-900.woff2 +0 -0
  255. package/readme.md +187 -0
  256. package/server.js +2593 -0
  257. package/start.sh +24 -0
  258. package/tools/charaverter/main.mjs +110 -0
  259. package/tools/charaverter/package.json +10 -0
package/.dockerignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ npm-debug.log
3
+ readme*
4
+ Start.bat
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: "[BUG]"
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS/Device: [e.g. Windows 11]
28
+ - Environment: [cloud, local]
29
+ - Browser [e.g. chrome, safari]
30
+ - Generation API [e.g. KoboldAI, OpenAI]
31
+ - Branch [main, dev]
32
+ - Model [e.g. Pygmalion 6b, LLaMa 13b]
33
+
34
+ **Additional context**
35
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,32 @@
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
+
4
+ name: Node.js Package
5
+
6
+ on:
7
+ release:
8
+ types: [created]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v3
15
+ - uses: actions/setup-node@v3
16
+ with:
17
+ node-version: 16
18
+ - run: npm ci
19
+
20
+ publish-npm:
21
+ needs: build
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v3
25
+ - uses: actions/setup-node@v3
26
+ with:
27
+ node-version: 16
28
+ registry-url: https://registry.npmjs.org/
29
+ - run: npm ci
30
+ - run: npm publish
31
+ env:
32
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/Dockerfile ADDED
@@ -0,0 +1,49 @@
1
+ FROM node:19.1.0-alpine3.16
2
+
3
+ # Arguments
4
+ ARG APP_HOME=/home/node/app
5
+
6
+ # Ensure proper handling of kernel signals
7
+ RUN apk add tini
8
+ ENTRYPOINT [ "tini", "--" ]
9
+
10
+ # Create app directory
11
+ WORKDIR ${APP_HOME}
12
+
13
+ # Install app dependencies
14
+ COPY package*.json ./
15
+ RUN \
16
+ echo "*** Install npm packages ***" && \
17
+ npm install
18
+
19
+ # Bundle app source
20
+ COPY . ./
21
+
22
+ # Copy default chats, characters and user avatars to <folder>.default folder
23
+ RUN \
24
+ echo "*** Copy default chats, characters and user avatars to <folder>.default folder ***" && \
25
+ mv "./public/characters" "./public/characters.default" && \
26
+ mv "./public/chats" "./public/chats.default" && \
27
+ mv "./public/User Avatars" "./public/User Avatars.default" && \
28
+ mv "./public/settings.json" "./public/settings.json.default" && \
29
+
30
+ echo "*** Create symbolic links to config directory ***" && \
31
+ ln -s "${APP_HOME}/config/characters" "${APP_HOME}/public/characters" && \
32
+ ln -s "${APP_HOME}/config/chats" "${APP_HOME}/public/chats" && \
33
+ ln -s "${APP_HOME}/config/User Avatars" "${APP_HOME}/public/User Avatars" && \
34
+ ln -s "${APP_HOME}/config/settings.json" "${APP_HOME}/public/settings.json"
35
+
36
+ # Cleanup unnecessary files
37
+ RUN \
38
+ echo "*** Cleanup ***" && \
39
+ mv "./docker/docker-entrypoint.sh" "./" && \
40
+ rm -rf "./docker" && \
41
+ rm -rf "./.git" && \
42
+ echo "*** Make docker-entrypoint.sh executable ***" && \
43
+ chmod +x "./docker-entrypoint.sh" && \
44
+ echo "*** Convert line endings to Unix format ***" && \
45
+ dos2unix "./docker-entrypoint.sh"
46
+
47
+ EXPOSE 8000
48
+
49
+ CMD [ "./docker-entrypoint.sh" ]
package/Start.bat ADDED
@@ -0,0 +1,3 @@
1
+ call npm install
2
+ node server.js
3
+ pause
@@ -0,0 +1,339 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "attachments": {},
5
+ "cell_type": "markdown",
6
+ "metadata": {},
7
+ "source": [
8
+ "**Links**<br>\n",
9
+ "Cohee's TavernAI fork Github https://github.com/Cohee1207/SillyTavern<br>\n",
10
+ "Cohee's TavernAI Extras Github https://github.com/Cohee1207/TavernAI-extras/<br>\n",
11
+ "TavernAI Discord https://discord.gg/zmK2gmr45t<br>\n",
12
+ "Questions? Hit me up on Discord: Cohee#1207"
13
+ ]
14
+ },
15
+ {
16
+ "cell_type": "code",
17
+ "execution_count": null,
18
+ "metadata": {
19
+ "cellView": "form",
20
+ "id": "_1gpebrnlp5-"
21
+ },
22
+ "outputs": [],
23
+ "source": [
24
+ "#@title <b><-- Convert TavernAI characters to SillyTavern format</b>\n",
25
+ "\n",
26
+ "!mkdir /convert\n",
27
+ "%cd /convert\n",
28
+ "\n",
29
+ "import os\n",
30
+ "from google.colab import drive\n",
31
+ "\n",
32
+ "drive.mount(\"/convert/drive\")\n",
33
+ "\n",
34
+ "!git clone -b tools https://github.com/EnergoStalin/SillyTavern.git\n",
35
+ "%cd SillyTavern\n",
36
+ "\n",
37
+ "!curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n",
38
+ "!nvm install 19.1.0\n",
39
+ "!nvm use 19.1.0\n",
40
+ "\n",
41
+ "%cd tools/charaverter\n",
42
+ "\n",
43
+ "!npm i\n",
44
+ "\n",
45
+ "path = \"/convert/drive/MyDrive/TavernAI/characters\"\n",
46
+ "output = \"/convert/drive/MyDrive/SillyTavern/characters\"\n",
47
+ "if not os.path.exists(path):\n",
48
+ " path = output\n",
49
+ "\n",
50
+ "!mkdir -p $output\n",
51
+ "!node main.mjs $path $output\n",
52
+ "\n",
53
+ "drive.flush_and_unmount()\n",
54
+ "\n",
55
+ "%cd /\n",
56
+ "!rm -rf /convert"
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "code",
61
+ "execution_count": null,
62
+ "metadata": {
63
+ "id": "ewkXkyiFP2Hq"
64
+ },
65
+ "outputs": [],
66
+ "source": [
67
+ "#@title <-- Tap this if you play on Mobile { display-mode: \"form\" }\n",
68
+ "%%html\n",
69
+ "<b>Press play on the music player to keep the tab alive, then start KoboldAI below (Uses only 13MB of data)</b><br/>\n",
70
+ "<audio src=\"https://raw.githubusercontent.com/KoboldAI/KoboldAI-Client/main/colab/silence.m4a\" controls>"
71
+ ]
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "execution_count": null,
76
+ "metadata": {
77
+ "cellView": "form",
78
+ "id": "lVftocpwCoYw"
79
+ },
80
+ "outputs": [],
81
+ "source": [
82
+ "#@title <b><-- Select your model below and then click this to start KoboldAI</b>\n",
83
+ "\n",
84
+ "Model = \"Pygmalion 6B\" #@param [\"Nerys V2 6B\", \"Erebus 6B\", \"Skein 6B\", \"Janeway 6B\", \"Adventure 6B\", \"Pygmalion 6B\", \"Pygmalion 6B Dev\", \"Lit V2 6B\", \"Lit 6B\", \"Shinen 6B\", \"Nerys 2.7B\", \"AID 2.7B\", \"Erebus 2.7B\", \"Janeway 2.7B\", \"Picard 2.7B\", \"Horni LN 2.7B\", \"Horni 2.7B\", \"Shinen 2.7B\", \"OPT 2.7B\", \"Fairseq Dense 2.7B\", \"Neo 2.7B\", \"Pygway 6B\", \"Nerybus 6.7B\", \"Pygway v8p4\", \"PPO-Janeway 6B\", \"PPO Shygmalion 6B\", \"LLaMA 7B\", \"Janin-GPTJ\", \"Javelin-GPTJ\", \"Javelin-R\", \"Janin-R\", \"Javalion-R\", \"Javalion-GPTJ\", \"Javelion-6B\", \"GPT-J-Pyg-PPO-6B\", \"ppo_hh_pythia-6B\", \"ppo_hh_gpt-j\", \"GPT-J-Pyg_PPO-6B\", \"GPT-J-Pyg_PPO-6B-Dev-V8p4\", \"Dolly_GPT-J-6b\", \"Dolly_Pyg-6B\"] {allow-input: true}\n",
85
+ "Version = \"Official\" #@param [\"Official\", \"United\"] {allow-input: true}\n",
86
+ "Provider = \"Localtunnel\" #@param [\"Localtunnel\"]\n",
87
+ "ForceInitSteps = [] #@param {allow-input: true}\n",
88
+ "UseGoogleDrive = True #@param {type:\"boolean\"}\n",
89
+ "StartKoboldAI = True #@param {type:\"boolean\"}\n",
90
+ "ModelsFromDrive = False #@param {type:\"boolean\"}\n",
91
+ "UseExtrasExtensions = True #@param {type:\"boolean\"}\n",
92
+ "#@markdown Enables hosting of extensions backend for TavernAI Extras\n",
93
+ "extras_enable_captioning = True #@param {type:\"boolean\"}\n",
94
+ "#@markdown Loads the image captioning module\n",
95
+ "Captions_Model = \"Salesforce/blip-image-captioning-large\" #@param [ \"Salesforce/blip-image-captioning-large\", \"Salesforce/blip-image-captioning-base\" ]\n",
96
+ "#@markdown * Salesforce/blip-image-captioning-large - good base model\n",
97
+ "#@markdown * Salesforce/blip-image-captioning-base - slightly faster but less accurate\n",
98
+ "extras_enable_emotions = True #@param {type:\"boolean\"}\n",
99
+ "#@markdown Loads the sentiment classification model\n",
100
+ "Emotions_Model = \"bhadresh-savani/distilbert-base-uncased-emotion\" #@param [\"bhadresh-savani/distilbert-base-uncased-emotion\", \"joeddav/distilbert-base-uncased-go-emotions-student\"]\n",
101
+ "#@markdown * bhadresh-savani/distilbert-base-uncased-emotion = 6 supported emotions<br>\n",
102
+ "#@markdown * joeddav/distilbert-base-uncased-go-emotions-student = 28 supported emotions\n",
103
+ "extras_enable_memory = True #@param {type:\"boolean\"}\n",
104
+ "#@markdown Loads the story summarization module\n",
105
+ "Memory_Model = \"Qiliang/bart-large-cnn-samsum-ChatGPT_v3\" #@param [ \"Qiliang/bart-large-cnn-samsum-ChatGPT_v3\", \"Qiliang/bart-large-cnn-samsum-ElectrifAi_v10\", \"distilbart-xsum-12-3\" ]\n",
106
+ "#@markdown * Qiliang/bart-large-cnn-samsum-ChatGPT_v3 - summarization model optimized for chats\n",
107
+ "#@markdown * Qiliang/bart-large-cnn-samsum-ElectrifAi_v10 - nice results so far, but still being evaluated\n",
108
+ "#@markdown * distilbart-xsum-12-3 - faster, but pretty basic alternative\n",
109
+ "\n",
110
+ "\n",
111
+ "%cd /content\n",
112
+ "\n",
113
+ "!cat .ii\n",
114
+ "!nvidia-smi\n",
115
+ "\n",
116
+ "import os, subprocess, time, pathlib, json, base64, sys\n",
117
+ "\n",
118
+ "# ---\n",
119
+ "# Utils\n",
120
+ "class IncrementialInstall:\n",
121
+ " def __init__(self, root = \"/\", tasks = [], force = []):\n",
122
+ " self.tasks = tasks\n",
123
+ " self.path = os.path.join(root, \".ii\")\n",
124
+ " self.completed = list(filter(lambda x: not x in force, self.__completed()))\n",
125
+ "\n",
126
+ " def __completed(self):\n",
127
+ " try:\n",
128
+ " with open(self.path) as f:\n",
129
+ " return json.load(f)\n",
130
+ " except:\n",
131
+ " return []\n",
132
+ "\n",
133
+ " def addTask(self, name, func):\n",
134
+ " self.tasks.append({\"name\": name, \"func\": func})\n",
135
+ "\n",
136
+ " def run(self):\n",
137
+ " todo = list(filter(lambda x: not x[\"name\"] in self.completed, self.tasks))\n",
138
+ " try:\n",
139
+ " for task in todo:\n",
140
+ " task[\"func\"]()\n",
141
+ " self.completed.append(task[\"name\"])\n",
142
+ " finally:\n",
143
+ " with open(self.path, \"w\") as f:\n",
144
+ " json.dump(self.completed, f)\n",
145
+ "\n",
146
+ "def create_paths(paths):\n",
147
+ " for directory in paths:\n",
148
+ " if not os.path.exists(directory):\n",
149
+ " os.makedirs(directory)\n",
150
+ "\n",
151
+ "def link(srcDir, destDir, files):\n",
152
+ " '''\n",
153
+ " Link source to dest copying dest to source if not present first\n",
154
+ " '''\n",
155
+ " for file in files:\n",
156
+ " source = os.path.join(srcDir, file)\n",
157
+ " dest = os.path.join(destDir, file)\n",
158
+ " if not os.path.exists(source):\n",
159
+ " !cp -r \"$dest\" \"$source\"\n",
160
+ " !rm -rf \"$dest\"\n",
161
+ " !ln -fs \"$source\" \"$dest\"\n",
162
+ "\n",
163
+ "from google.colab import drive\n",
164
+ "if UseGoogleDrive:\n",
165
+ " drive.mount(\"/content/drive/\")\n",
166
+ "else:\n",
167
+ " create_paths([\n",
168
+ " \"/content/drive/MyDrive\"\n",
169
+ " ])\n",
170
+ "\n",
171
+ "ii = IncrementialInstall(force=ForceInitSteps)\n",
172
+ "\n",
173
+ "# ---\n",
174
+ "# SillyTavern py modules\n",
175
+ "def cloneTavern():\n",
176
+ " %cd /\n",
177
+ " !git clone https://github.com/Cohee1207/SillyTavern\n",
178
+ " %cd -\n",
179
+ " !cp /SillyTavern/colab/*.py ./\n",
180
+ "ii.addTask(\"Clone SillyTavern\", cloneTavern)\n",
181
+ "ii.run()\n",
182
+ "\n",
183
+ "from models import GetModels, ModelData\n",
184
+ "model = GetModels(Version).get(Model, ModelData(Model, Version))\n",
185
+ "\n",
186
+ "# ---\n",
187
+ "# KoboldAI\n",
188
+ "if StartKoboldAI:\n",
189
+ " def downloadKobold():\n",
190
+ " !wget https://koboldai.org/ckds && chmod +x ckds\n",
191
+ " def initKobold():\n",
192
+ " !./ckds --init only\n",
193
+ "\n",
194
+ " ii.addTask(\"Download KoboldAI\", downloadKobold)\n",
195
+ " ii.addTask(\"Init KoboldAI\", initKobold)\n",
196
+ " \n",
197
+ " ii.run()\n",
198
+ "\n",
199
+ "kargs = [\"/content/ckds\"]\n",
200
+ "if not ModelsFromDrive:\n",
201
+ " kargs += [\"-x\", \"colab\", \"-l\", \"colab\"]\n",
202
+ "if Provider == \"Localtunnel\":\n",
203
+ " kargs += [\"--localtunnel\", \"yes\"]\n",
204
+ "\n",
205
+ "kargs += model.args()\n",
206
+ "\n",
207
+ "url = \"\"\n",
208
+ "print(kargs)\n",
209
+ "\n",
210
+ "if StartKoboldAI:\n",
211
+ " p = subprocess.Popen(kargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
212
+ "\n",
213
+ " prefix = \"KoboldAI has finished loading and is available at the following link\"\n",
214
+ " urlprefix = f\"{prefix}: \"\n",
215
+ " ui1prefix = f\"{prefix} for UI 1: \"\n",
216
+ " while True:\n",
217
+ " line = p.stdout.readline().decode().strip()\n",
218
+ " print(line)\n",
219
+ " if urlprefix in line:\n",
220
+ " url = line.split(urlprefix)[1]\n",
221
+ " break\n",
222
+ " elif ui1prefix in line:\n",
223
+ " url = line.split(ui1prefix)[1]\n",
224
+ " break\n",
225
+ " elif not line:\n",
226
+ " break\n",
227
+ " if \"INIT\" in line and \"Transformers\" in line:\n",
228
+ " print(\"Model loading... (It will take 2 - 5 minutes)\")\n",
229
+ "\n",
230
+ "print(url)\n",
231
+ "\n",
232
+ "\n",
233
+ "# ---\n",
234
+ "# nodejs\n",
235
+ "%cd /\n",
236
+ "def installNode():\n",
237
+ " !npm install -g n\n",
238
+ " !n 19\n",
239
+ " !node --version\n",
240
+ "ii.addTask(\"Install node\", installNode)\n",
241
+ "\n",
242
+ "\n",
243
+ "# ---\n",
244
+ "# TavernAI extras\n",
245
+ "import globals\n",
246
+ "globals.extras_url = '(disabled)'\n",
247
+ "globals.params = []\n",
248
+ "globals.params.append('--cpu')\n",
249
+ "ExtrasModules = []\n",
250
+ "\n",
251
+ "if (extras_enable_captioning):\n",
252
+ " ExtrasModules.append('caption')\n",
253
+ "if (extras_enable_memory):\n",
254
+ " ExtrasModules.append('summarize')\n",
255
+ "if (extras_enable_emotions):\n",
256
+ " ExtrasModules.append('classify')\n",
257
+ "\n",
258
+ "globals.params.append(f'--classification-model={Emotions_Model}')\n",
259
+ "globals.params.append(f'--summarization-model={Memory_Model}')\n",
260
+ "globals.params.append(f'--captioning-model={Captions_Model}')\n",
261
+ "globals.params.append(f'--enable-modules={\",\".join(ExtrasModules)}')\n",
262
+ "\n",
263
+ "\n",
264
+ "if UseExtrasExtensions:\n",
265
+ " def cloneExtras():\n",
266
+ " %cd /\n",
267
+ " !git clone https://github.com/Cohee1207/TavernAI-extras\n",
268
+ " ii.addTask('clone extras', cloneExtras)\n",
269
+ "\n",
270
+ " def installRequirements():\n",
271
+ " %cd /TavernAI-extras\n",
272
+ " !npm install -g localtunnel\n",
273
+ " !pip install -r requirements.txt\n",
274
+ " !pip install tensorflow==2.11\n",
275
+ " ii.addTask('install requirements', installRequirements)\n",
276
+ "\n",
277
+ " from extras_server import runServer, extractUrl\n",
278
+ " ii.addTask('run server', runServer)\n",
279
+ " ii.addTask('extract extras URL', extractUrl)\n",
280
+ "\n",
281
+ "%cd /SillyTavern\n",
282
+ "\n",
283
+ "if UseGoogleDrive:\n",
284
+ " %env googledrive=2\n",
285
+ "\n",
286
+ " def setupTavernPaths():\n",
287
+ " %cd /SillyTavern\n",
288
+ " tdrive = \"/content/drive/MyDrive/SillyTavern\"\n",
289
+ " create_paths([\n",
290
+ " tdrive,\n",
291
+ " os.path.join(\"public\", \"groups\"),\n",
292
+ " os.path.join(\"public\", \"group chats\")\n",
293
+ " ])\n",
294
+ " link(tdrive, \"public\", [\n",
295
+ " \"settings.json\",\n",
296
+ " \"backgrounds\",\n",
297
+ " \"characters\",\n",
298
+ " \"chats\",\n",
299
+ " \"User Avatars\",\n",
300
+ " \"worlds\",\n",
301
+ " \"group chats\",\n",
302
+ " \"groups\",\n",
303
+ " ])\n",
304
+ " ii.addTask(\"Setup Tavern Paths\", setupTavernPaths)\n",
305
+ "\n",
306
+ "def installTavernDependencies():\n",
307
+ " %cd /SillyTavern\n",
308
+ " !npm install\n",
309
+ " !npm install -g localtunnel\n",
310
+ "ii.addTask(\"Install Tavern Dependencies\", installTavernDependencies)\n",
311
+ "ii.run()\n",
312
+ "\n",
313
+ "%env colaburl=$url\n",
314
+ "%env SILLY_TAVERN_PORT=5001\n",
315
+ "print(\"KoboldAI LINK:\", url, '###Extensions API LINK###', globals.extras_url, \"###SillyTavern LINK###\", sep=\"\\n\")\n",
316
+ "p = subprocess.Popen([\"lt\", \"--port\", \"5001\"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
317
+ "print(p.stdout.readline().decode().strip())\n",
318
+ "!node server.js"
319
+ ]
320
+ }
321
+ ],
322
+ "metadata": {
323
+ "accelerator": "GPU",
324
+ "colab": {
325
+ "private_outputs": true,
326
+ "provenance": []
327
+ },
328
+ "gpuClass": "standard",
329
+ "kernelspec": {
330
+ "display_name": "Python 3",
331
+ "name": "python3"
332
+ },
333
+ "language_info": {
334
+ "name": "python"
335
+ }
336
+ },
337
+ "nbformat": 4,
338
+ "nbformat_minor": 0
339
+ }
@@ -0,0 +1,40 @@
1
+ import os
2
+ import time
3
+ import subprocess
4
+ import globals
5
+
6
+ def runServer():
7
+ cmd = f"python server.py {' '.join(globals.params)}"
8
+ print(cmd)
9
+ extras_process = subprocess.Popen(
10
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd='/TavernAI-extras', shell=True)
11
+ print('processId:', extras_process.pid)
12
+ while True:
13
+ line = extras_process.stdout.readline().decode().strip()
14
+ if "Running on " in line:
15
+ break
16
+ if not line:
17
+ print('breaking on line')
18
+ break
19
+ print(line)
20
+
21
+
22
+ def extractUrl():
23
+ subprocess.call(
24
+ 'nohup lt --port 5100 > ./extras.out 2> ./extras.err &', shell=True)
25
+ print('Waiting for lt init...')
26
+ time.sleep(5)
27
+ while True:
28
+ if (os.path.getsize('./extras.out') > 0):
29
+ with open('./extras.out', 'r') as f:
30
+ lines = f.readlines()
31
+ for x in range(len(lines)):
32
+ if ('your url is: ' in lines[x]):
33
+ print('TavernAI Extensions URL:')
34
+ globals.extras_url = lines[x].split('your url is: ')[1]
35
+ print(globals.extras_url)
36
+ break
37
+ if (os.path.getsize('./extras.err') > 0):
38
+ with open('./extras.err', 'r') as f:
39
+ print(f.readlines())
40
+ break
@@ -0,0 +1,2 @@
1
+ extras_url = '(disabled)'
2
+ params = []
@@ -0,0 +1,77 @@
1
+ class ModelData:
2
+ def __init__(self, name, version = "", revision="", path="", download=""):
3
+ self.name = name
4
+ self.version = version
5
+ self.revision = revision
6
+ self.path = path
7
+ self.download = download
8
+
9
+ def __str__(self):
10
+ return self.args().__str__()
11
+
12
+ def args(self):
13
+ args = ["-m", self.name]
14
+ if (self.version):
15
+ args += ["-g", self.version]
16
+ if (self.revision):
17
+ args += ["-r", self.revision]
18
+ return args
19
+
20
+
21
+ class ModelFactory:
22
+ def __init__(self, **kwargs):
23
+ self.kwargs = kwargs
24
+
25
+ def NewModelData(self, name, **kwargs):
26
+ cpy = self.kwargs.copy()
27
+ cpy.update(kwargs)
28
+ return ModelData(name = name, **cpy)
29
+
30
+
31
+ def GetModels(Version):
32
+ mf = ModelFactory(version=Version)
33
+ return {
34
+ "Nerys V2 6B": mf.NewModelData("KoboldAI/OPT-6B-nerys-v2"),
35
+ "Erebus 6B": mf.NewModelData("KoboldAI/OPT-6.7B-Erebus"),
36
+ "Skein 6B": mf.NewModelData("KoboldAI/GPT-J-6B-Skein"),
37
+ "Janeway 6B": mf.NewModelData("KoboldAI/GPT-J-6B-Janeway"),
38
+ "Adventure 6B": mf.NewModelData("KoboldAI/GPT-J-6B-Adventure"),
39
+ "Pygmalion 6B": mf.NewModelData("PygmalionAI/pygmalion-6b"),
40
+ "Pygmalion 6B Dev": mf.NewModelData("PygmalionAI/pygmalion-6b", revision="dev"),
41
+ "Lit V2 6B": mf.NewModelData("hakurei/litv2-6B-rev3"),
42
+ "Lit 6B": mf.NewModelData("hakurei/lit-6B"),
43
+ "Shinen 6B": mf.NewModelData("KoboldAI/GPT-J-6B-Shinen"),
44
+ "Nerys 2.7B": mf.NewModelData("KoboldAI/fairseq-dense-2.7B-Nerys"),
45
+ "Erebus 2.7B": mf.NewModelData("KoboldAI/OPT-2.7B-Erebus"),
46
+ "Janeway 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-Janeway"),
47
+ "Picard 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-Picard"),
48
+ "AID 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-AID"),
49
+ "Horni LN 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-Horni-LN"),
50
+ "Horni 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-Horni"),
51
+ "Shinen 2.7B": mf.NewModelData("KoboldAI/GPT-Neo-2.7B-Shinen"),
52
+ "Fairseq Dense 2.7B": mf.NewModelData("KoboldAI/fairseq-dense-2.7B"),
53
+ "OPT 2.7B": mf.NewModelData("facebook/opt-2.7b"),
54
+ "Neo 2.7B": mf.NewModelData("EleutherAI/gpt-neo-2.7B"),
55
+ "Pygway 6B": mf.NewModelData("TehVenom/PPO_Pygway-6b"),
56
+ "Nerybus 6.7B": mf.NewModelData("KoboldAI/OPT-6.7B-Nerybus-Mix"),
57
+ "Pygway v8p4": mf.NewModelData("TehVenom/PPO_Pygway-V8p4_Dev-6b"),
58
+ "PPO-Janeway 6B": mf.NewModelData("TehVenom/PPO_Janeway-6b"),
59
+ "PPO Shygmalion 6B": mf.NewModelData("TehVenom/PPO_Shygmalion-6b"),
60
+ "LLaMA 7B": mf.NewModelData("decapoda-research/llama-7b-hf"),
61
+ "Janin-GPTJ": mf.NewModelData("digitous/Janin-GPTJ"),
62
+ "Javelin-GPTJ": mf.NewModelData("digitous/Javelin-GPTJ"),
63
+ "Javelin-R": mf.NewModelData("digitous/Javelin-R"),
64
+ "Janin-R": mf.NewModelData("digitous/Janin-R"),
65
+ "Javalion-R": mf.NewModelData("digitous/Javalion-R"),
66
+ "Javalion-GPTJ": mf.NewModelData("digitous/Javalion-GPTJ"),
67
+ "Javelion-6B": mf.NewModelData("Cohee/Javelion-6b"),
68
+ "GPT-J-Pyg-PPO-6B": mf.NewModelData("TehVenom/GPT-J-Pyg_PPO-6B"),
69
+ "ppo_hh_pythia-6B": mf.NewModelData("reciprocate/ppo_hh_pythia-6B"),
70
+ "ppo_hh_gpt-j": mf.NewModelData("reciprocate/ppo_hh_gpt-j"),
71
+ "Alpaca-7B": mf.NewModelData("chainyo/alpaca-lora-7b"),
72
+ "LLaMA 4-bit": mf.NewModelData("decapoda-research/llama-13b-hf-int4"),
73
+ "GPT-J-Pyg_PPO-6B": mf.NewModelData("TehVenom/GPT-J-Pyg_PPO-6B"),
74
+ "GPT-J-Pyg_PPO-6B-Dev-V8p4": mf.NewModelData("TehVenom/GPT-J-Pyg_PPO-6B-Dev-V8p4"),
75
+ "Dolly_GPT-J-6b": mf.NewModelData("TehVenom/Dolly_GPT-J-6b"),
76
+ "Dolly_Pyg-6B": mf.NewModelData("TehVenom/AvgMerge_Dolly-Pygmalion-6b")
77
+ }
@@ -0,0 +1,12 @@
1
+ version: "3"
2
+ services:
3
+ tavernai:
4
+ build: ..
5
+ container_name: tavernai
6
+ hostname: tavernai
7
+ image: tavernai/tavernai:latest
8
+ ports:
9
+ - "8000:8000"
10
+ volumes:
11
+ - "./config:/home/node/app/config"
12
+ restart: unless-stopped
@@ -0,0 +1,28 @@
1
+ #!/bin/sh
2
+
3
+ # Check if the "characters" directory is empty
4
+ if [ -z "$(ls -A /home/node/app/config/characters)" ]; then
5
+ echo "Characters directory is empty. Copying default characters."
6
+ mv /home/node/app/public/characters.default /home/node/app/config/characters
7
+ fi
8
+
9
+ # Check if the "chats" directory is empty
10
+ if [ -z "$(ls -A /home/node/app/config/chats)" ]; then
11
+ echo "Chats directory is empty. Copying default chats."
12
+ mv /home/node/app/public/chats.default /home/node/app/config/chats/
13
+ fi
14
+
15
+ # Check if the "User Avatars" directory is empty
16
+ if [ -z "$(ls -A '/home/node/app/config/User Avatars')" ]; then
17
+ echo "User Avatars directory is empty. Copying default user avatars."
18
+ mv /home/node/app/public/User\ Avatars.default /home/node/app/config/User\ Avatars/
19
+ fi
20
+
21
+ # Check if the "settings.json" file is not empty
22
+ if [ ! -s "/home/node/app/config/settings.json" ]; then
23
+ echo "Settings file does not exist. Copying default settings."
24
+ mv /home/node/app/public/settings.json.default /home/node/app/config/settings.json
25
+ fi
26
+
27
+ # Start the server
28
+ exec node /home/node/app/server.js