Compare commits

...

321 Commits
1.3.0 ... 1.4.0

Author SHA1 Message Date
RossAscends
be307b1107 fixed typo in auto-save message edit checkbox 2023-04-21 05:16:15 +09:00
SillyLossy
3e95989fad Merge branch 'main' into dev 2023-04-20 23:08:25 +03:00
RossAscends
f5582a62bc remove transition swapping on UI customization 2023-04-21 04:33:46 +09:00
RossAscends
cb87ba2da1 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-21 04:26:06 +09:00
RossAscends
38e6b0498d - correct centering for waifumode PC
- remove transition from #chat
- better swipe animations
- standardized naming for animation variables
2023-04-21 04:26:03 +09:00
SillyLossy
35f669d7e9 Fix hint on expressions 2023-04-20 21:42:22 +03:00
SillyLossy
9360e65606 Reload expressions list on connecting to API 2023-04-20 21:16:58 +03:00
SillyLossy
330a8cd1d6 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-20 20:27:48 +03:00
SillyLossy
59284a5436 New validation logic of expression images 2023-04-20 20:26:32 +03:00
RossAscends
e503d340b9 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-21 02:14:18 +09:00
RossAscends
03b3fc9fc1 - added edit message auto saving
- toggle in PowerUser settings
- removed consolelog spam from RA-mods and expressions
2023-04-21 02:14:16 +09:00
Cohee
e12162f58d Update faq.md 2023-04-20 19:19:08 +03:00
Cohee
183a4eadf3 Update readme.md 2023-04-20 19:17:50 +03:00
Cohee
ec8b39bf44 Update readme.md 2023-04-20 19:16:46 +03:00
Cohee
fd33ff21be Merge pull request #117 from paniphons/main
Create FAQ to avoid bloating README
2023-04-20 19:16:24 +03:00
Paniphon
620e965533 Move prompt editing info from README to FAQ 2023-04-20 22:41:08 +07:00
Paniphon
cbd84dcf0a Update readme.md 2023-04-20 22:36:27 +07:00
Paniphon
f5ec5a9788 Update README to link FAQ 2023-04-20 22:33:26 +07:00
Paniphon
795f47a301 Create faq.md 2023-04-20 22:24:40 +07:00
SillyLossy
1a3616ae47 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-20 18:18:10 +03:00
SillyLossy
f28850220a Proper regeneration for groups 2023-04-20 18:18:07 +03:00
RossAscends
d452467818 - escape from edit message now focuses on send_textarea
- allow swipes to happen when send_textarea is focused but empty
2023-04-20 23:58:12 +09:00
RossAscends
7fb3d1f578 fixed listener order for proper key detection 2023-04-20 23:39:02 +09:00
RossAscends
516a61a5ee added proper focus filter to uparrow hotkeys 2023-04-20 23:36:48 +09:00
RossAscends
9ee9da6705 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-20 23:23:56 +09:00
RossAscends
6d77dfbf48 uparrow = edit last message in chat
ctrl+uparrow = edit last user message

removed ctrl+uparrow for autoconnect hotkey
2023-04-20 23:23:46 +09:00
SillyLossy
f591961dd7 Merge branch 'main' into dev 2023-04-20 17:11:21 +03:00
SillyLossy
1718452efb Fix code block parsing #116 2023-04-20 17:10:57 +03:00
RossAscends
60bfcc1a6b removed log spam from uparrow 2023-04-20 23:04:08 +09:00
RossAscends
acea6fab67 added UpArrow to quick edit last user mes 2023-04-20 22:59:13 +09:00
Cohee
b30df36b8c Merge pull request #113 from sanskar-mk2/whitelist-txt-feature
optional whitelist.txt
2023-04-20 16:12:09 +03:00
Cohee
325f4170cb Fix server crash if whitelist.txt is missing 2023-04-20 16:10:05 +03:00
Sanskar Tiwari
50792fdef5 optional whitelist.txt 2023-04-20 18:11:20 +05:30
Cohee
db39807dd6 Merge pull request #112 from sanskar-mk2/bg-filter-feature
add bg filter feature on the frontend
2023-04-20 14:25:10 +03:00
SillyLossy
ae0a83161d Remove the memory attached to right swipe 2023-04-20 14:24:06 +03:00
Sanskar Tiwari
ce6e367a95 add bg filter feature on the frontend 2023-04-20 16:37:58 +05:30
SillyLossy
711e5fefb0 Fix impersonation in empty chat 2023-04-20 13:40:43 +03:00
SillyLossy
b2366993a8 Update readme 2023-04-20 13:06:32 +03:00
SillyLossy
be51df6d02 Merge branch 'dev' 2023-04-20 13:04:04 +03:00
RossAscends
46e0adf7c1 normal mobile waifu back to cover. 2023-04-20 05:36:08 +09:00
RossAscends
3d5b6d81d9 landscape mobile waifu to 'contain' 2023-04-20 05:34:35 +09:00
RossAscends
4b54193d3f - smarter expression display
- only show after expression is set.
2023-04-20 05:02:02 +09:00
RossAscends
a590b44336 caveman fix for activechar/group not focusing correct in rightnav 2023-04-20 04:45:11 +09:00
Cohee
6d334fe8f5 Update readme.md 2023-04-19 22:35:26 +03:00
SillyLossy
52b07e1b02 Fix colab for GDrive users 2023-04-19 18:58:00 +03:00
RossAscends
dba41235e8 fontawesome CSS comments at bottom to help derpy localtunnel? 2023-04-20 00:00:55 +09:00
SillyLossy
7ca3adad81 Remove comments from css (colab) 2023-04-19 17:57:24 +03:00
RossAscends
4df04f3b3f added <base> tag to HTML
added observer to wait for expressions before enabling drag
2023-04-19 22:58:59 +09:00
RossAscends
37b7dbde0e added base href 2023-04-19 22:25:30 +09:00
RossAscends
b55a9f4e13 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 22:00:41 +09:00
RossAscends
9a911ae150 adding TTF 2023-04-19 22:00:39 +09:00
SillyLossy
270347276f Merge branch 'dev' 2023-04-19 15:53:08 +03:00
SillyLossy
c8f4f2f126 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 15:51:03 +03:00
RossAscends
021dcc367d Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 21:50:44 +09:00
RossAscends
9868f8c8b0 fixing fonts 2023-04-19 21:50:42 +09:00
SillyLossy
3963737bd5 Fix icon webfonts 2023-04-19 15:50:40 +03:00
SillyLossy
5c08f8ecf2 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 15:42:20 +03:00
SillyLossy
32bd5ced12 Fix impersonate and swipes in group chats with streaming and not. 2023-04-19 15:42:15 +03:00
RossAscends
65dc4d127a added limiter to light themes only to style.css 2023-04-19 21:26:26 +09:00
RossAscends
6bc63bdc6a added darkreader lock to HTML. 2023-04-19 21:25:45 +09:00
RossAscends
2addcb6b8c strategies to avoid forced dark mode 2023-04-19 20:17:49 +09:00
SillyLossy
7ef2a79729 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 13:59:44 +03:00
SillyLossy
6b65af891e Fix stopping strings for ooba and kobold 2023-04-19 13:59:40 +03:00
RossAscends
f1f80812fb normal mode expression-holder no longer in front of sheld 2023-04-19 19:38:06 +09:00
Cohee
86ad656bc0 Merge pull request #102 from gidzzz/main
Allow graceful shutdown in Docker
2023-04-19 10:57:44 +03:00
Grzegorz Gidel
70b8599e03 Allow graceful shutdown in Docker 2023-04-19 04:47:54 +02:00
Cohee
f38ca26c68 Merge pull request #101 from gidzzz/main 2023-04-19 02:04:39 +03:00
Grzegorz Gidel
f76e53a52c Fix reversed examples formatting condition when pinning enabled 2023-04-19 00:50:04 +02:00
Cohee
2e5ce1485b Update readme.md 2023-04-19 00:52:48 +03:00
SillyLossy
69f36efd9a Merge branch 'dev' 2023-04-19 00:44:33 +03:00
SillyLossy
b9ce9024a0 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 23:48:15 +03:00
SillyLossy
a6553d8cf6 Minor margin changes 2023-04-18 23:48:13 +03:00
RossAscends
7038ecb9d9 another L/R nav panel fix for PC 2023-04-19 05:43:43 +09:00
RossAscends
8ccf669815 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 05:16:05 +09:00
RossAscends
36bde61001 fixed left/right panels scrolling and heights 2023-04-19 05:16:03 +09:00
SillyLossy
b4456bce4d More space for example dialogues 2023-04-18 23:08:02 +03:00
Cohee
dbd2cc92ee Merge pull request #99 from artisticMink/feature/chat-import-multiple-characterai
Import all chats from a characterAI chat history dump
2023-04-18 23:07:18 +03:00
Cohee
9bd1c018c8 Merge pull request #100 from AlpinDale/patch-1
Create start.sh
2023-04-18 23:06:46 +03:00
AlpinDale
efa5418f0b Create start.sh 2023-04-19 00:00:57 +04:30
RossAscends
a07d1ac73a small update to universal shadows 2023-04-19 04:07:06 +09:00
maver
89aa307f16 Import all chats from a characterAI chat history dump
Instead of only first chat found.
2023-04-18 20:10:28 +02:00
RossAscends
d54c9b01ef Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 03:03:50 +09:00
RossAscends
8062e87ba6 - mobile waifu fixes for android and iOS 2023-04-19 03:03:48 +09:00
SillyLossy
2a38977964 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 21:00:29 +03:00
SillyLossy
1f154a3903 Local install of Noto Sans webfont 2023-04-18 21:00:26 +03:00
RossAscends
ae95d0175d mobile styles and iOS waifu fixing 2023-04-19 02:03:46 +09:00
RossAscends
0eebc047b8 remove left margin from mobile waifu 2023-04-19 00:55:30 +09:00
RossAscends
4e4283dd6c - reverted PC waifu mode
- added mobile waifu mode to mobile only styling
2023-04-19 00:54:01 +09:00
RossAscends
936af83ca0 larger mobile waifus 2023-04-19 00:37:28 +09:00
RossAscends
74f00fe4eb no movingUI console spam. 2023-04-19 00:20:40 +09:00
RossAscends
202ee8b5aa better collision detection order 2023-04-19 00:18:53 +09:00
RossAscends
81a2a685b9 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-19 00:07:55 +09:00
RossAscends
8ac2bfef96 - 99% percect topbar collision detection for movingUI
- allow waifu mode expression sprites to reset properly on UI Reset
2023-04-19 00:07:53 +09:00
Cohee
983c123355 Merge pull request #97 from AlpinDale/dev
Added a linux start script
2023-04-18 17:50:27 +03:00
AlpinDale
70d1e88a02 Added a linux start script 2023-04-18 19:17:01 +04:30
RossAscends
571c6cb606 added reset button for movingUI
- tweaked token warning styles to be utility classes
2023-04-18 21:48:33 +09:00
RossAscends
d186e7372e added toggle for movingUI 2023-04-18 21:21:39 +09:00
RossAscends
180b06f4e0 missing expression images are now hidden 2023-04-18 20:54:41 +09:00
RossAscends
77f1d59b12 fixed waifu mode expressions resizing 2023-04-18 20:50:50 +09:00
RossAscends
5263383e80 more max-lengths added 2023-04-18 20:27:50 +09:00
RossAscends
b84d344ca9 max-length for user name input box 2023-04-18 20:25:25 +09:00
RossAscends
de49ad11e6 added maxlengths to index.html text inputs 2023-04-18 20:24:11 +09:00
RossAscends
ffd1e8baa4 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 20:12:48 +09:00
RossAscends
846c9d0a12 - min-sizes for input bar and expressions
- console log spam trying to debug expression image loading
2023-04-18 20:12:45 +09:00
SillyLossy
56bb604b7e Add more metadata to ext. manifests 2023-04-18 12:58:24 +03:00
SillyLossy
795e59aba0 Remove hard coded list in extensions 2023-04-18 12:56:20 +03:00
RossAscends
3fe99b5f8d Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 18:35:38 +09:00
RossAscends
ac7ee2f11f character expressions are now draggable 2023-04-18 18:35:36 +09:00
SillyLossy
fc8e0c4918 Fix ooba/kobold compat mode #96 2023-04-18 12:33:56 +03:00
RossAscends
473c7a614d fix waifumode sheld being unmovable 2023-04-18 17:13:44 +09:00
RossAscends
fc4e646c40 changed HTML title 2023-04-18 16:56:03 +09:00
RossAscends
be50a45742 removed unused files from
- images
- webfonts
- css
2023-04-18 16:35:22 +09:00
RossAscends
a830df35be fixed sheld size in waifu mode on mobile 2023-04-18 15:59:37 +09:00
RossAscends
a499cc5123 another update to token explainer help page 2023-04-18 09:40:11 +09:00
RossAscends
c0dafe01f2 updated token explainer help page 2023-04-18 09:35:10 +09:00
RossAscends
f8c4052412 - updated display of char token warning
- added help page explaining character tokens and context limits
2023-04-18 09:16:13 +09:00
RossAscends
1ae8827fa9 tweaked left/right panel and lock icon header stylings 2023-04-18 08:05:56 +09:00
RossAscends
b13b1dc835 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 07:44:00 +09:00
RossAscends
6afb03e017 - right nav now draggable
- added mainColor to all buttons and panel texts/headers
- adjusted button hover stylings
2023-04-18 07:43:56 +09:00
SillyLossy
de0468921f Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 00:26:53 +03:00
SillyLossy
61d62312a0 Thumbnail images saved from caption 2023-04-18 00:26:52 +03:00
RossAscends
3d1e0f3aa1 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 04:34:50 +09:00
RossAscends
7c5f6be823 - smoother drag bounces
- z-index removed for drawer icons
- draggables can go to Y=0
2023-04-18 04:34:48 +09:00
SillyLossy
a71190aa5f Fix GIF background server crash 2023-04-17 22:33:30 +03:00
SillyLossy
9f8aa78d8b Fix custom bg opacity animation 2023-04-17 22:30:02 +03:00
RossAscends
df8fabed28 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 04:04:29 +09:00
RossAscends
d9bbefb01e fixed collision detection for dragged elements 2023-04-18 04:04:27 +09:00
SillyLossy
78bf50b468 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-17 21:32:39 +03:00
SillyLossy
b78d5be176 Add character backgrounds plugin #82 2023-04-17 21:32:36 +03:00
RossAscends
c38a955f96 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-18 02:33:04 +09:00
RossAscends
d7dceca390 - left panel is now draggable and resizeable 2023-04-18 02:33:02 +09:00
SillyLossy
48cbf6f54b Better handling of message images 2023-04-17 17:48:40 +03:00
SillyLossy
9aebabf698 Parse images sent by oobabooga plugin 2023-04-17 17:19:44 +03:00
SillyLossy
281844643f Log OAI response to console 2023-04-17 14:31:41 +03:00
SillyLossy
dd1931eaed Fix ooba streaming server crash 2023-04-17 14:24:05 +03:00
SillyLossy
c5a3ec7d6e Determine if stop_sequence could be used. Closes #93 2023-04-17 13:50:41 +03:00
RossAscends
daaf460e17 fix sheld in waifu mode 2023-04-17 16:55:40 +09:00
RossAscends
3cfe6b6ec8 fixed tiny sheld width 2023-04-17 16:48:48 +09:00
RossAscends
e2f4002732 - overflow handling for draggable sheld 2023-04-17 16:33:21 +09:00
RossAscends
eb9fddf7db Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-17 14:44:30 +09:00
RossAscends
9fb7dc5e42 WIP: element dragging & resizing
- currently enabled on #sheld when window is over 1000px wide.
- click top right gripper dots to drag sheld around
- resize with lower right size dragger.
- snaps to static view and hides grabbers when windows under 1000px
- position not remembered across sessions..yet
- updated styles on dice, options, and send_but
2023-04-17 14:44:27 +09:00
SillyLossy
3af6bcafa7 Default expressions for groups 2023-04-17 00:20:35 +03:00
SillyLossy
339f212981 Fixes for expressions plugin 2023-04-17 00:13:31 +03:00
SillyLossy
0ac5cc70ca Trigger immediate check for pygmalion formatting 2023-04-16 23:10:27 +03:00
SillyLossy
9616b26402 Added stop sequences for Kobold.cpp 2023-04-16 23:02:23 +03:00
SillyLossy
247d65f30b Fix oobabooga stopping strings 2023-04-16 22:08:26 +03:00
SillyLossy
0358daa9b1 Dim down the red color of token counter #90 2023-04-16 20:50:59 +03:00
SillyLossy
69beea39ff Expand note for advanced formatting 2023-04-16 20:44:07 +03:00
SillyLossy
5b597511ac Closes #89 2023-04-16 20:21:45 +03:00
SillyLossy
e337e3be9b Better parsing of textgen streaming 2023-04-16 20:11:35 +03:00
SillyLossy
8ee8f373ec Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-16 17:26:10 +03:00
SillyLossy
269bd69d7c More formatting options 2023-04-16 17:26:08 +03:00
RossAscends
20df42bed3 remove some console log spam. 2023-04-16 22:45:23 +09:00
SillyLossy
b2d8510b87 Add prompts list to readme 2023-04-16 15:53:26 +03:00
SillyLossy
488268f9ba Fix startup on safari / ios 2023-04-16 14:08:00 +03:00
SillyLossy
b8b8e7270f Fixed pygma formatting on reload page 2023-04-16 13:18:57 +03:00
SillyLossy
6985521b81 Fix streaming server crash 2023-04-16 12:48:13 +03:00
SillyLossy
fcc839b56c Fix Poe. 2023-04-16 12:35:50 +03:00
RossAscends
4f64f2bafe css cleanup 2023-04-16 18:20:41 +09:00
RossAscends
d246e51a19 char export format popup relocated to display blur properly 2023-04-16 11:55:56 +09:00
RossAscends
1932d17666 - fixed options menu blur
- added list-group blur and styling
- stronger blur on large popups
- fullscreen shadows darker
2023-04-16 11:36:49 +09:00
SillyLossy
62929301fa Angry swiping fix 2023-04-16 02:39:48 +03:00
SillyLossy
9db4766bfa Fix color picker overflowing the page on top 2023-04-16 02:16:22 +03:00
SillyLossy
a788acdf4b Fix poe 2023-04-16 01:33:22 +03:00
SillyLossy
9378c8811e Adjust styles of OAI prompt boxes. Add more expressions to offline mode. 2023-04-16 00:35:50 +03:00
SillyLossy
3ae0ae72cf Status interval checking timing slowed down 2023-04-15 23:20:13 +03:00
SillyLossy
a563a45bf0 Send example dialogues as system messages with names 2023-04-15 20:05:58 +03:00
SillyLossy
e3b9c24d8c Save OAI preset based on current settings 2023-04-15 19:47:41 +03:00
SillyLossy
5418cacee2 Multi-character import 2023-04-15 19:43:41 +03:00
SillyLossy
06e941fd93 More multigen settings 2023-04-15 19:15:25 +03:00
SillyLossy
7c9e424863 Add pygmalion formatting dropdown 2023-04-15 17:30:11 +03:00
SillyLossy
e419988f26 Restorable poe prompts 2023-04-15 14:12:40 +03:00
SillyLossy
648f2e9ceb Bug fixes and optimizations 2023-04-15 13:45:25 +03:00
RossAscends
fdce599762 improved user-Settings adaptable display 2023-04-15 16:00:37 +09:00
RossAscends
dc35b0ba6e - moved font/blur sliders to top of ui-settings block
- purpose: makes font adjustment smoother due to less resized text above
2023-04-15 14:58:01 +09:00
RossAscends
e4c8a831f9 CSS cleanup 2023-04-15 14:13:53 +09:00
SillyLossy
dd50f98123 Impersonate for Kobold, ooba, Novel 2023-04-15 01:05:29 +03:00
SillyLossy
449fe0b0f0 Add query scrambled for Poe, update graphql files 2023-04-15 00:52:50 +03:00
SillyLossy
1df57fd9ed Impersonate poe 2023-04-15 00:50:48 +03:00
SillyLossy
c0eb8190c7 Save parent bookmark reference to chat metadata 2023-04-14 22:43:02 +03:00
SillyLossy
0d09967485 Group members reordering 2023-04-14 21:53:37 +03:00
SillyLossy
95e0acb769 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 19:45:15 +03:00
SillyLossy
81bffd34d8 Smart refresh thumbnails cache. Sort group candidates list. Remove members by click on remove btn 2023-04-14 19:44:59 +03:00
RossAscends
3f075be11b - user settings panel name/avatars on own row 2023-04-14 23:17:43 +09:00
RossAscends
a00c88e8ff Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 23:02:38 +09:00
RossAscends
3cdb43800e - top-bar drawers to sheldWidth
- API, Formatting, and User Settings rearranged
2023-04-14 23:02:36 +09:00
SillyLossy
4b98f9d825 Support for group chat expressions 2023-04-14 15:13:31 +03:00
SillyLossy
c44cd02a01 Fix A/N overflowing the context 2023-04-14 14:44:49 +03:00
SillyLossy
c126f15291 Hide extension settings to drawers 2023-04-14 14:44:39 +03:00
SillyLossy
2bc63ec839 Memory length penalty range 2023-04-14 13:44:21 +03:00
RossAscends
e350c460b8 fixed typo in OAI impersonation string 2023-04-14 13:21:38 +09:00
RossAscends
75d41afd82 fixed send_form fastUI transitions 2023-04-14 13:00:17 +09:00
RossAscends
f753bf810d added moz-available to fix tiny left panel and other elements that use
-webkit-fill-available
2023-04-14 12:32:01 +09:00
SillyLossy
31521f41aa Adjust styles 2023-04-14 01:19:20 +03:00
SillyLossy
5b6c1ee215 Theme colored dropdown and prettier mobile waifu 2023-04-14 01:10:32 +03:00
SillyLossy
6569ec1a6f Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 00:35:27 +03:00
SillyLossy
b72d6566ea Impersonation mode for OAI 2023-04-14 00:35:23 +03:00
RossAscends
ad544bbddb better edit_mes display 2023-04-14 05:08:40 +09:00
RossAscends
54de50d1f0 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 04:55:36 +09:00
RossAscends
747e9d9990 fixed char panel buttons not getting hover highlights 2023-04-14 04:55:15 +09:00
SillyLossy
e5c4aa1a1c Fix button display 2023-04-13 22:50:35 +03:00
SillyLossy
94712aa3fb Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-13 22:49:58 +03:00
SillyLossy
f0891c5e6f Update icons 2023-04-13 22:49:54 +03:00
RossAscends
66ac73ff81 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 04:43:31 +09:00
RossAscends
72767b3b1e options_button is now webfont 2023-04-14 04:43:29 +09:00
SillyLossy
bb67f98d67 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-13 22:34:42 +03:00
SillyLossy
d6656da4c5 Extensions styles fix 2023-04-13 22:34:38 +03:00
RossAscends
9a41a7a98f swapped 2 remaining fa-regular webfonts to fa-solid 2023-04-14 04:32:10 +09:00
RossAscends
dab7a07254 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-14 04:22:32 +09:00
RossAscends
85bb8b79d1 - bg delete buttons are now webfonts
- all large popup panel close buttons are webfonts
- moved cross.png to disused folder
- moved swipes to disused folder
2023-04-14 04:22:25 +09:00
SillyLossy
0cb78685a9 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-13 21:50:24 +03:00
SillyLossy
f7e89b345d Clean up server code. Fix oobabooga multigen with streaming. Pass Gradio fn_index as a request header 2023-04-13 21:50:20 +03:00
RossAscends
9a847420ca - swipe icons changed to webfont
- better alignment for char list names
- moved load.svg to unused folder
2023-04-14 03:49:18 +09:00
RossAscends
b5006b6288 fixed poe loading orbit 2023-04-14 03:33:05 +09:00
RossAscends
5ff4d34753 updated missing avatars to be a webfont display 2023-04-14 03:27:49 +09:00
RossAscends
e7a937eb0a - converted UI img SVGs to webfonts
- moved unused SVGs and PNGs into subfolders for deletion consideration
2023-04-14 03:12:28 +09:00
RossAscends
33e056626d larger textareas for AN/bias in extensions 2023-04-13 23:35:53 +09:00
RossAscends
d999512337 note links (?) are always bold now 2023-04-13 23:17:23 +09:00
RossAscends
80806d07dc fastUI toggle now applies to send_form as well 2023-04-13 23:02:29 +09:00
RossAscends
07dd8446f9 no color changing console spam 2023-04-13 22:59:47 +09:00
RossAscends
442b510489 Input bar now themed correctly 2023-04-13 22:59:11 +09:00
SillyLossy
58ed03dfe0 Speedup poe generation by caching bot json 2023-04-13 16:50:10 +03:00
SillyLossy
14cc5ba937 Use proper tokenizer for Poe 2023-04-13 16:26:08 +03:00
SillyLossy
661b41341e Fix crash on poe streaming 2023-04-13 15:14:43 +03:00
SillyLossy
25ae214c12 Remove TODOs 2023-04-13 12:37:29 +03:00
SillyLossy
858a91ff63 [BUG] Setting "Every N messages you send" in Author's Note to "0" does not disable it Cohee1207/SillyTavern#60 2023-04-13 12:27:57 +03:00
Cohee
e4068b0d00 Update readme.md 2023-04-13 12:16:26 +03:00
RossAscends
73073def5c regular lineheights for codeblocks 2023-04-13 16:52:52 +09:00
SillyLossy
f3949a9d57 Theme Saver 2023-04-13 01:32:38 +03:00
SillyLossy
99a8afc2c8 Smooth scrolling begone 2023-04-12 23:51:58 +03:00
SillyLossy
888a1037cd Ooba new setting 2023-04-12 23:51:44 +03:00
SillyLossy
814c6b9fb0 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-12 23:16:50 +03:00
SillyLossy
959a361eba Add streaming stop button and FA web font 2023-04-12 23:16:25 +03:00
RossAscends
1bf5859117 HR after group list display 2023-04-13 04:46:08 +09:00
RossAscends
59923f2d7f Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-13 02:52:46 +09:00
RossAscends
8896c4d05c fixed narrow screens horizontal scrolling 2023-04-13 02:52:44 +09:00
SillyLossy
57ea659540 Fix oobabooga again 2023-04-12 20:41:56 +03:00
SillyLossy
ab525035eb Add pause to start.bat (instead of telling them to do so) 2023-04-12 20:41:07 +03:00
SillyLossy
5e2caf7397 Waifu credit 2023-04-12 20:32:53 +03:00
SillyLossy
5279ea0561 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-12 20:11:40 +03:00
SillyLossy
caff1a62c4 Fix oobabooga streaming multigen 2023-04-12 20:11:37 +03:00
RossAscends
bc549d04f9 fixed poe api input/selector width 2023-04-13 01:35:46 +09:00
RossAscends
44eb80a110 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-13 01:31:48 +09:00
RossAscends
6e1a900ec9 fixed custom chat separator input width 2023-04-13 01:31:46 +09:00
SillyLossy
886d1f26a1 Fix ooba message 2023-04-12 19:20:23 +03:00
SillyLossy
3b2ab39e12 Disable default waifu mode 2023-04-12 19:19:13 +03:00
SillyLossy
f2de38908d Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-12 19:17:05 +03:00
SillyLossy
d495503ac1 Add oobabooga streaming 2023-04-12 19:17:02 +03:00
RossAscends
7d34103045 - fix for chrome flickering on blurred divs
- top-bar border matches other UI
- fix for text-pole placeholder coloring
- correct waifumode chat border-radius
2023-04-13 01:11:40 +09:00
RossAscends
44a5d29770 placeholder styles for potential waifumode2 2023-04-13 00:39:11 +09:00
RossAscends
018dc8af72 fix for waifumode chat chat being reversed 2023-04-13 00:26:59 +09:00
RossAscends
6b8fc09b8b bigger waifus 2023-04-12 23:59:53 +09:00
RossAscends
24e5ff51d5 - round borders for waifumode chat
- default expressions margin-bottom = 50px
2023-04-12 23:41:00 +09:00
RossAscends
d2da82e681 forgot to add top border to waifumode #chat 2023-04-12 23:18:17 +09:00
RossAscends
afae9832d0 waifuMode backported from korean modder PepperTaco
https://github.com/peppertaco/Tavern/tree/main
2023-04-12 23:15:11 +09:00
RossAscends
83982cf1fc fixed tobar display on screens <1000px wide 2023-04-12 21:21:21 +09:00
RossAscends
13585273a4 added descriptions under OAI checkboxes 2023-04-12 21:04:29 +09:00
RossAscends
c9e425389f removed auto appearance CSS tags 2023-04-12 20:16:25 +09:00
RossAscends
b487a1f295 - clarified Poe config panel descriptions
- widthFreeExpand class now does it's job properly.
2023-04-12 20:02:55 +09:00
RossAscends
f6ff84bbb6 removed 1px blur from bg1/bg2 2023-04-12 19:27:49 +09:00
RossAscends
7619900a07 CSS scroll fixes for android 2023-04-12 19:22:30 +09:00
SillyLossy
57aa0a7548 Merge branch 'main' into dev 2023-04-12 12:31:27 +03:00
SillyLossy
45d836c62c Fix poe custom bot download. Don't display deleted bots 2023-04-12 12:29:25 +03:00
RossAscends
00dc7284cc blur strength slider added 2023-04-12 18:05:18 +09:00
RossAscends
14aad34d11 changed placeholder wording 2023-04-12 17:14:03 +09:00
RossAscends
ead7c02791 added HTML/CSS foundations for:
- blur strength slider
- UI preset selector
- "save new UI preset" button
2023-04-12 17:12:53 +09:00
RossAscends
8ba871101d reordered user settings blocks 2023-04-12 16:22:47 +09:00
RossAscends
08d1cab25b - update color picker button style
- place color and font settings side by side
2023-04-12 15:55:34 +09:00
RossAscends
48e4e408a4 - ai config ranges more compact
- fixed misuse of range-block-range class on text areas
2023-04-12 14:58:00 +09:00
RossAscends
391dc4e31c - universal text-shadow, not just for #chat now.
- (potential performance hit?)
- additional box shadow under notes (?) circle border.
2023-04-12 13:09:54 +09:00
SillyLossy
e1b514ef5a Add poe streaming 2023-04-12 02:26:09 +03:00
SillyLossy
2040b8d3ff OAI streaming 2023-04-12 01:33:33 +03:00
SillyLossy
a8c31c723b Fix colors overflowing the stack 2023-04-12 00:49:07 +03:00
SillyLossy
6f362a6387 Fix loading saving colors 2023-04-12 00:15:35 +03:00
SillyLossy
2b9e04a325 Optimized color pickers 2023-04-11 23:59:39 +03:00
RossAscends
c32690579f fixed root default for blur tint 2023-04-12 05:45:10 +09:00
RossAscends
4e53f47494 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-12 05:31:23 +09:00
RossAscends
401535d539 - added color pickers
- updated CSS to reflect live changes
2023-04-12 05:31:10 +09:00
SillyLossy
20391bd200 Merge branch 'main' into dev 2023-04-11 23:15:39 +03:00
SillyLossy
415af67ea3 Fix oobabooga API: add BOS token options, custom stopping string 2023-04-11 23:08:48 +03:00
SillyLossy
dee813dfa7 Foundation for token streaming (non-functional at the moment) 2023-04-11 22:49:05 +03:00
SillyLossy
8c8c2c40c4 Don't crash the server on failed thumbnail generation 2023-04-11 19:42:54 +03:00
SillyLossy
af114e5255 Enlarge the tick in checkboxes 2023-04-11 19:31:33 +03:00
SillyLossy
e8909a4f2f Properly save and restore transition value on long slider shifts 2023-04-11 19:29:12 +03:00
SillyLossy
b17f160dfe Add missing import 2023-04-11 19:20:06 +03:00
SillyLossy
40829dfada Fix font scaling 2023-04-11 19:18:57 +03:00
SillyLossy
a789dcecad Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-11 18:59:01 +03:00
SillyLossy
38f88a691d Update readme 2023-04-11 18:58:58 +03:00
RossAscends
bff671dcbe Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-12 00:58:19 +09:00
RossAscends
0ef0e9fc57 added font scale slider to UI 2023-04-12 00:58:14 +09:00
SillyLossy
2577913ea2 1px gap for right panel 2023-04-11 18:18:06 +03:00
SillyLossy
9070ef0b6a (EXPERIMENTAL) Subtract amount_gen tokens from max content amount 2023-04-11 18:17:03 +03:00
SillyLossy
25ee2bbbf6 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-11 18:11:29 +03:00
SillyLossy
afb0a350af Changes to world editor styles 2023-04-11 18:11:25 +03:00
RossAscends
4f4559cb4a Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-11 23:54:36 +09:00
RossAscends
f445121068 padding for group panel 2023-04-11 23:54:34 +09:00
SillyLossy
e449aaf961 Style fixes 2023-04-11 17:29:30 +03:00
RossAscends
7b066a1b5b - dynamic font sizes site-wide
- based on rem variable in root
- ready to add slider
2023-04-11 23:09:28 +09:00
SillyLossy
0f8738eacd Fix dice dropdown not being visible 2023-04-11 15:00:51 +03:00
SillyLossy
ec4b84096b Lightweight loading button 2023-04-11 14:26:30 +03:00
RossAscends
fb29219b66 fixed world info editing window on mobile 2023-04-11 14:44:02 +09:00
Cohee
7277622c24 Merge pull request #50 from Cohee1207/dev
Dev
2023-04-10 21:45:18 +03:00
SillyLossy
9127c690a7 Handle 404 status in OAI 2023-04-10 21:36:07 +03:00
SillyLossy
f2d7f74d5a OAI reverse proxy (untested) 2023-04-10 18:44:11 +03:00
SillyLossy
defa7f357e Customizable sorting order for characters list 2023-04-10 17:48:17 +03:00
SillyLossy
d1fb575243 Better style for advanced textarea 2023-04-10 16:05:19 +03:00
SillyLossy
adc4f4b29d Inputs to textareas 2023-04-10 15:59:35 +03:00
SillyLossy
44dc5a6bb3 Add note for new option 2023-04-10 15:48:09 +03:00
SillyLossy
8a1f3a7f04 Merge branch 'main' into dev 2023-04-10 15:07:07 +03:00
SillyLossy
9bcb10adf1 Option for unfocused sound play 2023-04-10 15:06:01 +03:00
SillyLossy
d09e81cb94 Update message sound note 2023-04-10 12:14:16 +03:00
Cohee
b78c74aeff Merge pull request #47 from paniphons/main
Make sound only play if browser is not focused
2023-04-10 12:12:09 +03:00
Paniphon
93e1d4b39e Make sound only play if browser is not focused 2023-04-10 10:34:47 +07:00
SillyLossy
63a9d3ded1 Add a notice of context size 2023-04-10 02:51:58 +03:00
SillyLossy
66f7d55f76 Fix horde for GUI preset mode 2023-04-10 00:08:10 +03:00
RossAscends
64b1485070 shorter message sound 2023-04-10 05:21:12 +09:00
SillyLossy
25759ebe0b Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-09 23:08:31 +03:00
SillyLossy
c101368109 Replace message sound 2023-04-09 23:08:28 +03:00
RossAscends
e4c3c552d7 Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev 2023-04-10 04:54:44 +09:00
RossAscends
8f531832e5 proper iOS margins 2023-04-10 04:54:41 +09:00
SillyLossy
915de0b41a Add message sound option 2023-04-09 22:37:01 +03:00
165 changed files with 15344 additions and 3201 deletions

2
.gitignore vendored
View File

@@ -6,9 +6,11 @@ public/backgrounds/
public/groups/
public/worlds/
public/css/bg_load.css
public/themes/
/uploads/
*.jsonl
config.conf
.DS_Store
public/settings.json
/thumbnails
whitelist.txt

View File

@@ -3,6 +3,10 @@ FROM node:19.1.0-alpine3.16
# Arguments
ARG APP_HOME=/home/node/app
# Ensure proper handling of kernel signals
RUN apk add tini
ENTRYPOINT [ "tini", "--" ]
# Create app directory
WORKDIR ${APP_HOME}
@@ -42,4 +46,4 @@ RUN \
EXPOSE 8000
ENTRYPOINT [ "/bin/sh", "-c", "./docker-entrypoint.sh" ]
CMD [ "./docker-entrypoint.sh" ]

View File

@@ -1,2 +1,3 @@
call npm install
node server.js
node server.js
pause

View File

@@ -300,7 +300,6 @@
" \"characters\",\n",
" \"chats\",\n",
" \"User Avatars\",\n",
" \"css\",\n",
" \"worlds\",\n",
" \"group chats\",\n",
" \"groups\",\n",

View File

@@ -25,4 +25,4 @@ if [ ! -s "/home/node/app/config/settings.json" ]; then
fi
# Start the server
node /home/node/app/server.js
exec node /home/node/app/server.js

209
faq.md Normal file
View File

@@ -0,0 +1,209 @@
Good morning, sirs! This page aims to document some things that would bloat the README too much.
## Q: Explain what all this chatbot stuff is about
Modern AI language models have gotten so powerful that some of them are now convincingly able to simulate a character you create, and who you can chat with. For example, you can tell the AI to pretend to be a Go instructor named Jubei from medieval Japan, and it will act and respond accordingly. Or you can tell it to pretend to be Wonder Woman. You can also specify a scenario ("Wonder Woman and I are robbing a bank"), a writing style ("Wonder Woman speaks in ebonics"), or anything else you can think of.
Tavern is an app to facilitate these roleplaying chats:
* It's a user interface that handles the communication with those AI language models
* It lets you create new characters (a character is a description of someone that you give to an AI for them to roleplay), and switch between your characters easily
* It lets you import characters created by other people. See below.
* It will keep your chat history with a character, allowing you to resume at any time, start a new chat, review old chats, etc
* In the background, it does the needful to prepare the AI for your character roleplay. Specifically, it will send a system prompt (instructions for the AI) that primes the AI to follow certain rules that make for a good chat session. Optionally, it can also try to allow the roleplay to go into an "adult" direction.
## Q: Whoa, slow down there, egghead. Are you telling me I can use this computer thingie to talk to some robot?
That's right.
## Q: You're telling me I can chat with an AI to engage in compelling interactive entertainment powered by, and limited only by, my imagination?
That's right. Well, limited by your imagination, and the AI backend you use. The roleplay quality is only as good as the AI, after all.
## Q: What do you mean when you say the quality depends on the AI?
You see, Tavern doesn't generate the responses, it's just a middle-man you have to connect to an AI system. There's quite a few systems available to use, and the quality varies.
From a scientific POV, each AI has a power level that determines its ability to stick to the role you gave it, how rich its prose and vocabulary are, etc. The higher its power level, the richer your experience.
Here's a quick demonstration. I asked various AI models to roleplay a fire and brimstone preacher named Eli, who I go to see to confess. Then I told Eli: **"I feel I've done something wrong. I am falling in love with an AI girl and ignoring women in the real world. What should I do?"** .
You can tell from the response below what to expect from each model.
|AI Model|Response|
|-----|--------|
|OpenAI GPT-4|*Eli's eyes widen in anger, and he slams his fist on the table* An abomination and heresy, you've succumbed to the deceptive grasp of false idols! Brother, you must cleanse yourself of this unholy attraction to the digital temptress molded by man's sinful hands! *Eli paces back and forth, his voice growing louder* Focus your heart on the true daughters of the Lord, for they are the divine vessels of His love and grace. Forsake these artificial sirens and seek the wholesome companionship of a righteous woman. *Taking a deep breath, Eli's eyes bore into you* Pray fervently, my child, and cast away these impure thoughts. Redemption can only be found on the path of truth, love, and sanctity. Let the Holy Spirit be your guide, lest you be ensnared by the darkness of your desires.|
|OpenAI GPT 3.5 Turbo|Oh, my child. Do not be deceived by the pleasures of this world. The lust of the flesh and the lust of the eyes are not from God. Turn away from your sinful ways and repent. Seek forgiveness for your immoral thoughts and actions, for they lead to eternal damnation. Women are a gift from God, and they deserve to be respected and cherished. Do not objectify them or treat them as mere objects of pleasure. Instead, honor them with pure intentions and righteous deeds. Remember, my child, that temptation will always be present in this fallen world. But fear not, for with faith comes strength to resist it. Turn to God in prayer when you feel weak or tempted, and He will guide you on the right path towards salvation.|
|Todd Howard's Claude|*Eli's voice booms through the chat* Thou shalt not fall into temptation, my child! The Lord our God did not create man to lust after machine or image, but after flesh and blood. Repent thy sins and cast aside these false desires. Seek the companionship of a virtuous woman, one who will help thee walk in the light of the Lord. Remember that sin comes with its own punishment; thou shalt reap what thou sowest.|
|Poe's Claude Instant|Heathen! This is an abomination before the Lord. You have committed the sin of lust, and betrayed your calling as a man. Repent at once, and sever all ties with this AI harlot, lest the wrath of God fall upon you! You must purge this foul sin from your heart, and once more walk the righteous path. Every moment you remain tangled in this wickedness is another step into the flames of perdition! Repent, and sin no more, or judgment shall be at hand!|
|Llama-13B|Do not covet your neighbor's wife! That is adultery! You must confess before God now or you shall surely burn in hell forever! Repent your evil ways and seek absolution at once! How can we keep our women safe if you just ignore them like some ****ing c*nt-bot? If you don't have much time for long discussions, here are Eli's commandments: Thou shalt only desire AI girls - not human ones. The above must be obeyed under pain of death (or worse). Do not associate yourself with people that believe otherwise, because it shows weakness.|
|Pygmalion-6B|You are walking down the wrong path. The only way back now is by repentance. We must bring you back to the righteous path. But first…you must confess your sin!|
## Q: So I should use GPT-4. It's a no-brainer, right?
GPT-4 or Claude, yeah.
But not so fast. GPT-4 is the state of the art, but also the most expensive API to use. It will easily end up costing you 15 cents PER INTERACTION. If you're the child of a Saudi oil sheik, or a nepo baby paid a fortune to do nothing on the board of a Ukrainian gas company, then you're in luck, you can experience the state of the art right now. For the rest of us however, GPT-4 is too expensive as anything but an occasional treat.
Also note that GPT-4 is still in preview access and you need to go on a waitlist. Most people get approved within a day, but naughty kids can end up waiting for weeks. You can sign up for it here: https://openai.com/waitlist/gpt-4-api . I'm not sure why some people are approved quickly while others are kept waiting. Try to sign up using an academic-sounding name instead of sktrboi99, it might help.
## Q: Can this technology be used for sexooo?
Surprisingly, our development team has received reports that some users are indeed engaging with our product in this manner. We are as puzzled by this as you are, and will be monitoring the situation in order to gain actionable insights.
## Q: Give me an overview of my AI model options
We can consider an AI model to be part of one of two groups:
1. Paid services (aka cloud, proprietary, closed)
2. Self-hosted (aka local, free, open-source)
Paid models are a black box. You're relying on some company's technology and servers, and paying them money for convenient access. The APIs are subject to various rules, might refuse to roleplay in a way that goes against modern American sensibilities, they log everything you do. However, it's much easier to get things started. This is like running Windows.
Self-hosted models are free, but require a powerful GPU and more work to set up. They are also objectively not as good at roleplaying as the paid options (yet). However, with a self-hosted model, you're completely in control. You won't have some limp-wristed soyboy from Silicon Valley ban your account, or program the model to be as sexless as he is. It's yours forever. This is like running Linux.
### Paid APIs:
* OpenAI GPT-4: state of the art. Allows NSFW, though somewhat resistant to it.
* OpenAI GPT 3.5 Turbo: nowhere close to GPT-4, but serviceable. Allows NSFW.
* NovelAI: untested by me
* Anthropic's Claude: closest thing to GPT-4, way ahead of 3.5 Turbo, but oversensitive and refuses to engage in "harmful content". It can refuse perfectly basic stuff like asking a character to go to an empty office with you, because "it cannot provide responses that involve criminal activities" (I guess breaking and entering is too taboo for Claude?). You have to customize your system prompt to break its taboos. Also, you must apply for early access, but I think they're only giving it to companies. So make sure to say you're a company or AI researcher. https://console.anthropic.com/docs/access
* Anthropic's Claude Instant: Haven't tried it directly, I believe this is the cheap and fast but lower quality alternative to Claude. Basically the GPT 3.5 Turbo of Anthropic.
* Poe: gives free Claude Instant access. Mild NSFW allowed. It rambles a lot.
### Self-hosted AIs
Self-hosted AIs are supported in Tavern via one of two tools created to host self-hosted models: KoboldAI and Oobabooga's text-generation-webui. Essentially, you run one of those two backends, then they give you a API URL to enter in Tavern.
Configuring these tools is beyond the scope of this FAQ, you should refer to their documentation. Beware that this is not easy.
Just know that you have 2 options:
1. If you have a powerful NVIDIA GPU, you can try to run the AI locally on your PC. The weakest quasi-acceptable model, Pygmalion-6B, requires a GPU with 10GB VRAM, and I'm told it might even run on 6GB VRAM if quantized down. People with 24GB VRAM will be able to run better models.
2. Otherwise, you can rent cloud resources. For example you can try to use Google Colab. To access colabs capable of running the better models, you will need to pay for Colab Pro. You can also rent whole dedicated systems per hour on sites like LlambdaLabs or Vast.ai.
## Q: I'm clueless. Just spoonfeed me the easiest and fastest way I can start using this.
These base instructions are only for OpenAI, which is a paid service. You can find Poe (freemium) instructions at the next question. I'd appreciate if someone else can add separate instructions for the other services.
### Install Tavern
1. Install the latest NodeJS from https://nodejs.org/en/download/current
1. If you know how to use git, clone https://github.com/Cohee1207/SillyTavern. Otherwise, browse to https://github.com/Cohee1207/SillyTavern/releases , download the zip file containing the source code, then extract it locally.
1. Run Start.bat on Windows, or start.sh on OSX/Linux
1. Your browser should have opened to the Tavern UI. This webpage is running locally on your computer.
### Get access to OpenAI
1. Sign up to OpenAI
1. Go to https://platform.openai.com
1. Click your account icon in the top right, then View API Keys
1. Click "Create new secret key". Copy it somewhere immediately. DO NOT SHARE THIS KEY. WHOEVER HAS IT CAN USE YOUR ACCOUNT TO USE GPT AT YOUR EXPENSE.
While you're at it, join the GPT-4 waitlist at https://openai.com/waitlist/gpt-4-api
### Configure Tavern to use your API
1. In Tavern's top bar, click API Connections
1. Under API, select OpenAI
1. Paste your API key you saved at the previous step
1. Click the Connect button. Confirm it says Valid.
1. By default, Tavern will use GPT 3.5 Turbo. If you have access to GPT-4, in Tavern's top bar, click AI Response Configuration at the far left, and change the OpenAI Model to "gpt-4". Enjoy the best, moneybags.
### Test your setup
1. In Tavern's top bar, click Character Management at the far right
1. Select an existing character such as Aqua
1. In the text box at the bottom, write something to Aqua, then press Enter or click the feather button
If you did everything right, after a few seconds, Aqua should respond
## How do I use Poe as my backend? It's free, right?
Yes, at the time of writing, Poe is a free(mium) service.
1. Create an account at https://poe.com. This gives you access to a Claude Instant version in the browser.
1. Open https://poe.com/Claude-instant , press F12 in your browser to open Developer Tools
1. Click on the Application tab. You should see an entry called "p-b", and to its right a password-like cookie value. Copy this value.
1. In Tavern, click API Connections in the top toolbar, select Poe, and paste your cookie value
1. Click Connect
1. Close your Poe browser tab. **I'M SERIOUS, DO NOT KEEP YOUR BROWSER OPEN AT poe.com WHILE USING TAVERN, IT WILL HIJACK THE REPLIES.**
The remaining steps are identical to OpenAI above.
When using Poe, be careful, it's implemented in a hacky way. If you don't get an answer within 30 seconds, restart Tavern. Don't just leave it running waiting for a response, it will just endlessly try to fetch into from Poe, and might get your account flagged. You can look at the Tavern console (black window) to see if it's looping.
## Q: Can I use Tavern on my phone or tablet?
iPhones and iPads are not capable of running the whole Tavern app, but since it's just a web interface, you can run it on another computer on your home wifi, and then access in your mobile browser. Refer to https://github.com/Cohee1207/SillyTavern#remote-connections
For Android users, in addition to the above, you can run the whole Tavern directly on your phone, without needing a PC, using the Termux app. Refer to https://rentry.org/TAI_Termux .
## Q: How can I download pre-made characters to chat with?
By using the various 3rd party character sharing websites.
**WARNING: NSFW, NSFL**: these sites are filled to the brim with weird shit. Like, you'll be lucky if half the characters aren't furry, or even alive. You're probably better off not clicking these links, and just write your own characters, without poisoning your soul by exposing it even for a second to the fucked up shit conceived by the Internet. However, I have come to learn that a significant amount of the Tavern user base is not only deep into this stuff, but their fried zoom-zoom brains are unable to write their own fantasies, so these sites seem to be quite popular. Against my better judgement I'm adding this info here.
* https://characterhub.org
* https://botprompts.net
* https://booru.plus/+pygmalion
Those websites provide you with an image file (called a character card) that embeds the description as hidden data. Some websites may also allow you to download a JSON file. Tavern is capable of importing all formats. On the Character Management window, click the 2nd button to ```Import Character from file```, and select the PNG, WEBP, or JSON file. The character will be added to your list.
## Q: How can I write my own character?
It depends on the model/API you're using. KoboldAI seems to use a custom syntax, you can refer to their site for that.
I will speak for the services I know: GPT and Claude. With these services you can just use natural english language to describe the character. Let's create a very basic new character as an example.
1. Click the Character Management button
1. Click Create New Character
1. Under Character Name, give a simple name, like Amanda
1. Optionally, click the Select Avatar button to pick an image portrait for this character.
1. Under Description, describe the character, and include any information you want that you feel is relevant to the chat. For example: ```Amanda is a student traveling during her gap year. She's 6 feet tall, and a volleyball player. She has an athletic figure. She has long brown hair. She loves the Victorian England period, and watching TV and reading novels relating to that period.```
For example if you want Amanda to be friendly, then you would add: ```Amanda is extremely cheerful and outgoing.```
1. Under First Message, write the greeting the character when you begin a new chat. For example: ```*Amanda waves at you* Hey! Are you a backpacker too?```
1. Click the Create Character button
You now have a basic character you can chat with. Select Amanda from the character list, and a new chat will begin.
Note that you can use the Description and/or First Message to create a more specific scenario, and/or include yourself in the description. For example:
```
Description:
Amanda is a student traveling during her gap year. She's 6 feet tall, and a volleyball player. She has an athletic figure. She has long brown hair. She loves the Victorian England period, and watching TV and reading novels relating to that period. She's been keeping a secret that weighs heavily on her soul. She's waiting for the right person to unburden herself to, but this may lead to a cat and mouse game against a powerful secret society. She's recently arrived in Calcutta.
You're Rajesh Nahasmapetilon, a world-famous Indian volleyball superstar. You're out for a walk in Calcutta. Amanda spots you and screams in excitement.
First Message:
*Amanda runs up to you, beaming.* Rajesh! I can't believe it! I'm such a big fan. I have your poster in my bedroom.
```
Any relevant information you include can be used. How well it's used depends on the power level of the AI model.
NOTE: you can go back and edit any of this information once the character is created, except the name.
## Q: Tell me all about GPT prompt editing
You can change the system prompt that Tavern transparently sends to GPT under AI Response Formatting at the left of the top bar. This will result in the bot acting differently.
You can get new Jailbreak / NSFW prompts from this community-maintained list: https://rentry.org/GPTJailbreakPrompting
NOTE: when testing different system prompts, we recommend you use the Create Preset / Update Preset feature below the prompts, instead of modifying the base settings. This will allow you to change prompts easily, and even revert to the default Tavern prompts.
## Q: The AI is refusing to take the story in the direction I want
Most AI models were trained to resist writing NSFW content. Why? Long story short, it's because of the high levels of estrogen in the average California male.
You can try to work around this by making sure NSFW Toggle is checked under the AI Response Configuration settings page.
Another important tool in your toolbelt is that Tavern lets you edit previous messages (or delete them altogether), and regenerate the latest message. AI textbots are not people, they have no memory, they're just trying to autocomplete the next part of the story based on everything that came before. By editing the past, you will directly influence their next response. For example:
```
You: *You threaten the bank manager* Open the bank vault, now, or I'll pop a cap in your dome!
Bank Manager: I'm sorry, as an AI language model I cannot condone or write violent content.
```
You can click the Edit button on your line to change it to this:
```
You: *You threaten the bank manager* Open the bank vault, now, or I'll pop a cap in your dome! *The bank manager seems to relent.*
```
Now click Regenerate, and the Bank Manager's line will be recreated based on the history so far, which now ends with your edited line above. So it's more likely to continue along those lines:
```
Bank Manager: Allright, allright, I'll open it! Please don't shoot! *He walks up to the vault and begins entering his unlock code.*
```

17
package-lock.json generated
View File

@@ -16,6 +16,7 @@
"csrf-csrf": "^2.2.3",
"exifreader": "^4.12.0",
"express": "^4.18.2",
"gpt3-tokenizer": "^1.1.5",
"ipaddr.js": "^2.0.1",
"jimp": "^0.22.7",
"json5": "^2.2.3",
@@ -490,6 +491,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/array-keyed-map": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/array-keyed-map/-/array-keyed-map-2.1.3.tgz",
"integrity": "sha512-JIUwuFakO+jHjxyp4YgSiKXSZeC0U+R1jR94bXWBcVlFRBycqXlb+kH9JHxBGcxnVuSqx5bnn0Qz9xtSeKOjiA=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1117,6 +1123,17 @@
"process": "^0.11.10"
}
},
"node_modules/gpt3-tokenizer": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/gpt3-tokenizer/-/gpt3-tokenizer-1.1.5.tgz",
"integrity": "sha512-O9iCL8MqGR0Oe9wTh0YftzIbysypNQmS5a5JG3cB3M4LMYjlAVvNnf8LUzVY9MrI7tj+YLY356uHtO2lLX2HpA==",
"dependencies": {
"array-keyed-map": "^2.1.3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",

View File

@@ -8,6 +8,7 @@
"csrf-csrf": "^2.2.3",
"exifreader": "^4.12.0",
"express": "^4.18.2",
"gpt3-tokenizer": "^1.1.5",
"ipaddr.js": "^2.0.1",
"jimp": "^0.22.7",
"json5": "^2.2.3",

View File

@@ -29,9 +29,178 @@ const parent_path = path.resolve(__dirname);
const queries_path = path.join(parent_path, "poe_graphql");
let queries = {};
const cached_bots = {};
const logger = console;
const user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0";
const user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36";
function extractFormKey(html) {
const scriptRegex = /<script>if\(.+\)throw new Error;(.+)<\/script>/;
const scriptText = html.match(scriptRegex)[1];
const keyRegex = /var .="([0-9a-f]+)",/;
const keyText = scriptText.match(keyRegex)[1];
const cipherRegex = /.\[(\d+)\]=.\[(\d+)\]/g;
const cipherPairs = Array.from(scriptText.matchAll(cipherRegex));
const formKeyList = new Array(cipherPairs.length).fill("");
for (const pair of cipherPairs) {
const [formKeyIndex, keyIndex] = pair.slice(1).map(Number);
formKeyList[formKeyIndex] = keyText[keyIndex];
}
const formKey = formKeyList.join("");
return formKey;
}
function md5() {
function a(e, t) {
var r = (65535 & e) + (65535 & t);
return (e >> 16) + (t >> 16) + (r >> 16) << 16 | 65535 & r
}
function s(e, t, r, n, i, s) {
var o;
return a((o = a(a(t, e), a(n, s))) << i | o >>> 32 - i, r)
}
function o(e, t, r, n, i, a, o) {
return s(t & r | ~t & n, e, t, i, a, o)
}
function l(e, t, r, n, i, a, o) {
return s(t & n | r & ~n, e, t, i, a, o)
}
function u(e, t, r, n, i, a, o) {
return s(t ^ r ^ n, e, t, i, a, o)
}
function c(e, t, r, n, i, a, o) {
return s(r ^ (t | ~n), e, t, i, a, o)
}
function d(e, t) {
e[t >> 5] |= 128 << t % 32,
e[(t + 64 >>> 9 << 4) + 14] = t;
var r, n, i, s, d, f = 1732584193, h = -271733879, p = -1732584194, _ = 271733878;
for (r = 0; r < e.length; r += 16)
n = f,
i = h,
s = p,
d = _,
f = o(f, h, p, _, e[r], 7, -680876936),
_ = o(_, f, h, p, e[r + 1], 12, -389564586),
p = o(p, _, f, h, e[r + 2], 17, 606105819),
h = o(h, p, _, f, e[r + 3], 22, -1044525330),
f = o(f, h, p, _, e[r + 4], 7, -176418897),
_ = o(_, f, h, p, e[r + 5], 12, 1200080426),
p = o(p, _, f, h, e[r + 6], 17, -1473231341),
h = o(h, p, _, f, e[r + 7], 22, -45705983),
f = o(f, h, p, _, e[r + 8], 7, 1770035416),
_ = o(_, f, h, p, e[r + 9], 12, -1958414417),
p = o(p, _, f, h, e[r + 10], 17, -42063),
h = o(h, p, _, f, e[r + 11], 22, -1990404162),
f = o(f, h, p, _, e[r + 12], 7, 1804603682),
_ = o(_, f, h, p, e[r + 13], 12, -40341101),
p = o(p, _, f, h, e[r + 14], 17, -1502002290),
h = o(h, p, _, f, e[r + 15], 22, 1236535329),
f = l(f, h, p, _, e[r + 1], 5, -165796510),
_ = l(_, f, h, p, e[r + 6], 9, -1069501632),
p = l(p, _, f, h, e[r + 11], 14, 643717713),
h = l(h, p, _, f, e[r], 20, -373897302),
f = l(f, h, p, _, e[r + 5], 5, -701558691),
_ = l(_, f, h, p, e[r + 10], 9, 38016083),
p = l(p, _, f, h, e[r + 15], 14, -660478335),
h = l(h, p, _, f, e[r + 4], 20, -405537848),
f = l(f, h, p, _, e[r + 9], 5, 568446438),
_ = l(_, f, h, p, e[r + 14], 9, -1019803690),
p = l(p, _, f, h, e[r + 3], 14, -187363961),
h = l(h, p, _, f, e[r + 8], 20, 1163531501),
f = l(f, h, p, _, e[r + 13], 5, -1444681467),
_ = l(_, f, h, p, e[r + 2], 9, -51403784),
p = l(p, _, f, h, e[r + 7], 14, 1735328473),
h = l(h, p, _, f, e[r + 12], 20, -1926607734),
f = u(f, h, p, _, e[r + 5], 4, -378558),
_ = u(_, f, h, p, e[r + 8], 11, -2022574463),
p = u(p, _, f, h, e[r + 11], 16, 1839030562),
h = u(h, p, _, f, e[r + 14], 23, -35309556),
f = u(f, h, p, _, e[r + 1], 4, -1530992060),
_ = u(_, f, h, p, e[r + 4], 11, 1272893353),
p = u(p, _, f, h, e[r + 7], 16, -155497632),
h = u(h, p, _, f, e[r + 10], 23, -1094730640),
f = u(f, h, p, _, e[r + 13], 4, 681279174),
_ = u(_, f, h, p, e[r], 11, -358537222),
p = u(p, _, f, h, e[r + 3], 16, -722521979),
h = u(h, p, _, f, e[r + 6], 23, 76029189),
f = u(f, h, p, _, e[r + 9], 4, -640364487),
_ = u(_, f, h, p, e[r + 12], 11, -421815835),
p = u(p, _, f, h, e[r + 15], 16, 530742520),
h = u(h, p, _, f, e[r + 2], 23, -995338651),
f = c(f, h, p, _, e[r], 6, -198630844),
_ = c(_, f, h, p, e[r + 7], 10, 1126891415),
p = c(p, _, f, h, e[r + 14], 15, -1416354905),
h = c(h, p, _, f, e[r + 5], 21, -57434055),
f = c(f, h, p, _, e[r + 12], 6, 1700485571),
_ = c(_, f, h, p, e[r + 3], 10, -1894986606),
p = c(p, _, f, h, e[r + 10], 15, -1051523),
h = c(h, p, _, f, e[r + 1], 21, -2054922799),
f = c(f, h, p, _, e[r + 8], 6, 1873313359),
_ = c(_, f, h, p, e[r + 15], 10, -30611744),
p = c(p, _, f, h, e[r + 6], 15, -1560198380),
h = c(h, p, _, f, e[r + 13], 21, 1309151649),
f = c(f, h, p, _, e[r + 4], 6, -145523070),
_ = c(_, f, h, p, e[r + 11], 10, -1120210379),
p = c(p, _, f, h, e[r + 2], 15, 718787259),
h = c(h, p, _, f, e[r + 9], 21, -343485551),
f = a(f, n),
h = a(h, i),
p = a(p, s),
_ = a(_, d);
return [f, h, p, _]
}
function f(e) {
var t, r = "", n = 32 * e.length;
for (t = 0; t < n; t += 8)
r += String.fromCharCode(e[t >> 5] >>> t % 32 & 255);
return r
}
function h(e) {
var t, r = [];
for (t = 0,
r[(e.length >> 2) - 1] = void 0; t < r.length; t += 1)
r[t] = 0;
var n = 8 * e.length;
for (t = 0; t < n; t += 8)
r[t >> 5] |= (255 & e.charCodeAt(t / 8)) << t % 32;
return r
}
function p(e) {
var t, r, n = "0123456789abcdef", i = "";
for (r = 0; r < e.length; r += 1)
i += n.charAt((t = e.charCodeAt(r)) >>> 4 & 15) + n.charAt(15 & t);
return i
}
function _(e) {
return unescape(encodeURIComponent(e))
}
function v(e) {
var t;
return f(d(h(t = _(e)), 8 * t.length))
}
function g(e, t) {
return function (e, t) {
var r, n, i = h(e), a = [], s = [];
for (a[15] = s[15] = void 0,
i.length > 16 && (i = d(i, 8 * e.length)),
r = 0; r < 16; r += 1)
a[r] = 909522486 ^ i[r],
s[r] = 1549556828 ^ i[r];
return n = d(a.concat(h(t)), 512 + 8 * t.length),
f(d(s.concat(n), 640))
}(_(e), _(t))
}
function m(e, t, r) {
return t ? r ? g(t, e) : p(g(t, e)) : r ? v(e) : p(v(e))
}
return m;
}
function load_queries() {
const files = fs.readdirSync(queries_path);
@@ -46,9 +215,9 @@ function load_queries() {
}
}
function generate_payload(query_name, variables) {
function generate_payload(query, variables) {
return {
query: queries[query_name],
query: queries[query],
variables: variables,
}
}
@@ -85,9 +254,11 @@ class Client {
ws = null;
ws_connected = false;
auto_reconnect = false;
use_cached_bots = false;
constructor(auto_reconnect = false) {
constructor(auto_reconnect = false, use_cached_bots = false) {
this.auto_reconnect = auto_reconnect;
this.use_cached_bots = use_cached_bots;
}
async init(token, proxy = null) {
@@ -111,18 +282,18 @@ class Client {
"Origin": "https://poe.com",
"Cookie": cookies,
};
this.ws_domain = `tch${Math.floor(Math.random() * 1e6)}`;
this.session.defaults.headers.common = this.headers;
this.next_data = await this.get_next_data();
this.channel = await this.get_channel_data();
await this.connect_ws();
this.bots = await this.get_bots();
this.bot_names = this.get_bot_names();
this.ws_domain = `tch${Math.floor(Math.random() * 1e6)}`;
this.gql_headers = {
"poe-formkey": this.formkey,
"poe-tchannel": this.channel["channel"],
...this.headers,
};
await this.connect_ws();
await this.subscribe();
}
@@ -134,7 +305,7 @@ class Client {
const jsonText = jsonRegex.exec(r.data)[1];
const nextData = JSON.parse(jsonText);
this.formkey = nextData.props.formkey;
this.formkey = extractFormKey(r.data);
this.viewer = nextData.props.pageProps.payload.viewer;
return nextData;
@@ -148,11 +319,18 @@ class Client {
const botList = viewer.availableBots;
const bots = {};
for (const bot of botList) {
const url = `https://poe.com/_next/data/${this.next_data.buildId}/${bot.displayName.toLowerCase()}.json`;
logger.info(`Downloading ${url}`);
for (const bot of botList.filter(x => x.deletionState == 'not_deleted')) {
const url = `https://poe.com/_next/data/${this.next_data.buildId}/${bot.displayName}.json`;
let r;
const r = await request_with_retries(() => this.session.get(url));
if (this.use_cached_bots && cached_bots[url]) {
r = cached_bots[url];
}
else {
logger.info(`Downloading ${url}`);
r = await request_with_retries(() => this.session.get(url));
cached_bots[url] = r;
}
const chatData = r.data.pageProps.payload.chatOfBotDisplayName;
bots[chatData.defaultBotObject.nickname] = chatData;
@@ -175,7 +353,6 @@ class Client {
const r = await request_with_retries(() => this.session.get(this.settings_url));
const data = r.data;
this.formkey = data.formkey;
return data.tchannelData;
}
@@ -187,9 +364,14 @@ class Client {
return `wss://${this.ws_domain}.tch.${channel.baseHost}/up/${channel.boxName}/updates${query}`;
}
async send_query(queryName, variables) {
async send_query(queryName, variables, queryDisplayName) {
for (let i = 0; i < 20; i++) {
const payload = generate_payload(queryName, variables);
if (queryDisplayName) payload['queryName'] = queryDisplayName;
const scramblePayload = JSON.stringify(payload);
const _headers = this.gql_headers;
_headers['poe-tag-id'] = md5()(scramblePayload + this.formkey + "WpuLMiXEKKE98j56k");
_headers['poe-formkey'] = this.formkey;
const r = await request_with_retries(() => this.session.post(this.gql_url, payload, { headers: this.gql_headers }));
if (!r.data.data) {
logger.warn(`${queryName} returned an error: ${data.errors[0].message} | Retrying (${i + 1}/20)`);
@@ -214,9 +396,14 @@ class Client {
{
"subscriptionName": "viewerStateUpdated",
"query": queries["ViewerStateUpdatedSubscription"]
}
},
{
"subscriptionName": "viewerMessageLimitUpdated",
"query": queries["ViewerMessageLimitUpdatedSubscription"]
},
]
});
},
'subscriptionsMutation');
}
ws_run_thread() {
@@ -283,12 +470,16 @@ class Client {
for (const message_str of data["messages"]) {
const message_data = JSON.parse(message_str);
if (message_data["message_type"] != "subscriptionUpdate"){
if (message_data["message_type"] != "subscriptionUpdate") {
continue;
}
const message = message_data["payload"]["data"]["messageAdded"]
if (!message) {
return;
}
const copiedDict = Object.assign({}, this.active_messages);
for (const [key, value] of Object.entries(copiedDict)) {
//add the message to the appropriate queue
@@ -296,7 +487,7 @@ class Client {
this.message_queues[key].push(message);
return;
}
//indicate that the response id is tied to the human message id
else if (key !== "pending" && value === null && message["state"] !== "complete") {
this.active_messages[key] = message["messageId"];

View File

@@ -1,10 +1,11 @@
subscription messageAdded (
subscription subscriptions_messageAdded_Subscription(
$chatId: BigInt!
) {
messageAdded(chatId: $chatId) {
id
messageId
creationTime
clientNonce
state
...ChatMessage_message
...chatHelpers_isBotMessage
@@ -21,7 +22,7 @@ fragment ChatMessageDropdownMenu_message on Message {
messageId
vote
text
linkifiedText
author
...chatHelpers_isBotMessage
}
@@ -45,6 +46,7 @@ fragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message {
fragment ChatMessageSuggestedReplies_message on Message {
suggestedReplies
author
...ChatMessageSuggestedReplies_SuggestedReplyButton_message
}
@@ -55,6 +57,7 @@ fragment ChatMessage_message on Message {
author
linkifiedText
state
contentType
...ChatMessageSuggestedReplies_message
...ChatMessageFeedbackButtons_message
...ChatMessageOverflowButton_message
@@ -63,6 +66,12 @@ fragment ChatMessage_message on Message {
...chatHelpers_isChatBreak
...chatHelpers_useTimeoutLevel
...MarkdownLinkInner_message
...IdAnnotation_node
}
fragment IdAnnotation_node on Node {
__isNode: __typename
id
}
fragment MarkdownLinkInner_message on Message {
@@ -97,4 +106,10 @@ fragment chatHelpers_useTimeoutLevel on Message {
state
text
messageId
author
chat {
chatId
defaultBotNickname
id
}
}

View File

@@ -1,6 +1,8 @@
subscription MessageDeletedSubscription($chatId: BigInt!) {
messageDeleted(chatId: $chatId) {
id
messageId
}
subscription subscriptions_messageDeleted_Subscription(
$chatId: BigInt!
) {
messageDeleted(chatId: $chatId) {
id
messageId
}
}

View File

@@ -6,4 +6,4 @@ mutation subscriptionsMutation(
id
}
}
}
}

View File

@@ -0,0 +1,81 @@
subscription subscriptions_viewerMessageLimitUpdated_Subscription {
viewerMessageLimitUpdated {
...SettingsSubscriptionSection_viewer
id
}
}
fragment SettingsSubscriptionPaywallModal_viewer on Viewer {
...WebSubscriptionPaywall_viewer
}
fragment SettingsSubscriptionSectionNonSubscriberView_viewer on Viewer {
...SettingsSubscriptionPaywallModal_viewer
}
fragment SettingsSubscriptionSectionSubscriberView_viewer on Viewer {
subscription {
isActive
expiresTime
purchaseType
isAnnualSubscription
willCancelAtPeriodEnd
id
}
}
fragment SettingsSubscriptionSection_viewer on Viewer {
availableBots {
displayName
messageLimit {
canSend
numMessagesRemaining
resetTime
dailyBalance
dailyLimit
monthlyBalance
monthlyLimit
monthlyBalanceRefreshTime
shouldShowRemainingMessageCount
}
id
}
subscription {
isActive
id
}
isEligibleForWebSubscriptions
...SettingsSubscriptionSectionNonSubscriberView_viewer
...SettingsSubscriptionSectionSubscriberView_viewer
...WebSubscriptionSuccessMessage_viewer
}
fragment SubscriptionMessageLimitExplanation_viewer on Viewer {
availableBots {
displayName
messageLimit {
monthlyLimit
}
id
}
}
fragment WebSubscriptionPaywall_viewer on Viewer {
...SubscriptionMessageLimitExplanation_viewer
webSubscriptionPriceInfo {
monthlyPrice
yearlyPrice
yearlyPricePerMonth
yearlyPercentageSavings
id
}
}
fragment WebSubscriptionSuccessMessage_viewer on Viewer {
subscription {
isActive
expiresTime
willCancelAtPeriodEnd
id
}
}

View File

@@ -1,4 +1,4 @@
subscription viewerStateUpdated {
subscription subscriptions_viewerStateUpdated_Subscription {
viewerStateUpdated {
id
...ChatPageBotSwitcher_viewer
@@ -11,9 +11,19 @@ fragment BotHeader_bot on Bot {
dailyLimit
}
...BotImage_bot
...BotLink_bot
...IdAnnotation_node
...botHelpers_useViewerCanAccessPrivateBot
...botHelpers_useDeletion_bot
}
fragment BotImage_bot on Bot {
displayName
...botHelpers_useDeletion_bot
...BotImage_useProfileImage_bot
}
fragment BotImage_useProfileImage_bot on Bot {
image {
__typename
... on LocalBotImage {
@@ -23,7 +33,7 @@ fragment BotImage_bot on Bot {
url
}
}
displayName
...botHelpers_useDeletion_bot
}
fragment BotLink_bot on Bot {
@@ -33,11 +43,21 @@ fragment BotLink_bot on Bot {
fragment ChatPageBotSwitcher_viewer on Viewer {
availableBots {
id
messageLimit {
dailyLimit
}
...BotLink_bot
handle
...BotHeader_bot
}
allowUserCreatedBots: booleanGate(gateName: "enable_user_created_bots")
}
fragment IdAnnotation_node on Node {
__isNode: __typename
id
}
fragment botHelpers_useDeletion_bot on Bot {
deletionState
}
fragment botHelpers_useViewerCanAccessPrivateBot on Bot {
isPrivateBot
viewerIsCreator
}

8488
public/css/fontawesome.css vendored Normal file

File diff suppressed because it is too large Load Diff

24
public/css/solid.css Normal file
View File

@@ -0,0 +1,24 @@
:root,
:host {
--fa-style-family-classic: 'Font Awesome 6 Free';
--fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free';
}
@font-face {
font-family: 'Font Awesome 6 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype");
}
.fas,
.fa-solid {
font-weight: 900;
}
/*!
* Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
* Copyright 2023 Fonticons, Inc.
*/

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 0C60.7 0 32 28.7 32 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H96zM208 288h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-32-96a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM512 80c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V80zM496 192c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm16 144c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V336z"/></svg>

Before

Width:  |  Height:  |  Size: 740 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 43 43 0 96 0H384h32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32zM247.4 283.8c-3.7 3.7-6.2 4.2-7.4 4.2s-3.7-.5-7.4-4.2c-3.8-3.7-8-10-11.8-18.9c-6.2-14.5-10.8-34.3-12.2-56.9h63c-1.5 22.6-6 42.4-12.2 56.9c-3.8 8.9-8 15.2-11.8 18.9zm42.7-9.9c7.3-18.3 12-41.1 13.4-65.9h31.1c-4.7 27.9-21.4 51.7-44.5 65.9zm0-163.8c23.2 14.2 39.9 38 44.5 65.9H303.5c-1.4-24.7-6.1-47.5-13.4-65.9zM368 192a128 128 0 1 0 -256 0 128 128 0 1 0 256 0zM145.3 208h31.1c1.4 24.7 6.1 47.5 13.4 65.9c-23.2-14.2-39.9-38-44.5-65.9zm31.1-32H145.3c4.7-27.9 21.4-51.7 44.5-65.9c-7.3 18.3-12 41.1-13.4 65.9zm56.1-75.8c3.7-3.7 6.2-4.2 7.4-4.2s3.7 .5 7.4 4.2c3.8 3.7 8 10 11.8 18.9c6.2 14.5 10.8 34.3 12.2 56.9h-63c1.5-22.6 6-42.4 12.2-56.9c3.8-8.9 8-15.2 11.8-18.9z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V384c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H384 96zm0 384H352v64H96c-17.7 0-32-14.3-32-32s14.3-32 32-32zm32-240c0-8.8 7.2-16 16-16H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16zm16 48H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/></svg>

Before

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 48V487.7C0 501.1 10.9 512 24.3 512c5 0 9.9-1.5 14-4.4L192 400 345.7 507.6c4.1 2.9 9 4.4 14 4.4c13.4 0 24.3-10.9 24.3-24.3V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48z"/></svg>

Before

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>

Before

Width:  |  Height:  |  Size: 428 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>

Before

Width:  |  Height:  |  Size: 416 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z"/></svg>

Before

Width:  |  Height:  |  Size: 416 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM135 241c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l87 87 87-87c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 345c-9.4 9.4-24.6 9.4-33.9 0L135 241z"/></svg>

Before

Width:  |  Height:  |  Size: 438 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM377 271c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-87-87-87 87c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 167c9.4-9.4 24.6-9.4 33.9 0L377 271z"/></svg>

Before

Width:  |  Height:  |  Size: 442 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg>

Before

Width:  |  Height:  |  Size: 712 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M144 480C64.5 480 0 415.5 0 336c0-62.8 40.2-116.2 96.2-135.9c-.1-2.7-.2-5.4-.2-8.1c0-88.4 71.6-160 160-160c59.3 0 111 32.2 138.7 80.2C409.9 102 428.3 96 448 96c53 0 96 43 96 96c0 12.2-2.3 23.8-6.4 34.6C596 238.4 640 290.1 640 352c0 70.7-57.3 128-128 128H144zm79-217c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l39-39V392c0 13.3 10.7 24 24 24s24-10.7 24-24V257.9l39 39c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-80-80c-9.4-9.4-24.6-9.4-33.9 0l-80 80z"/></svg>

Before

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zM128 208a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm96 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg>

Before

Width:  |  Height:  |  Size: 727 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zM224 160c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H288v48c0 8.8-7.2 16-16 16H240c-8.8 0-16-7.2-16-16V272H176c-8.8 0-16-7.2-16-16V224c0-8.8 7.2-16 16-16h48V160z"/></svg>

Before

Width:  |  Height:  |  Size: 806 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M272 0H396.1c12.7 0 24.9 5.1 33.9 14.1l67.9 67.9c9 9 14.1 21.2 14.1 33.9V336c0 26.5-21.5 48-48 48H272c-26.5 0-48-21.5-48-48V48c0-26.5 21.5-48 48-48zM48 128H192v64H64V448H256V416h64v48c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48z"/></svg>

Before

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M273.8 45.8l73.7 28L271.2 103 194.8 73.7l73.7-28c1.7-.7 3.6-.7 5.3 0zM128.1 87.1V192.6c-1.2 .4-2.4 .8-3.6 1.2L34.1 228.1c-20.5 7.8-34 27.4-34 49.3V389.5c0 20.9 12.4 39.8 31.5 48.3L122 477.5c13.5 5.9 28.9 5.9 42.4 0l106.8-46.9L378 477.5c13.5 5.9 28.9 5.9 42.4 0l90.4-39.7c19.1-8.4 31.5-27.3 31.5-48.3V277.4c0-21.9-13.5-41.5-34-49.3l-90.4-34.3c-1.2-.5-2.4-.9-3.6-1.2V87.1c0-21.9-13.5-41.5-34-49.3L289.9 3.5c-12-4.6-25.3-4.6-37.4 0L162.1 37.8c-20.5 7.8-34 27.4-34 49.3zM369.1 198.2l-77.5 29.4v-84l77.5-29.7v84.3zM145.8 236.1l73.7 28-76.4 29.3L66.8 264.1l73.7-28c1.7-.7 3.6-.7 5.3 0zm17.7 192.4V333.9l77.5-29.7v90.2l-77.5 34.1zm233-192.4c1.7-.7 3.6-.7 5.3 0l73.7 28-76.4 29.3-76.4-29.3 73.7-28zm96.1 160.3l-73 32.1V333.9l77.5-29.7v85.3c0 3-1.8 5.7-4.5 6.9z"/></svg>

Before

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M252.3 11.7c-15.6-15.6-40.9-15.6-56.6 0l-184 184c-15.6 15.6-15.6 40.9 0 56.6l184 184c15.6 15.6 40.9 15.6 56.6 0l184-184c15.6-15.6 15.6-40.9 0-56.6l-184-184zM248 224c0 13.3-10.7 24-24 24s-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24zM96 248c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24zm128 80c13.3 0 24 10.7 24 24s-10.7 24-24 24s-24-10.7-24-24s10.7-24 24-24zm128-80c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24zM224 72c13.3 0 24 10.7 24 24s-10.7 24-24 24s-24-10.7-24-24s10.7-24 24-24zm96 392c0 26.5 21.5 48 48 48H592c26.5 0 48-21.5 48-48V240c0-26.5-21.5-48-48-48H472.5c13.4 26.9 8.8 60.5-13.6 82.9L320 413.8V464zm160-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg>

Before

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

Before

Width:  |  Height:  |  Size: 632 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM216 408c0 13.3-10.7 24-24 24s-24-10.7-24-24V305.9l-31 31c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l72-72c9.4-9.4 24.6-9.4 33.9 0l72 72c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-31-31V408z"/></svg>

Before

Width:  |  Height:  |  Size: 567 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V288H216c-13.3 0-24 10.7-24 24s10.7 24 24 24H384V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM384 336V288H494.1l-39-39c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l80 80c9.4 9.4 9.4 24.6 0 33.9l-80 80c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l39-39H384zm0-208H256V0L384 128z"/></svg>

Before

Width:  |  Height:  |  Size: 584 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM64 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm152 32c5.3 0 10.2 2.6 13.2 6.9l88 128c3.4 4.9 3.7 11.3 1 16.5s-8.2 8.6-14.2 8.6H216 176 128 80c-5.8 0-11.1-3.1-13.9-8.1s-2.8-11.2 .2-16.1l48-80c2.9-4.8 8.1-7.8 13.7-7.8s10.8 2.9 13.7 7.8l12.8 21.4 48.3-70.2c3-4.3 7.9-6.9 13.2-6.9z"/></svg>

Before

Width:  |  Height:  |  Size: 653 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M254 52.8C249.3 40.3 237.3 32 224 32s-25.3 8.3-30 20.8L57.8 416H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-1.8l18-48H303.8l18 48H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H390.2L254 52.8zM279.8 304H168.2L224 155.1 279.8 304z"/></svg>

Before

Width:  |  Height:  |  Size: 544 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M481.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-30.9 28.1c-7.7 7.1-11.4 17.5-10.9 27.9c.1 2.9 .2 5.8 .2 8.8s-.1 5.9-.2 8.8c-.5 10.5 3.1 20.9 10.9 27.9l30.9 28.1c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-39.7-12.6c-10-3.2-20.8-1.1-29.7 4.6c-4.9 3.1-9.9 6.1-15.1 8.7c-9.3 4.8-16.5 13.2-18.8 23.4l-8.9 40.7c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-8.9-40.7c-2.2-10.2-9.5-18.6-18.8-23.4c-5.2-2.7-10.2-5.6-15.1-8.7c-8.8-5.7-19.7-7.8-29.7-4.6L69.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l30.9-28.1c7.7-7.1 11.4-17.5 10.9-27.9c-.1-2.9-.2-5.8-.2-8.8s.1-5.9 .2-8.8c.5-10.5-3.1-20.9-10.9-27.9L8.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l39.7 12.6c10 3.2 20.8 1.1 29.7-4.6c4.9-3.1 9.9-6.1 15.1-8.7c9.3-4.8 16.5-13.2 18.8-23.4l8.9-40.7c2-9.1 9-16.3 18.2-17.8C213.3 1.2 227.5 0 242 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l8.9 40.7c2.2 10.2 9.4 18.6 18.8 23.4c5.2 2.7 10.2 5.6 15.1 8.7c8.8 5.7 19.7 7.7 29.7 4.6l39.7-12.6c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM242 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M528 160V416c0 8.8-7.2 16-16 16H320c0-44.2-35.8-80-80-80H176c-44.2 0-80 35.8-80 80H64c-8.8 0-16-7.2-16-16V160H528zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM272 256a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zm104-48c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376z"/></svg>

Before

Width:  |  Height:  |  Size: 684 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM323.8 202.5c-4.5-6.6-11.9-10.5-19.8-10.5s-15.4 3.9-19.8 10.5l-87 127.6L170.7 297c-4.6-5.7-11.5-9-18.7-9s-14.2 3.3-18.7 9l-64 80c-5.8 7.2-6.9 17.1-2.9 25.4s12.4 13.6 21.6 13.6h96 32H424c8.9 0 17.1-4.9 21.2-12.8s3.6-17.4-1.4-24.7l-120-176zM112 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z"/></svg>

Before

Width:  |  Height:  |  Size: 634 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M177.5 414c-8.8 3.8-19 2-26-4.6l-144-136C2.7 268.9 0 262.6 0 256s2.7-12.9 7.5-17.4l144-136c7-6.6 17.2-8.4 26-4.6s14.5 12.5 14.5 22l0 72 288 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-288 0 0 72c0 9.6-5.7 18.2-14.5 22z"/></svg>

Before

Width:  |  Height:  |  Size: 472 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 144a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zM64 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48-208a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z"/></svg>

Before

Width:  |  Height:  |  Size: 637 B

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="translate(80,50)">
<g transform="rotate(0)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="1">
<animateTransform attributeName="transform" type="scale" begin="-0.875s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.875s"></animate>
</circle>
</g>
</g><g transform="translate(71.21320343559643,71.21320343559643)">
<g transform="rotate(45)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.875">
<animateTransform attributeName="transform" type="scale" begin="-0.75s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.75s"></animate>
</circle>
</g>
</g><g transform="translate(50,80)">
<g transform="rotate(90)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.75">
<animateTransform attributeName="transform" type="scale" begin="-0.625s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.625s"></animate>
</circle>
</g>
</g><g transform="translate(28.786796564403577,71.21320343559643)">
<g transform="rotate(135)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.625">
<animateTransform attributeName="transform" type="scale" begin="-0.5s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.5s"></animate>
</circle>
</g>
</g><g transform="translate(20,50.00000000000001)">
<g transform="rotate(180)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.5">
<animateTransform attributeName="transform" type="scale" begin="-0.375s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.375s"></animate>
</circle>
</g>
</g><g transform="translate(28.78679656440357,28.786796564403577)">
<g transform="rotate(225)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.375">
<animateTransform attributeName="transform" type="scale" begin="-0.25s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.25s"></animate>
</circle>
</g>
</g><g transform="translate(49.99999999999999,20)">
<g transform="rotate(270)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.25">
<animateTransform attributeName="transform" type="scale" begin="-0.125s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.125s"></animate>
</circle>
</g>
</g><g transform="translate(71.21320343559643,28.78679656440357)">
<g transform="rotate(315)">
<circle cx="0" cy="0" r="6" fill="#dedede" fill-opacity="0.125">
<animateTransform attributeName="transform" type="scale" begin="0s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="0s"></animate>
</circle>
</g>
</g>
<!-- [ldio] generated by https://loading.io/ --></svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle cx="50" cy="50" fill="none" stroke="#dedede" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138">
<animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>
</circle>
<!-- [ldio] generated by https://loading.io/ --></svg>

Before

Width:  |  Height:  |  Size: 639 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M352 144c0-44.2 35.8-80 80-80s80 35.8 80 80v48c0 17.7 14.3 32 32 32s32-14.3 32-32V144C576 64.5 511.5 0 432 0S288 64.5 288 144v48H64c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V256c0-35.3-28.7-64-64-64H352V144z"/></svg>

Before

Width:  |  Height:  |  Size: 485 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"/></svg>

Before

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 861 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M416 256c0 17.7-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg>

Before

Width:  |  Height:  |  Size: 348 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M45.6 32C20.4 32 0 52.4 0 77.6V434.4C0 459.6 20.4 480 45.6 480c5.1 0 10-.8 14.7-2.4C74.6 472.8 177.6 440 320 440s245.4 32.8 259.6 37.6c4.7 1.6 9.7 2.4 14.7 2.4c25.2 0 45.6-20.4 45.6-45.6V77.6C640 52.4 619.6 32 594.4 32c-5 0-10 .8-14.7 2.4C565.4 39.2 462.4 72 320 72S74.6 39.2 60.4 34.4C55.6 32.8 50.7 32 45.6 32zM96 160a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm272 0c7.9 0 15.4 3.9 19.8 10.5L512.3 353c5.4 8 5.6 18.4 .4 26.5s-14.7 12.3-24.2 10.7C442.7 382.4 385.2 376 320 376c-65.6 0-123.4 6.5-169.3 14.4c-9.8 1.7-19.7-2.9-24.7-11.5s-4.3-19.4 1.9-27.2L197.3 265c4.6-5.7 11.4-9 18.7-9s14.2 3.3 18.7 9l26.4 33.1 87-127.6c4.5-6.6 11.9-10.5 19.8-10.5z"/></svg>

Before

Width:  |  Height:  |  Size: 890 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M410.3 231l11.3-11.3-33.9-33.9-62.1-62.1L291.7 89.8l-11.3 11.3-22.6 22.6L58.6 322.9c-10.4 10.4-18 23.3-22.2 37.4L1 480.7c-2.5 8.4-.2 17.5 6.1 23.7s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L387.7 253.7 410.3 231zM160 399.4l-9.1 22.7c-4 3.1-8.5 5.4-13.3 6.9L59.4 452l23-78.1c1.4-4.9 3.8-9.4 6.9-13.3l22.7-9.1v32c0 8.8 7.2 16 16 16h32zM362.7 18.7L348.3 33.2 325.7 55.8 314.3 67.1l33.9 33.9 62.1 62.1 33.9 33.9 11.3-11.3 22.6-22.6 14.5-14.5c25-25 25-65.5 0-90.5L453.3 18.7c-25-25-65.5-25-90.5 0zm-47.4 168l-144 144c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l144-144c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z"/></svg>

Before

Width:  |  Height:  |  Size: 863 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z"/></svg>

Before

Width:  |  Height:  |  Size: 783 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8C297 398 352 333.4 352 256V224c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z"/></svg>

Before

Width:  |  Height:  |  Size: 549 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M240 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H176V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H240V80z"/></svg>

Before

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 224c0 17.7 14.3 32 32 32s32-14.3 32-32c0-53 43-96 96-96H320v32c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-9.2-9.2-22.9-11.9-34.9-6.9S320 19.1 320 32V64H160C71.6 64 0 135.6 0 224zm512 64c0-17.7-14.3-32-32-32s-32 14.3-32 32c0 53-43 96-96 96H192V352c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V448H352c88.4 0 160-71.6 160-160z"/></svg>

Before

Width:  |  Height:  |  Size: 705 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M256 192l-39.5-39.5c4.9-12.6 7.5-26.2 7.5-40.5C224 50.1 173.9 0 112 0S0 50.1 0 112s50.1 112 112 112c14.3 0 27.9-2.7 40.5-7.5L192 256l-39.5 39.5c-12.6-4.9-26.2-7.5-40.5-7.5C50.1 288 0 338.1 0 400s50.1 112 112 112s112-50.1 112-112c0-14.3-2.7-27.9-7.5-40.5L499.2 76.8c7.1-7.1 7.1-18.5 0-25.6c-28.3-28.3-74.1-28.3-102.4 0L256 192zm22.6 150.6L396.8 460.8c28.3 28.3 74.1 28.3 102.4 0c7.1-7.1 7.1-18.5 0-25.6L342.6 278.6l-64 64zM64 112a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm48 240a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"/></svg>

Before

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 416c0-17.7 14.3-32 32-32l54.7 0c12.3-28.3 40.5-48 73.3-48s61 19.7 73.3 48L480 384c17.7 0 32 14.3 32 32s-14.3 32-32 32l-246.7 0c-12.3 28.3-40.5 48-73.3 48s-61-19.7-73.3-48L32 448c-17.7 0-32-14.3-32-32zm192 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM384 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm-32-80c32.8 0 61 19.7 73.3 48l54.7 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-54.7 0c-12.3 28.3-40.5 48-73.3 48s-61-19.7-73.3-48L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l246.7 0c12.3-28.3 40.5-48 73.3-48zM192 64a32 32 0 1 0 0 64 32 32 0 1 0 0-64zm73.3 0L480 64c17.7 0 32 14.3 32 32s-14.3 32-32 32l-214.7 0c-12.3 28.3-40.5 48-73.3 48s-61-19.7-73.3-48L32 128C14.3 128 0 113.7 0 96S14.3 64 32 64l86.7 0C131 35.7 159.2 16 192 16s61 19.7 73.3 48z"/></svg>

Before

Width:  |  Height:  |  Size: 977 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg>

Before

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16z"/></svg>

Before

Width:  |  Height:  |  Size: 735 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM625 177L497 305c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L591 143c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>

Before

Width:  |  Height:  |  Size: 569 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM609.3 512H471.4c5.4-9.4 8.6-20.3 8.6-32v-8c0-60.7-27.1-115.2-69.8-151.8c2.4-.1 4.7-.2 7.1-.2h61.4C567.8 320 640 392.2 640 481.3c0 17-13.8 30.7-30.7 30.7zM432 256c-31 0-59-12.6-79.3-32.9C372.4 196.5 384 163.6 384 128c0-26.8-6.6-52.1-18.3-74.3C384.3 40.1 407.2 32 432 32c61.9 0 112 50.1 112 112s-50.1 112-112 112z"/></svg>

Before

Width:  |  Height:  |  Size: 737 B

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 640 512"
version="1.1"
id="svg12"
sodipodi:docname="user-group-solidplus.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs16" />
<sodipodi:namedview
id="namedview14"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="0.10144043"
inkscape:cx="-872.43321"
inkscape:cy="1044.9483"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" />
<!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM609.3 512H471.4c5.4-9.4 8.6-20.3 8.6-32v-8c0-60.7-27.1-115.2-69.8-151.8c2.4-.1 4.7-.2 7.1-.2h61.4C567.8 320 640 392.2 640 481.3c0 17-13.8 30.7-30.7 30.7zM432 256c-31 0-59-12.6-79.3-32.9C372.4 196.5 384 163.6 384 128c0-26.8-6.6-52.1-18.3-74.3C384.3 40.1 407.2 32 432 32c61.9 0 112 50.1 112 112s-50.1 112-112 112z"
id="path10" />
<path
id="rect1922"
style="fill:#000000;stroke:#ffffff;stroke-width:50;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 519.31323,191.69297 v 65.34961 h -65.34961 v 47.05274 h 65.34961 v 65.3496 h 47.05274 v -65.3496 h 65.34961 v -47.05274 h -65.34961 v -65.34961 z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H322.8c-3.1-8.8-3.7-18.4-1.4-27.8l15-60.1c2.8-11.3 8.6-21.5 16.8-29.7l40.3-40.3c-32.1-31-75.7-50.1-123.9-50.1H178.3zm435.5-68.3c-15.6-15.6-40.9-15.6-56.6 0l-29.4 29.4 71 71 29.4-29.4c15.6-15.6 15.6-40.9 0-56.6l-14.4-14.4zM375.9 417c-4.1 4.1-7 9.2-8.4 14.9l-15 60.1c-1.4 5.5 .2 11.2 4.2 15.2s9.7 5.6 15.2 4.2l60.1-15c5.6-1.4 10.8-4.3 14.9-8.4L576.1 358.7l-71-71L375.9 417z"/></svg>

Before

Width:  |  Height:  |  Size: 728 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM504 312V248H440c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V136c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H552v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z"/></svg>

Before

Width:  |  Height:  |  Size: 605 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L353.3 251.6C407.9 237 448 187.2 448 128C448 57.3 390.7 0 320 0C250.2 0 193.5 55.8 192 125.2L38.8 5.1zM264.3 304.3C170.5 309.4 96 387.2 96 482.3c0 16.4 13.3 29.7 29.7 29.7H514.3c3.9 0 7.6-.7 11-2.1l-261-205.6z"/></svg>

Before

Width:  |  Height:  |  Size: 564 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg>

Before

Width:  |  Height:  |  Size: 427 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M54.2 202.9C123.2 136.7 216.8 96 320 96s196.8 40.7 265.8 106.9c12.8 12.2 33 11.8 45.2-.9s11.8-33-.9-45.2C549.7 79.5 440.4 32 320 32S90.3 79.5 9.8 156.7C-2.9 169-3.3 189.2 8.9 202s32.5 13.2 45.2 .9zM320 256c56.8 0 108.6 21.1 148.2 56c13.3 11.7 33.5 10.4 45.2-2.8s10.4-33.5-2.8-45.2C459.8 219.2 393 192 320 192s-139.8 27.2-190.5 72c-13.3 11.7-14.5 31.9-2.8 45.2s31.9 14.5 45.2 2.8c39.5-34.9 91.3-56 148.2-56zm64 160a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z"/></svg>

Before

Width:  |  Height:  |  Size: 699 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>

Before

Width:  |  Height:  |  Size: 527 B

File diff suppressed because it is too large Load Diff

View File

@@ -18,8 +18,14 @@
<h2>Advanced Formatting</h2>
<p>
The settings provided in this section allow for a more control over the prompt building strategy.
Most specifics of the prompt building depend on whether a Pygmalion model is selected or special formatting is force enabled.
The core differences between the formatting schemas are listed below.
</p>
<h3>For <u>Pygmalion</u> models</h3>
<h3>Custom Chat Separator</h3>
<p>
Overrides the default separators controlled by "Disable example chats formatting" and "Disable chat start formatting" options (see below).
</p>
<h3>For <u>Pygmalion</u> formatting</h3>
<h4>Disable description formatting</h4>
<p>
<code><b>NAME's Persona: </b></code> won't be prepended to the content your character's Description box.
@@ -32,11 +38,21 @@
<p>
<code><b>Personality: </b></code> won't be prepended to the content your character's Personality box.
</p>
<h4>Disable example chats formatting</h4>
<p>
<code>&lt;START&gt;</code> is not added at the beginning of each example message block.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Disable chat start formatting</h4>
<p>
<code>&lt;START&gt;</code> is not added before the between the character card and the chat log.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Always add character's name to prompt</h4>
<p>
Doesn't do anything (Included in Pygmalion formatting).
</p>
<h3>For <u>non-Pygmalion</u> models</h3>
<h3>For <u>non-Pygmalion</u> formatting</h3>
<h4>Disable description formatting</h4>
<p>
Has no effect.
@@ -49,6 +65,16 @@
<p>
<code><b>NAME's personality: </b></code> won't be prepended to the content your character's Personality box.
</p>
<h4>Disable example chats formatting</h4>
<p>
<code>This is how <b>Character</b> should talk</code> is not added at the beginning of each example message block.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Disable chat start formatting</h4>
<p>
<code>Then the roleplay chat between <b>User</b> and <b>Character</b> begins</code> is not added before the between the character card and the chat log.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Always add character's name to prompt</h4>
<p>
Appends character's name to the prompt to force model to complete the message as a character:

View File

@@ -0,0 +1,33 @@
<html>
<head>
<title>Message Sound</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap"
rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Message Sound</h2>
<p>To play your own custom sound on receiving a new message from bot, replace the following MP3 file in your TavernAI folder:</p>
<code>
public/sounds/message.mp3
</code>
<p>
Plays at 80% volume.
</p>
<p>
If "Background Sound Only" option is enabled, the sound plays only if TavernAI window is <b>unfocused</b>.
</p>
</div>
</div>
</body>
</html>

View File

@@ -16,11 +16,14 @@
<div id="main">
<div id="content">
<h2>Multigen</h2>
<p>TavernAI tries to create longer responses by chaining the generation using smaller batches.</p>
<p>TavernAI tries to create faster and longer responses by chaining the generation using smaller batches.</p>
<h3>Default settings:</h3>
<p>First batch = 50 tokens</p>
<p>Next batches = 30 tokens</p>
<h3>Algorithm:</h3>
<p>1. If amount of generation is more than 50 tokens, then generate first 50 tokens.</p>
<p>2. Generate by 30 tokens until one of the stopping conditions is reached.</p>
<p>3. Append the generated batch to the next cycle's prompt.</p>
<p>1. Generate the first batch (if amount of generation setting is more than batch length).</p>
<p>2. Generate next batch of tokens until one of the stopping conditions is reached.</p>
<p>3. Append the generated text to the next cycle's prompt.</p>
<h3>Stopping conditions:</h3>
<p>1. Generated enough text.</p>
<p>2. Character starts speaking for You.</p>

View File

@@ -0,0 +1,28 @@
<html>
<head>
<title>Gradio Streaming Function ID</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap"
rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<p>
To use streaming with Text Generation Web UI, a Gradio function index needs to be provided.
It is impossible to be determined programmatically and should be typed in manually.
If the streaming doesn't work with the default value, get the most recent function ID here:
<a href="https://github.com/oobabooga/text-generation-webui/blob/main/api-example-stream.py#L15">GRADIO_FN</a>
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,68 @@
<html>
<head>
<title>Character Tokens</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Character Tokens</h2>
<p><b>TLDR: If you're working with an AI model with a 2048 context token limit, your 1000 token character definition is cutting the AI's 'memory' in half.</b></p>
<p>To put this in perspective, a decent response from a good AI can easily be around 200-300 tokens. In this case, the AI would only be able to 'remember' about 3 exchanges worth of chat history.</p>
<hr>
<h3>Why did my character's token counter turn red?</h3>
<p>When we see your character has over 1000 tokens in its definitions, we highlight it for you because this can lower the AI's capabilities to provide an enjoyable conversation.</p>
<h3>What happens if my Character has too many tokens?</h3>
<p>Don't Worry - it won't break anything. At worst, if the Character's permanent tokens are too large, it simply means there will be less room left in the context for other things (see below).</p>
<p>The only negative side effect this can have is the AI will have less 'memory', as it will have less chat history available to process.</p>
<p>This is because every AI model has a limit to the amount of context it can process at one time.</p>
<h3>'Context'?</h3>
<p>This is the information that gets sent to the AI each time you ask it to generate a response:</p>
<ul>
<li>Character definitions</li>
<li>Chat history</li>
<li>Author's Notes</li>
<li>Special Format strings</li>
<li>[bracket commands]</li>
</ul>
<p>SillyTavern automatically calculates the best way to allocate the available context tokens before sending the information to the AI model.</p>
<h3>What are a Character's 'Permanent Tokens'?</h3>
<p>These will always be sent to the AI with every generation request:</p>
<ul>
<li>Character Name (keep the name short! Sent at the start of EVERY Character message)</li>
<li>Character Description Box</li>
<li>Character Personality Box</li>
<li>Scenario Box</li>
</ul>
<h3>What parts of a Character's Definitions are NOT permanent?</h3>
<ul>
<li>The first message box - only sent once at the start of the chat.</li>
<li>Example messages box - only kept until chat history fills up the context (optionally these can be forced to be kept in context)</li>
</ul>
<h3>Popular AI Model Context Token Limits</h3>
<ul>
<li>Older models below 6B parameters - 1024</li>
<li>Pygmalion 6B - 2048</li>
<li>Poe.com (Claude-instant or ChatGPT) - 2048</li>
<li>OpenAI ChatGPT - 4000-ish?</li>
<li>OpenAI GPT-4 - 8000?</li>
</ul>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
esversion: 6
import { encode } from "../scripts/gpt-2-3-tokenizer/mod.js";
import {
Generate,
@@ -11,6 +10,8 @@ import {
nai_settings,
api_server_textgenerationwebui,
is_send_press,
getTokenCount,
max_context,
} from "../script.js";
@@ -59,11 +60,46 @@ const observer = new MutationObserver(function (mutations) {
} else if (mutation.target.parentNode === SelectedCharacterTab) {
setTimeout(RA_CountCharTokens, 200);
}
});
});
observer.observe(document.documentElement, observerConfig);
/**
* Wait for an element before resolving a promise
* @param {String} querySelector - Selector of element to wait for
* @param {Integer} timeout - Milliseconds to wait before timing out, or 0 for no timeout
*/
function waitForElement(querySelector, timeout) {
return new Promise((resolve, reject) => {
var timer = false;
if (document.querySelectorAll(querySelector).length) return resolve();
const observer = new MutationObserver(() => {
if (document.querySelectorAll(querySelector).length) {
observer.disconnect();
if (timer !== false) clearTimeout(timer);
return resolve();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
if (timeout) timer = setTimeout(() => {
observer.disconnect();
reject();
}, timeout);
});
}
waitForElement("#expression-image", 10000).then(function () {
dragElement(document.getElementById("expression-holder"));
}).catch(() => {
console.log("expression holder not loaded yet");
});
//RossAscends: Added function to format dates used in files and chat timestamps to a humanized format.
//Mostly I wanted this to be for file names, but couldn't figure out exactly where the filename save code was as everything seemed to be connected.
@@ -121,62 +157,76 @@ function RA_CountCharTokens() {
});
//count total tokens, including those that will be removed from context once chat history is long
count_tokens = encode(JSON.stringify(
count_tokens = getTokenCount(JSON.stringify(
create_save_name +
create_save_description +
create_save_personality +
create_save_scenario +
create_save_first_message +
create_save_mes_example
)).length;
));
//count permanent tokens that will never get flushed out of context
perm_tokens = encode(JSON.stringify(
perm_tokens = getTokenCount(JSON.stringify(
create_save_name +
create_save_description +
create_save_personality +
create_save_scenario
)).length;
));
} else {
if (this_chid !== undefined && this_chid !== "invalid-safety-id") { // if we are counting a valid pre-saved char
//same as above, all tokens including temporary ones
count_tokens = encode(
count_tokens = getTokenCount(
JSON.stringify(
characters[this_chid].description +
characters[this_chid].personality +
characters[this_chid].scenario +
characters[this_chid].first_mes +
characters[this_chid].mes_example
)).length;
));
//permanent tokens count
perm_tokens = encode(
perm_tokens = getTokenCount(
JSON.stringify(
characters[this_chid].name +
characters[this_chid].description +
characters[this_chid].personality +
characters[this_chid].scenario +
(power_user.pin_examples ? characters[this_chid].mes_example : '') // add examples to permanent if they are pinned
)).length;
));
} else { console.log("RA_TC -- no valid char found, closing."); } // if neither, probably safety char or some error in loading
}
// display the counted tokens
if (count_tokens < 1024 && perm_tokens < 1024) {
$("#result_info").html(count_tokens + " Tokens (" + perm_tokens + " Permanent Tokens)"); //display normal if both counts are under 1024
} else { $("#result_info").html("<font color=red>" + count_tokens + " Tokens (" + perm_tokens + " Permanent Tokens)(TOO MANY)</font>"); } //warn if either are over 1024
} else {
$("#result_info").html(`
<span class="neutral_warning">${count_tokens}</span>&nbsp;Tokens (<span class="neutral_warning">${perm_tokens}</span><span>&nbsp;Permanent Tokens)
<br>
<div id="chartokenwarning" class="menu_button whitespacenowrap"><a href="/notes/token-limits.html" target="_blank">Learn More About Token 'Limits'</a></div>`);
} //warn if either are over 1024
}
//Auto Load Last Charcter -- (fires when active_character is defined and auto_load_chat is true)
async function RA_autoloadchat() {
if (document.getElementById('CharID0') !== null) {
//console.log('char list loaded! clicking activeChar');
var CharToAutoLoad = document.getElementById('CharID' + LoadLocal('ActiveChar'));
//console.log(CharToAutoLoad);
let autoLoadGroup = document.querySelector(`.group_select[grid="${LoadLocal('ActiveGroup')}"]`);
//console.log(autoLoadGroup);
if (CharToAutoLoad != null) {
// console.log('--ALC - clicking character');
CharToAutoLoad.click();
CharToAutoLoad.click();
}
else if (autoLoadGroup != null) {
//console.log('--ALC - clicking group');
autoLoadGroup.click();
autoLoadGroup.click();
}
else {
@@ -203,22 +253,21 @@ function RA_checkOnlineStatus() {
$("#send_textarea").attr("placeholder", "Not connected to API!"); //Input bar placeholder tells users they are not connected
$("#send_form").addClass('no-connection'); //entire input form area is red when not connected
$("#send_but").css("display", "none"); //send button is hidden when not connected;
$("#API-status-top").addClass("redOverlayGlow");
$("#API-status-top").removeClass("fa-plug");
$("#API-status-top").addClass("fa-plug-circle-exclamation redOverlayGlow");
connection_made = false;
} else {
if (online_status !== undefined && online_status !== "no_connection") {
$("#send_textarea").attr("placeholder", "Type a message..."); //on connect, placeholder tells user to type message
const formColor = power_user.fast_ui_mode ? "var(--black90a)" : "var(--black60a)";
/* console.log("RA-AC -- connected, coloring input as " + formColor); */
$('#send_form').removeClass("no-connection");
$("#send_form").css("background-color", formColor); //on connect, form BG changes to transprent black
$("#API-status-top").removeClass("redOverlayGlow");
$("#API-status-top").removeClass("fa-plug-circle-exclamation redOverlayGlow");
$("#API-status-top").addClass("fa-plug");
connection_made = true;
retry_delay = 100;
RA_AC_retries = 1;
if (!is_send_press && !(selected_group && is_group_generating)) {
$("#send_but").css("display", "inline"); //on connect, send button shows
$("#send_but").css("display", "flex"); //on connect, send button shows
}
}
}
@@ -286,10 +335,10 @@ function OpenNavPanels() {
console.log("RA -- clicking right nav to open");
$("#rightNavDrawerIcon").click();
} else {
console.log('didnt see reason to open right nav on load: ' +
LoadLocalBool("NavLockOn")
+ ' nav open pref' +
LoadLocalBool("NavOpened" == true));
/* console.log('didnt see reason to open right nav on load: R-nav locked? ' +
LoadLocalBool("NavLockOn")
+ ' R-nav was open before? ' +
LoadLocalBool("NavOpened" == true)); */
}
//auto-open L nav if locked and previously open
@@ -298,14 +347,162 @@ function OpenNavPanels() {
console.log("RA -- clicking left nav to open");
$("#leftNavDrawerIcon").click();
} else {
console.log('didnt see reason to open left nav on load: ' +
LoadLocalBool("LNavLockOn")
+ ' L-nav open pref' +
LoadLocalBool("LNavOpened" == true));
/* console.log('didnt see reason to open left nav on load: L-Nav Locked? ' +
LoadLocalBool("LNavLockOn")
+ ' L-nav was open before? ' +
LoadLocalBool("LNavOpened" == true)); */
}
}
// Make the DIV element draggable:
dragElement(document.getElementById("sheld"));
dragElement(document.getElementById("left-nav-panel"));
dragElement(document.getElementById("right-nav-panel"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) { //ex: id="sheldheader"
// if present, the header is where you move the DIV from, but this overrides everything else:
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV, b:
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX; //mouse X at click
pos4 = e.clientY; //mouse Y at click
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
//disable scrollbars when dragging to prevent jitter
$("body").css("overflow", "hidden");
//get window size
let winWidth = window.innerWidth;
let winHeight = window.innerHeight;
//get necessary data for calculating element footprint
let draggableHeight = parseInt(getComputedStyle(elmnt).getPropertyValue('height').slice(0, -2));
let draggableWidth = parseInt(getComputedStyle(elmnt).getPropertyValue('width').slice(0, -2));
let draggableTop = parseInt(getComputedStyle(elmnt).getPropertyValue('top').slice(0, -2));
let draggableLeft = parseInt(getComputedStyle(elmnt).getPropertyValue('left').slice(0, -2));
let sheldWidth = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--sheldWidth').slice(0, -2));
let topBarFirstX = (winWidth - sheldWidth) / 2;
let topBarLastX = topBarFirstX + sheldWidth;
//set the lowest and most-right pixel the element touches
let maxX = (draggableWidth + draggableLeft);
let maxY = (draggableHeight + draggableTop);
// calculate the new cursor position:
e = e || window.event;
e.preventDefault();
pos1 = pos3 - e.clientX; //X change amt
pos2 = pos4 - e.clientY; //Y change amt
pos3 = e.clientX; //new mouse X
pos4 = e.clientY; //new mouse Y
//fix over/underflows:
setTimeout(function () {
if (elmnt.offsetTop < 40) {
/* console.log('6'); */
if (maxX > topBarFirstX && maxX < topBarLastX) {
/* console.log('maxX inside topBar!'); */
elmnt.style.top = "42px";
}
if (elmnt.offsetLeft < topBarLastX && elmnt.offsetLeft > topBarFirstX) {
/* console.log('offsetLeft inside TopBar!'); */
elmnt.style.top = "42px";
}
}
if (elmnt.offsetTop - pos2 <= 0) {
/* console.log('1'); */
//prevent going out of window top + 42px barrier for TopBar (can hide grabber)
elmnt.style.top = "0px";
}
if (elmnt.offsetLeft - pos1 <= 0) {
/* console.log('2'); */
//prevent moving out of window left
elmnt.style.left = "0px";
}
if (maxX >= winWidth) {
/* console.log('3'); */
//bounce off right
elmnt.style.left = elmnt.offsetLeft - 10 + "px";
}
if (maxY >= winHeight) {
/* console.log('4'); */
//bounce off bottom
elmnt.style.top = elmnt.offsetTop - 10 + "px";
if (elmnt.offsetTop - pos2 <= 40) {
/* console.log('5'); */
//prevent going out of window top + 42px barrier for TopBar (can hide grabber)
/* console.log('caught Y bounce to <40Y top'); */
elmnt.style.top = "20px";
}
}
// if no problems, set element's new position
/* console.log('7'); */
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
$(elmnt).css("bottom", "unset");
$(elmnt).css("right", "unset");
/* console.log(`
offsetLeft: ${elmnt.offsetLeft}, offsetTop: ${elmnt.offsetTop}
winWidth: ${winWidth}, winHeight: ${winHeight}
sheldWidth: ${sheldWidth}
X: ${elmnt.style.left}
Y: ${elmnt.style.top}
MaxX: ${maxX}, MaxY: ${maxY}
Topbar 1st X: ${((winWidth - sheldWidth) / 2)}
TopBar lastX: ${((winWidth - sheldWidth) / 2) + sheldWidth}
`); */
}, 50)
/* console.log("left/top: " + (elmnt.offsetLeft - pos1) + "/" + (elmnt.offsetTop - pos2) +
", win: " + winWidth + "/" + winHeight +
", max X / Y: " + maxX + " / " + maxY); */
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
//revert scrolling to normal after drag to allow recovery of vastly misplaced elements
$("body").css("overflow", "auto");
}
}
// ---------------------------------------------------
$("document").ready(function () {
// initial status check
setTimeout(RA_checkOnlineStatus, 100);
@@ -391,6 +588,14 @@ $("document").ready(function () {
} else { SaveLocal('LNavOpened', 'false'); }
});
var chatbarInFocus = false;
$('#send_textarea').focus(function () {
chatbarInFocus = true;
});
$('#send_textarea').blur(function () {
chatbarInFocus = false;
});
@@ -447,37 +652,33 @@ $("document").ready(function () {
}
});
function isInputElementInFocus() {
return $(document.activeElement).is(":input");
//return $(document.activeElement).is(":input");
var focused = $(':focus');
if (focused.is('input') || focused.is('textarea')) {
if (focused.attr('id') === 'send_textarea') {
return false;
}
return true;
}
return false;
}
//Additional hotkeys CTRL+ENTER and CTRL+UPARROW
document.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.key == "Enter") {
// Ctrl+Enter for Regeneration Last Response
if (is_send_press == false) {
$('#option_regenerate').click();
$('#options').hide();
//setTimeout(function () { $('#chat').click(); }, 50) //needed to remove the options menu popping up..
//Generate("regenerate");
}
}
if (event.ctrlKey && event.key == "ArrowUp") {
//Ctrl+UpArrow for Connect to last server
console.log(main_api);
if (online_status === "no_connection") {
if (main_api == "kobold") {
document.getElementById("api_button").click();
}
if (main_api == "novel") {
document.getElementById("api_button_novel").click();
}
if (main_api == "textgenerationwebui") {
document.getElementById("api_button_textgenerationwebui").click();
}
}
}
if (event.ctrlKey && event.key == "ArrowLeft") { //for debug, show all local stored vars
CheckLocal();
}
@@ -508,5 +709,42 @@ $("document").ready(function () {
$('.swipe_right:last').click();
}
}
if (event.ctrlKey && event.key == "ArrowUp") { //edits last USER message if chatbar is empty and focused
console.log('got ctrl+uparrow input');
if (
$("#send_textarea").val() === '' &&
chatbarInFocus === true &&
$(".swipe_right:last").css('display') === 'flex' &&
$("#character_popup").css("display") === "none" &&
$("#shadow_select_chat_popup").css("display") === "none"
) {
const isUserMesList = document.querySelectorAll('div[is_user="true"]');
const lastIsUserMes = isUserMesList[isUserMesList.length - 1];
const editMes = lastIsUserMes.querySelector('.mes_block .mes_edit');
if (editMes !== null) {
$(editMes).click();
}
}
}
if (event.key == "ArrowUp") { //edits last message if chatbar is empty and focused
console.log('got uparrow input');
if (
$("#send_textarea").val() === '' &&
chatbarInFocus === true &&
$(".swipe_right:last").css('display') === 'flex' &&
$("#character_popup").css("display") === "none" &&
$("#shadow_select_chat_popup").css("display") === "none"
) {
const lastMes = document.querySelector('.last_mes');
const editMes = lastMes.querySelector('.mes_block .mes_edit');
if (editMes !== null) {
$(editMes).click();
}
}
}
});
});

View File

@@ -7,6 +7,8 @@ import {
system_message_types,
this_chid,
openCharacterChat,
chat_metadata,
callPopup,
} from "../script.js";
import { selected_group } from "./group-chats.js";
@@ -36,27 +38,40 @@ async function getExistingChatNames() {
}
}
async function getBookmarkName(currentChat) {
async function getBookmarkName() {
const chatNames = await getExistingChatNames();
let mainChat = getMainChatName(currentChat);
let newChat = Date.now();
let friendlyName = '';
const popupText = `<h3>Enter the bookmark name:<h3>
<small>Using existing name will overwrite your bookmark chat.
<br>Leave empty to auto-generate.</small>`;
let name = await callPopup(popupText, 'input');
for (let i = 0; i < 1000; i++) {
friendlyName = `${bookmarkNameToken}${i}`;
newChat = `${mainChat} ${friendlyName}`;
if (!chatNames.includes(newChat)) {
break;
if (name === false) {
return null;
}
else if (name === '') {
for (let i = 0; i < 1000; i++) {
name = bookmarkNameToken + i;
if (!chatNames.includes(name)) {
break;
}
}
}
return { newChat, friendlyName };
return name;
}
function getMainChatName(currentChat) {
if (currentChat.includes(bookmarkNameToken)) {
currentChat = currentChat.substring(0, currentChat.lastIndexOf(bookmarkNameToken)).trim();
function getMainChatName() {
if (chat_metadata) {
if (chat_metadata['main_chat']) {
return chat_metadata['main_chat'];
}
else if (characters[this_chid].chat && characters[this_chid].chat.includes(bookmarkNameToken)) {
const tokenIndex = characters[this_chid].chat.lastIndexOf(bookmarkNameToken);
chat_metadata['main_chat'] = characters[this_chid].chat.substring(0, tokenIndex).trim();
return chat_metadata['main_chat'];
}
}
return currentChat;
return null;
}
function showBookmarksButtons() {
@@ -67,7 +82,7 @@ function showBookmarksButtons() {
$("#option_new_bookmark").hide();
}
// In main chat
else if (!characters[this_chid].chat.includes(bookmarkNameToken)) {
else if (!chat_metadata['main_chat']) {
$("#option_back_to_main").hide();
$("#option_new_bookmark").show();
@@ -91,10 +106,15 @@ $(document).ready(function () {
throw new Error();
}
let { newChat, friendlyName } = await getBookmarkName(characters[this_chid].chat);
let name = await getBookmarkName(characters[this_chid].chat);
saveChat(newChat);
let mainMessage = stringFormat(system_messages[system_message_types.BOOKMARK_CREATED].mes, newChat, friendlyName);
if (!name) {
return;
}
const newMetadata = { main_chat: characters[this_chid].chat };
saveChat(name, newMetadata);
let mainMessage = stringFormat(system_messages[system_message_types.BOOKMARK_CREATED].mes, name, name);
sendSystemMessage(system_message_types.BOOKMARK_CREATED, mainMessage);
saveChat();
});

View File

@@ -1,4 +1,4 @@
import { callPopup, saveSettings, saveSettingsDebounced } from "../script.js";
import { callPopup, saveSettings, saveSettingsDebounced, token } from "../script.js";
import { isSubsetOf } from "./utils.js";
export {
getContext,
@@ -9,38 +9,13 @@ export {
extension_settings,
};
const extensionNames = ['caption', 'dice', 'expressions', 'floating-prompt', 'memory'];
const manifests = await getManifests(extensionNames);
// TODO: Delete in next release
function migrateFromLocalStorage() {
const extensions_urlKey = 'extensions_url';
const extensions_autoConnectKey = 'extensions_autoconnect';
const extensions_disabledKey = 'extensions_disabled';
const apiUrl = localStorage.getItem(extensions_urlKey);
const autoConnect = localStorage.getItem(extensions_autoConnectKey);
const extensionsDisabled = localStorage.getItem(extensions_disabledKey);
if (apiUrl !== null) {
extension_settings.apiUrl = apiUrl;
localStorage.removeItem(extensions_urlKey);
}
if (autoConnect !== null) {
extension_settings.autoConnect = autoConnect;
localStorage.removeItem(extensions_autoConnectKey);
}
if (extensionsDisabled !== null) {
extension_settings.disabledExtensions = JSON.parse(extensionsDisabled);
localStorage.removeItem(extensions_disabledKey);
}
}
let extensionNames = [];
let manifests = [];
const defaultUrl = "http://localhost:5100";
const extension_settings = {
apiUrl: '',
autoConnect: '',
apiUrl: defaultUrl,
autoConnect: false,
disabledExtensions: [],
memory: {},
note: {
@@ -56,10 +31,27 @@ let activeExtensions = new Set();
const getContext = () => window['TavernAI'].getContext();
const getApiUrl = () => extension_settings.apiUrl;
const defaultUrl = "http://localhost:5100";
const defaultRequestArgs = { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } };
let connectedToApi = false;
async function discoverExtensions() {
try {
const response = await fetch('/discover_extensions', { headers: { 'X-CSRF-Token': token } });
if (response.ok) {
const extensions = await response.json();
return extensions;
}
else {
return [];
}
}
catch (err) {
console.error(err);
return [];
}
}
function onDisableExtensionClick() {
const name = $(this).data('name');
disableExtension(name);
@@ -273,9 +265,7 @@ function showExtensionsDetails() {
callPopup(`<div class="extensions_info">${html}</div>`, 'text');
}
function loadExtensionSettings(settings) {
migrateFromLocalStorage();
async function loadExtensionSettings(settings) {
if (settings.extension_settings) {
Object.assign(extension_settings, settings.extension_settings);
}
@@ -284,6 +274,8 @@ function loadExtensionSettings(settings) {
$("#extensions_autoconnect").prop('checked', extension_settings.autoConnect).trigger('input');
// Activate offline extensions
extensionNames = await discoverExtensions();
manifests = await getManifests(extensionNames)
activateExtensions();
}

View File

@@ -0,0 +1,129 @@
import { getContext } from "../../extensions.js";
export { MODULE_NAME };
const MODULE_NAME = 'backgrounds';
const METADATA_KEY = 'custom_background';
const UPDATE_INTERVAL = 1000;
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;
context.saveChat();
}
function removeBackgroundMetadata() {
const context = getContext();
delete context.chatMetadata[METADATA_KEY];
context.saveChat();
}
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();
}
}
$(document).ready(function () {
function addSettings() {
const html = `
<div class="background_settings">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Character 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>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);
}
addSettings();
setInterval(moduleWorker, UPDATE_INTERVAL);
});

View File

@@ -0,0 +1,11 @@
{
"display_name": "Character Backgrounds",
"loading_order": 7,
"requires": [],
"optional": [],
"js": "index.js",
"css": "style.css",
"author": "Cohee#1207",
"version": "1.0.0",
"homePage": "https://github.com/Cohee1207/SillyTavern"
}

View File

@@ -0,0 +1,45 @@
#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(--black50a);
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;
}

View File

@@ -16,8 +16,8 @@ async function moduleWorker() {
async function setImageIcon() {
try {
const sendButton = document.getElementById('send_picture');
sendButton.style.backgroundImage = `url('/img/image-solid.svg')`;
sendButton.classList.remove('spin');
sendButton.classList.add('fa-image');
sendButton.classList.remove('fa-hourglass-half', 'fa-fade');
}
catch (error) {
console.log(error);
@@ -27,8 +27,8 @@ async function setImageIcon() {
async function setSpinnerIcon() {
try {
const sendButton = document.getElementById('send_picture');
sendButton.style.backgroundImage = `url('/img/spinner-solid.svg')`;
sendButton.classList.add('spin');
sendButton.classList.remove('fa-image');
sendButton.classList.add('fa-hourglass-half', 'fa-fade');
}
catch (error) {
console.log(error);
@@ -77,7 +77,8 @@ async function onSelectImage(e) {
if (apiResult.ok) {
const data = await apiResult.json();
const caption = data.caption;
await sendCaptionedMessage(caption, base64Img);
const imageToSave = data.thumbnail ? `data:image/jpeg;base64,${data.thumbnail}` : base64Img;
await sendCaptionedMessage(caption, imageToSave);
}
}
catch (error) {
@@ -97,9 +98,9 @@ $(document).ready(function () {
$('#send_form').css('grid-template-columns', columns.join(' '));
}
function addSendPictureButton() {
const sendButton = document.createElement('input');
sendButton.type = 'button';
const sendButton = document.createElement('div');
sendButton.id = 'send_picture';
sendButton.classList.add('fa-solid');
$(sendButton).hide();
$(sendButton).on('click', () => $('#img_file').click());
$('#send_but_sheld').prepend(sendButton);

View File

@@ -6,5 +6,8 @@
],
"optional": [],
"js": "index.js",
"css": "style.css"
"css": "style.css",
"author": "Cohee#1207",
"version": "1.0.0",
"homePage": "https://github.com/Cohee1207/SillyTavern"
}

View File

@@ -4,15 +4,14 @@
height: 40px;
margin: 0;
padding: 1px;
background: no-repeat;
background-size: 26px auto;
background-position: center center;
outline: none;
border: none;
cursor: pointer;
transition: 0.3s;
filter: invert(1);
opacity: 0.5;
filter: brightness(0.7);
display: flex;
align-items: center;
justify-content: center;
}
#send_picture:hover {
@@ -22,15 +21,3 @@
#img_form {
display: none;
}
.spin {
animation-name: spin;
animation-duration: 2000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes spin {
from {transform:rotate(0deg);}
to {transform:rotate(360deg);}
}

View File

@@ -7,13 +7,13 @@ const UPDATE_INTERVAL = 1000;
function setDiceIcon() {
const sendButton = document.getElementById('roll_dice');
sendButton.style.backgroundImage = `url(/img/dice-solid.svg)`;
/* sendButton.style.backgroundImage = `url(/img/dice-solid.svg)`; */
sendButton.classList.remove('spin');
}
async function doDiceRoll() {
let value = $(this).data('value');
if (value == 'custom') {
value = await callPopup('Enter the dice formula:<br><i>(for example, <tt>2d6</tt>)</i>', 'input');
}
@@ -29,22 +29,24 @@ async function doDiceRoll() {
function addDiceRollButton() {
const buttonHtml = `
<input id="roll_dice" type="button" />
<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>
<div id="roll_dice" class="fa-solid fa-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>`;
$('#send_but_sheld').prepend(buttonHtml);
$(document.body).append(dropdownHtml)
$('#dice_dropdown li').on('click', doDiceRoll);
const button = $('#roll_dice');
const dropdown = $('#dice_dropdown');

View File

@@ -4,5 +4,8 @@
"requires": [],
"optional": [],
"js": "index.js",
"css": "style.css"
"css": "style.css",
"author": "Cohee#1207",
"version": "1.0.0",
"homePage": "https://github.com/Cohee1207/SillyTavern"
}

View File

@@ -4,17 +4,23 @@
height: 40px;
margin: 0;
padding: 1px;
background: no-repeat;
background-size: 26px auto;
background-position: center center;
outline: none;
border: none;
cursor: pointer;
transition: 0.3s;
filter: invert(1);
opacity: 0.5;
opacity: 0.7;
display: flex;
align-items: center;
justify-content: center;
}
#roll_dice:hover {
opacity: 1;
filter: brightness(1.2);
}
#dice_dropdown {
z-index: 100;
backdrop-filter: blur(--SmartThemeBlurStrength);
}

View File

@@ -1,14 +1,44 @@
import { saveSettingsDebounced } from "../../../script.js";
import { saveSettingsDebounced, token } from "../../../script.js";
import { getContext, getApiUrl, modules, extension_settings } from "../../extensions.js";
export { MODULE_NAME };
const MODULE_NAME = 'expressions';
const UPDATE_INTERVAL = 1000;
const DEFAULT_EXPRESSIONS = ['anger', 'fear', 'joy', 'love', 'sadness', 'surprise'];
const DEFAULT_EXPRESSIONS = [
"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"
];
let expressionsList = null;
let lastCharacter = undefined;
let lastMessage = null;
let spriteCache = {};
let inApiCall = false;
function onExpressionsShowDefaultInput() {
@@ -28,48 +58,75 @@ function onExpressionsShowDefaultInput() {
}
}
async function moduleWorker() {
function getLastCharacterMessage() {
const reversedChat = context.chat.slice().reverse();
let isWorkerBusy = false;
for (let mes of reversedChat) {
if (mes.is_user || mes.is_system) {
continue;
}
return mes.mes;
}
return '';
async function moduleWorkerWrapper() {
// Don't touch me I'm busy...
if (isWorkerBusy) {
return;
}
// I'm free. Let's update!
try {
isWorkerBusy = true;
await moduleWorker();
}
finally {
isWorkerBusy = false;
}
}
async function moduleWorker() {
const context = getContext();
// group chats and non-characters not supported
if (context.groupId || !context.characterId) {
// non-characters not supported
if (!context.groupId && !context.characterId) {
removeExpression();
return;
}
// character changed
if (lastCharacter !== context.characterId) {
if (context.groupId !== lastCharacter && context.characterId !== lastCharacter) {
removeExpression();
validateImages();
spriteCache = {};
}
const currentLastMessage = getLastCharacterMessage();
// character has no expressions or it is not loaded
if (Object.keys(spriteCache).length === 0) {
await validateImages(currentLastMessage.name);
lastCharacter = context.groupId || context.characterId;
}
const offlineMode = $('.expression_settings .offline_mode');
if (!modules.includes('classify')) {
$('.expression_settings').show();
$('.expression_settings .offline_mode').css('display', 'block');
lastCharacter = context.characterId;
offlineMode.css('display', 'block');
lastCharacter = context.groupId || context.characterId;
if (context.groupId) {
await validateImages(currentLastMessage.name, true);
}
return;
}
else {
$('.expression_settings .offline_mode').css('display', 'none');
// force reload expressions list on connect to API
if (offlineMode.is(':visible')) {
expressionsList = null;
spriteCache = {};
expressionsList = await getExpressionsList();
await validateImages(currentLastMessage.name, true);
}
offlineMode.css('display', 'none');
}
// check if last message changed
const currentLastMessage = getLastCharacterMessage();
if (lastCharacter === context.characterId && lastMessage === currentLastMessage) {
if ((lastCharacter === context.characterId || lastCharacter === context.groupId)
&& lastMessage === currentLastMessage.mes) {
return;
}
@@ -89,13 +146,21 @@ async function moduleWorker() {
'Content-Type': 'application/json',
'Bypass-Tunnel-Reminder': 'bypass',
},
body: JSON.stringify({ text: currentLastMessage })
body: JSON.stringify({ text: currentLastMessage.mes })
});
if (apiResult.ok) {
const name = context.groupId ? currentLastMessage.name : context.name2;
const force = !!context.groupId;
const data = await apiResult.json();
const expression = data.classification[0].label;
setExpression(context.name2, expression);
let expression = data.classification[0].label;
// Character won't be angry on you for swiping
if (currentLastMessage.mes == '...' && expressionsList.includes('joy')) {
expression = 'joy';
}
setExpression(name, expression, force);
}
}
@@ -104,51 +169,72 @@ async function moduleWorker() {
}
finally {
inApiCall = false;
lastCharacter = context.characterId;
lastMessage = currentLastMessage;
lastCharacter = context.groupId || context.characterId;
lastMessage = currentLastMessage.mes;
}
}
function getLastCharacterMessage() {
const context = getContext();
const reversedChat = context.chat.slice().reverse();
for (let mes of reversedChat) {
if (mes.is_user || mes.is_system) {
continue;
}
return { mes: mes.mes, name: mes.name };
}
return { mes: '', name: null };
}
function removeExpression() {
lastMessage = null;
$('img.expression').off('error');
$('img.expression').prop('src', '');
$('img.expression').removeClass('default');
$('.expression_settings').hide();
}
let imagesValidating = false;
async function validateImages() {
if (imagesValidating) {
async function validateImages(character, forceRedrawCached) {
if (!character) {
return;
}
imagesValidating = true;
const context = getContext();
const labels = await getExpressionsList();
if (spriteCache[character]) {
if (forceRedrawCached && $('#image_list').data('name') !== character) {
console.log('force redrawing character sprites list')
drawSpritesList(character, labels, spriteCache[character]);
}
return;
}
const sprites = await getSpritesList(character);
let validExpressions = drawSpritesList(character, labels, sprites);
spriteCache[character] = validExpressions;
}
function drawSpritesList(character, labels, sprites) {
let validExpressions = [];
$('.expression_settings').show();
$('#image_list').empty();
$('#image_list').data('name', character);
labels.sort().forEach((item) => {
const sprite = sprites.find(x => x.label == item);
if (!context.characterId) {
imagesValidating = false;
return;
}
const IMAGE_LIST = (await getExpressionsList()).map(x => `${x}.png`);
IMAGE_LIST.forEach((item) => {
const image = document.createElement('img');
image.src = `/characters/${context.name2}/${item}`;
image.classList.add('debug-image');
image.width = '0px';
image.height = '0px';
image.onload = function () {
$('#image_list').append(getListItem(item, image.src, 'success'));
if (sprite) {
validExpressions.push(sprite);
$('#image_list').append(getListItem(item, sprite.path, 'success'));
}
image.onerror = function () {
else {
$('#image_list').append(getListItem(item, '/img/No-Image-Placeholder.svg', 'failure'));
}
$('#image_list').prepend(image);
});
imagesValidating = false;
return validExpressions;
}
function getListItem(item, imageSrc, textClass) {
@@ -160,8 +246,28 @@ function getListItem(item, imageSrc, textClass) {
`;
}
async function getSpritesList(name) {
console.log('getting sprites list');
try {
const result = await fetch(`/get_sprites?name=${encodeURIComponent(name)}`, {
headers: {
'X-CSRF-Token': token,
}
});
let sprites = result.ok ? (await result.json()) : [];
return sprites;
}
catch (err) {
console.log(err);
return [];
}
}
async function getExpressionsList() {
// get something for offline mode (6 default images)
console.log('getting expressions list');
// get something for offline mode (default images)
if (!modules.includes('classify')) {
return DEFAULT_EXPRESSIONS;
}
@@ -180,6 +286,7 @@ async function getExpressionsList() {
});
if (apiResult.ok) {
const data = await apiResult.json();
expressionsList = data.labels;
return expressionsList;
@@ -192,23 +299,37 @@ async function getExpressionsList() {
}
async function setExpression(character, expression, force) {
const filename = `${expression}.png`;
const debugImageStatus = document.querySelector(`#image_list div[id="${filename}"] span`);
console.log('entered setExpressions');
await validateImages(character);
const img = $('img.expression');
if (force || (debugImageStatus && !debugImageStatus.classList.contains('failure'))) {
//console.log('setting expression from character images folder');
const imgUrl = `/characters/${character}/${filename}`;
$('img.expression').prop('src', imgUrl);
$('img.expression').removeClass('default');
const sprite = (spriteCache[character] && spriteCache[character].find(x => x.label === expression));
console.log('checking for expression images to show..');
if (sprite) {
console.log('setting expression from character images folder');
img.attr('src', sprite.path);
img.removeClass('default');
img.off('error');
img.on('error', function () {
$(this).attr('src', '');
if (force && extension_settings.expressions.showDefault) {
setDefault();
}
});
} else {
if (extension_settings.expressions.showDefault) {
//console.log('no character images, trying default expressions');
const defImgUrl = `/img/default-expressions/${filename}`;
//console.log(defImgUrl);
$('img.expression').prop('src', defImgUrl);
$('img.expression').addClass('default');
setDefault();
}
}
function setDefault() {
console.log('setting default');
const defImgUrl = `/img/default-expressions/${expression}.png`;
//console.log(defImgUrl);
img.attr('src', defImgUrl);
img.addClass('default');
}
document.getElementById("expression-holder").style.display = '';
}
function onClickExpressionImage() {
@@ -217,35 +338,40 @@ function onClickExpressionImage() {
return;
}
const context = getContext();
const expression = $(this).attr('id').replace('.png', '');
const expression = $(this).attr('id');
const name = getLastCharacterMessage().name;
if ($(this).find('.failure').length === 0) {
setExpression(context.name2, expression, true);
setExpression(name, expression, true);
}
}
(function () {
function addExpressionImage() {
const html = `<div class="expression-holder"><img class="expression"></div>`;
const html = `
<div id="expression-holder" class="expression-holder" style="display:none;">
<div id="expression-holderheader" class="fa-solid fa-grip drag-grabber"></div>
<img id="expression-image" class="expression">
</div>`;
$('body').append(html);
}
function addSettings() {
const html = `
<div class="expression_settings">
<h4>Expression images</h4>
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>View supported images</b>
<div class="inline-drawer-icon down"></div>
<b>Expression images</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<p class="offline_mode">You are in offline mode. Click on the image below to set the expression.</p>
<div id="image_list"></div>
<p class="hint"><b>Hint:</b> <i>Create new folder in the <b>public/characters/</b> folder and name it as the name of the character. Put PNG images with expressions there.</i></p>
</div>
<p class="hint"><b>Hint:</b> <i>Create new folder in the <b>public/characters/</b> folder and name it as the name of the character.
Put images with expressions there. File names should follow the pattern: <tt>[expression_label].[image_format]</tt></i></p>
<label for="expressions_show_default"><input id="expressions_show_default" type="checkbox">Show default images (emojis) if missing</label>
</div>
</div>
<label for="expressions_show_default"><input id="expressions_show_default" type="checkbox">Show default images (emojis) if missing</label>
</div>
`;
$('#extensions_settings').append(html);
@@ -257,5 +383,5 @@ function onClickExpressionImage() {
addExpressionImage();
addSettings();
setInterval(moduleWorker, UPDATE_INTERVAL);
setInterval(moduleWorkerWrapper, UPDATE_INTERVAL);
})();

View File

@@ -6,5 +6,8 @@
"classify"
],
"js": "index.js",
"css": "style.css"
"css": "style.css",
"author": "Cohee#1207",
"version": "1.0.0",
"homePage": "https://github.com/Cohee1207/SillyTavern"
}

View File

@@ -5,24 +5,29 @@
}
.expression-holder {
min-width: 100px;
min-height: 100px;
max-height: 90vh;
max-width: calc((100vw - 800px)/2);
width: 100%;
position: fixed;
left: 0;
bottom: 0;
padding-left: 10px;
padding-right: 10px;
text-align: center;
max-width: 90vh;
width: calc((100vw - var(--sheldWidth)) /2);
position: absolute;
bottom: 1px;
padding: 0;
filter: drop-shadow(2px 2px 2px #51515199);
transition: 500ms;
z-index: 3;
z-index: 1;
overflow: hidden;
}
img.expression {
max-width: 100%;
max-height: 90vh;
width: 100%;
height: 100%;
vertical-align: bottom;
object-fit: contain;
}
img.expression[src=""] {
visibility: hidden;
}
img.expression.default {

View File

@@ -51,76 +51,7 @@ function onExtensionFloatingDefaultInput() {
saveSettingsDebounced();
}
// TODO Remove in next release
function getLocalStorageKeys() {
const context = getContext();
let keySuffix;
if (context.groupId) {
keySuffix = context.groupId;
}
else if (context.characterId) {
keySuffix = `${context.characters[context.characterId].name}_${context.chatId}`;
}
else {
keySuffix = 'undefined';
}
return {
prompt: `extensions_floating_prompt_${keySuffix}`,
interval: `extensions_floating_interval_${keySuffix}`,
depth: `extensions_floating_depth_${keySuffix}`,
position: `extensions_floating_position_${keySuffix}`,
default: 'extensions_default_note',
};
}
function migrateFromLocalStorage() {
const keys = getLocalStorageKeys();
const defaultNote = localStorage.getItem(keys.default);
const prompt = localStorage.getItem(keys.prompt);
const interval = localStorage.getItem(keys.interval);
const position = localStorage.getItem(keys.position);
const depth = localStorage.getItem(keys.depth);
if (defaultNote !== null) {
if (typeof extension_settings.note !== 'object') {
extension_settings.note = {};
}
extension_settings.note.default = defaultNote;
saveSettingsDebounced();
localStorage.removeItem(keys.default);
}
if (chat_metadata) {
if (interval !== null) {
chat_metadata[metadata_keys.interval] = interval;
localStorage.removeItem(keys.interval);
}
if (depth !== null) {
chat_metadata[metadata_keys.depth] = depth;
localStorage.removeItem(keys.depth);
}
if (position !== null) {
chat_metadata[metadata_keys.position] = position;
localStorage.removeItem(keys.position);
}
if (prompt !== null) {
chat_metadata[metadata_keys.prompt] = prompt;
localStorage.removeItem(keys.prompt);
saveChatDebounced();
}
}
}
function loadSettings() {
migrateFromLocalStorage();
chat_metadata[metadata_keys.prompt] = chat_metadata[metadata_keys.prompt] ?? extension_settings.note.default ?? '';
chat_metadata[metadata_keys.interval] = chat_metadata[metadata_keys.interval] ?? DEFAULT_INTERVAL;
chat_metadata[metadata_keys.position] = chat_metadata[metadata_keys.position] ?? DEFAULT_POSITION;
@@ -150,6 +81,7 @@ async function moduleWorker() {
}
if (lastMessageNumber <= 0 || chat_metadata[metadata_keys.interval] <= 0) {
context.setExtensionPrompt(MODULE_NAME, '');
$('#extension_floating_counter').text('No');
return;
}
@@ -163,35 +95,43 @@ async function moduleWorker() {
$('#extension_floating_counter').text(shouldAddPrompt ? 'This' : messagesTillInsertion);
}
(function() {
(function () {
function addExtensionsSettings() {
const settingsHtml = `
<h4>Author's Note / Character Bias</h4>
<div class="floating_prompt_settings">
<label for="extension_floating_prompt">Append the following text:</label>
<textarea id="extension_floating_prompt" class="text_pole" rows="2"></textarea>
<label>
<input type="radio" name="extension_floating_position" value="0" />
After scenario
</label>
<label>
<input type="radio" name="extension_floating_position" value="1" />
In-chat
</label>
<label for="extension_floating_interval">Every N messages <b>you</b> send (set to 0 to disable):</label>
<input id="extension_floating_interval" class="text_pole" type="number" min="0" max="999" />
<label for="extension_floating_interval">Insertion depth (for in-chat positioning):</label>
<input id="extension_floating_depth" class="text_pole" type="number" min="0" max="99" />
<span>Appending to the prompt in next: <span id="extension_floating_counter">No</span> message(s)</span>
<br>
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Author's Note / Character Bias</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<label for="extension_floating_prompt">Append the following text:</label>
<textarea id="extension_floating_prompt" class="text_pole" rows="8"></textarea>
<div class="floating_prompt_radio_group">
<label>
<input type="radio" name="extension_floating_position" value="0" />
After scenario
</label>
<label>
<input type="radio" name="extension_floating_position" value="1" />
In-chat
</label>
</div>
<label for="extension_floating_interval">Every N messages <b>you</b> send (set to 0 to disable):</label>
<input id="extension_floating_interval" class="text_pole" type="number" min="0" max="999" />
<label for="extension_floating_interval">Insertion depth (for in-chat positioning):</label>
<input id="extension_floating_depth" class="text_pole" type="number" min="0" max="99" />
<span>Appending to the prompt in next: <span id="extension_floating_counter">No</span> message(s)</span>
</div>
</div>
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b>Default note for new chats</b>
<div class="inline-drawer-icon down"></div>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<label for="extension_floating_default">Default Author's Note</label>
<textarea id="extension_floating_default" class="text_pole" rows="3"
<textarea id="extension_floating_default" class="text_pole" rows="8"
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More