├── .dockerignore ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ └── feature-request.yml ├── readme-zh_cn.md ├── readme.md └── workflows │ ├── build-and-publish-release.yml │ ├── build-and-publish-staging.yml │ ├── docker-publish.yml │ ├── npm-publish.yml │ └── update-docs.yml ├── .gitignore ├── .npmignore ├── .replit ├── Dockerfile ├── LICENSE ├── Remote-Link.cmd ├── SECURITY.md ├── Start.bat ├── Update-Instructions.txt ├── UpdateAndStart.bat ├── colab └── GPU.ipynb ├── default ├── bg_load.css ├── config.conf ├── content │ ├── Eldoria.json │ ├── Seraphina │ │ ├── admiration.png │ │ ├── amusement.png │ │ ├── anger.png │ │ ├── annoyance.png │ │ ├── approval.png │ │ ├── caring.png │ │ ├── confusion.png │ │ ├── curiosity.png │ │ ├── desire.png │ │ ├── disappointment.png │ │ ├── disapproval.png │ │ ├── disgust.png │ │ ├── embarrassment.png │ │ ├── excitement.png │ │ ├── fear.png │ │ ├── gratitude.png │ │ ├── grief.png │ │ ├── joy.png │ │ ├── love.png │ │ ├── nervousness.png │ │ ├── neutral.png │ │ ├── optimism.png │ │ ├── pride.png │ │ ├── realization.png │ │ ├── relief.png │ │ ├── remorse.png │ │ ├── sadness.png │ │ └── surprise.png │ ├── default_CodingSensei.png │ ├── default_FluxTheCat.png │ ├── default_Seraphina.png │ ├── index.json │ └── user-default.png ├── settings.json └── user.css ├── docker ├── docker-compose.yml └── docker-entrypoint.sh ├── jsconfig.json ├── package-lock.json ├── package.json ├── post-install.js ├── public ├── NovelAI Settings │ ├── Asper-Kayra.settings │ ├── Blended-Coffee-Kayra.settings │ ├── Blook-Kayra.settings │ ├── Carefree-Kayra.settings │ ├── Edgewise-Clio.settings │ ├── Fresh-Coffee-Clio.settings │ ├── Fresh-Coffee-Kayra.settings │ ├── Green-Active-Writer-Kayra.settings │ ├── Keelback-Clio.settings │ ├── Long-Press-Clio.settings │ ├── Pilotfish-Kayra.settings │ ├── Pro_Writer-Kayra.settings │ ├── Stelenes-Kayra.settings │ ├── Talker-Chat-Clio.settings │ ├── Tea_Time-Kayra.settings │ ├── Tesseract-Kayra.settings │ ├── Vingt-Un-Clio.settings │ └── Writers-Daemon-Kayra.settings ├── backgrounds │ ├── __transparent.png │ ├── _black.jpg │ ├── _white.jpg │ ├── bedroom clean.jpg │ ├── bedroom cyberpunk.jpg │ ├── bedroom red.jpg │ ├── bedroom tatami.jpg │ ├── cityscape medieval market.jpg │ ├── cityscape medieval night.jpg │ ├── cityscape postapoc.jpg │ ├── forest treehouse fireworks air baloons (by kallmeflocc).jpg │ ├── japan classroom side.jpg │ ├── japan classroom.jpg │ ├── japan path cherry blossom.jpg │ ├── japan university.jpg │ ├── landscape autumn great tree.jpg │ ├── landscape beach day.png │ ├── landscape beach night.jpg │ ├── landscape mountain lake.jpg │ ├── landscape postapoc.jpg │ ├── landscape winter lake house.jpg │ ├── royal.jpg │ └── tavern day.jpg ├── context │ └── Pygmalion.json ├── css │ ├── bright.min.css │ ├── character-group-overlay.css │ ├── cropper.min.css │ ├── extensions-panel.css │ ├── fontawesome.css │ ├── group-avatars.css │ ├── jquery-ui.min.css │ ├── loader.css │ ├── mobile-styles.css │ ├── promptmanager.css │ ├── rm-groups.css │ ├── select2-overrides.css │ ├── select2.min.css │ ├── solid.css │ ├── st-tailwind.css │ ├── tags.css │ ├── toastr.min.css │ ├── toggle-dependent.css │ └── world-info.css ├── favicon.ico ├── i18n.json ├── img │ ├── No-Image-Placeholder.svg │ ├── addbg3.png │ ├── ai21.svg │ ├── ai4.png │ ├── aphrodite.svg │ ├── apple-icon-114x114.png │ ├── apple-icon-144x144.png │ ├── apple-icon-57x57.png │ ├── apple-icon-72x72.png │ ├── claude.svg │ ├── default-expressions │ │ ├── admiration.png │ │ ├── amusement.png │ │ ├── anger.png │ │ ├── annoyance.png │ │ ├── approval.png │ │ ├── caring.png │ │ ├── confusion.png │ │ ├── curiosity.png │ │ ├── desire.png │ │ ├── desire1.png │ │ ├── desire2.png │ │ ├── disappointment.png │ │ ├── disapproval.png │ │ ├── disgust.png │ │ ├── embarrassment.png │ │ ├── excitement.png │ │ ├── fear.png │ │ ├── gratitude.png │ │ ├── grief.png │ │ ├── joy.png │ │ ├── love.png │ │ ├── nervousness.png │ │ ├── neutral.png │ │ ├── optimism.png │ │ ├── pride.png │ │ ├── realization.png │ │ ├── relief.png │ │ ├── remorse.png │ │ ├── sadness.png │ │ └── surprise.png │ ├── five.png │ ├── kobold.svg │ ├── koboldhorde.svg │ ├── mancer.svg │ ├── novel.svg │ ├── openai.svg │ ├── openrouter.svg │ ├── palm.svg │ ├── quill.png │ ├── textgenerationwebui.svg │ └── times-circle.svg ├── index.html ├── instruct │ ├── Alpaca.json │ ├── Koala.json │ ├── Metharme.json │ ├── OpenOrca-OpenChat.json │ ├── Roleplay.json │ ├── Vicuna 1.0.json │ ├── Vicuna 1.1.json │ ├── WizardLM-13B.json │ └── WizardLM.json ├── jsconfig.json ├── lib │ ├── cropper.min.js │ ├── droll.js │ ├── eventemitter.js │ ├── fuse.js │ ├── handlebars.js │ ├── highlight.min.js │ ├── jquery-3.5.1.min.js │ ├── jquery-cookie-1.4.1.min.js │ ├── jquery-cropper.min.js │ ├── jquery-ui.min.js │ ├── jquery.transit.min.js │ ├── jquery.ui.touch-punch.min.js │ ├── localforage.min.js │ ├── moment.min.js │ ├── moment.min.js.map │ ├── pagination.js │ ├── popper.js │ ├── popper.js.map │ ├── purify.min.js │ ├── purify.min.js.map │ ├── seedrandom.min.js │ ├── select2-search-placeholder.js │ ├── select2.min.js │ ├── showdown-katex.min.js │ ├── showdown-katex.min.js.map │ ├── showdown-toc.min.js │ ├── showdown.min.js │ ├── showdown.min.js.map │ ├── structured-clone │ │ ├── LICENSE │ │ ├── deserialize.js │ │ ├── index.js │ │ ├── json.js │ │ ├── monkey-patch.js │ │ ├── serialize.js │ │ └── types.js │ ├── svg-inject.js │ ├── swiped-events.js │ ├── toastr.js.map │ ├── toastr.min.js │ ├── toolcool-color-picker.js │ └── uniqolor.js ├── robots.txt ├── script.js ├── scripts │ ├── BulkEditOverlay.js │ ├── PromptManager.js │ ├── RossAscends-mods.js │ ├── authors-note.js │ ├── backgrounds.js │ ├── bookmarks.js │ ├── bulk-edit.js │ ├── cfg-scale.js │ ├── chats.js │ ├── extensions.js │ ├── extensions │ │ ├── assets │ │ │ ├── confirm.html │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ ├── style.css │ │ │ └── window.html │ │ ├── caption │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── style.css │ │ ├── expressions │ │ │ ├── add-custom-expression.html │ │ │ ├── index.js │ │ │ ├── list-item.html │ │ │ ├── manifest.json │ │ │ ├── remove-custom-expression.html │ │ │ ├── settings.html │ │ │ └── style.css │ │ ├── gallery │ │ │ ├── index.js │ │ │ ├── jquery.nanogallery2.min.js │ │ │ ├── manifest.json │ │ │ └── nanogallery2.woff.min.css │ │ ├── memory │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── style.css │ │ ├── quick-reply │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── style.css │ │ ├── regex │ │ │ ├── dropdown.html │ │ │ ├── editor.html │ │ │ ├── engine.js │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ ├── scriptTemplate.html │ │ │ └── style.css │ │ ├── stable-diffusion │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ ├── settings.html │ │ │ └── style.css │ │ ├── token-counter │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── style.css │ │ ├── translate │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── style.css │ │ ├── tts │ │ │ ├── coqui.js │ │ │ ├── coqui_api_models_settings.json │ │ │ ├── coqui_api_models_settings_full.json │ │ │ ├── edge.js │ │ │ ├── elevenlabs.js │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ ├── novel.js │ │ │ ├── openai.js │ │ │ ├── readme.md │ │ │ ├── silerotts.js │ │ │ ├── style.css │ │ │ └── system.js │ │ └── vectors │ │ │ ├── index.js │ │ │ ├── manifest.json │ │ │ └── settings.html │ ├── f-localStorage.js │ ├── filters.js │ ├── flowgpt.js │ ├── group-chats.js │ ├── horde.js │ ├── i18n.js │ ├── instruct-mode.js │ ├── kai-settings.js │ ├── loader.js │ ├── mancer-settings.js │ ├── nai-settings.js │ ├── openai.js │ ├── personas.js │ ├── poe.js │ ├── power-user.js │ ├── preset-manager.js │ ├── secrets.js │ ├── server-history.js │ ├── setting-search.js │ ├── showdown-exclusion.js │ ├── slash-commands.js │ ├── stats.js │ ├── tags.js │ ├── templates │ │ ├── debug.html │ │ ├── formatting.html │ │ ├── help.html │ │ ├── hotkeys.html │ │ ├── itemizationChat.html │ │ ├── itemizationText.html │ │ ├── macros.html │ │ └── welcome.html │ ├── textgen-settings.js │ ├── tokenizers.js │ ├── utils.js │ ├── variables.js │ └── world-info.js ├── sounds │ ├── message.mp3 │ └── silence.mp3 ├── st-launcher.ico ├── style.css └── webfonts │ ├── NotoSans │ ├── NotoSans-Black.woff │ ├── NotoSans-Black.woff2 │ ├── NotoSans-BlackItalic.woff │ ├── NotoSans-BlackItalic.woff2 │ ├── NotoSans-Bold.woff │ ├── NotoSans-Bold.woff2 │ ├── NotoSans-BoldItalic.woff │ ├── NotoSans-BoldItalic.woff2 │ ├── NotoSans-ExtraBold.woff │ ├── NotoSans-ExtraBold.woff2 │ ├── NotoSans-ExtraBoldItalic.woff │ ├── NotoSans-ExtraBoldItalic.woff2 │ ├── NotoSans-ExtraLight.woff │ ├── NotoSans-ExtraLight.woff2 │ ├── NotoSans-ExtraLightItalic.woff │ ├── NotoSans-ExtraLightItalic.woff2 │ ├── NotoSans-Italic.woff │ ├── NotoSans-Italic.woff2 │ ├── NotoSans-Light.woff │ ├── NotoSans-Light.woff2 │ ├── NotoSans-LightItalic.woff │ ├── NotoSans-LightItalic.woff2 │ ├── NotoSans-Medium.woff │ ├── NotoSans-Medium.woff2 │ ├── NotoSans-MediumItalic.woff │ ├── NotoSans-MediumItalic.woff2 │ ├── NotoSans-Regular.woff │ ├── NotoSans-Regular.woff2 │ ├── NotoSans-SemiBold.woff │ ├── NotoSans-SemiBold.woff2 │ ├── NotoSans-SemiBoldItalic.woff │ ├── NotoSans-SemiBoldItalic.woff2 │ ├── NotoSans-Thin.woff │ ├── NotoSans-Thin.woff2 │ ├── NotoSans-ThinItalic.woff │ ├── NotoSans-ThinItalic.woff2 │ └── stylesheet.css │ ├── fa-solid-900.ttf │ └── fa-solid-900.woff2 ├── replit.nix ├── server.js ├── src ├── ai_horde │ ├── LICENSE.md │ ├── index.d.ts │ ├── index.js │ └── index.mjs ├── assets.js ├── caption.js ├── character-card-parser.js ├── chat-completion.js ├── classify.js ├── claude.json ├── constants.js ├── content-manager.js ├── embedding.js ├── extensions.js ├── flowgpt-client.js ├── horde.js ├── middleware │ └── basicAuthMiddleware.js ├── novelai.js ├── openai-vectors.js ├── openai.js ├── palm-vectors.js ├── poe-client.js ├── poe_graphql │ ├── AddHumanMessageMutation.graphql │ ├── AddMessageBreakMutation.graphql │ ├── AutoSubscriptionMutation.graphql │ ├── BioFragment.graphql │ ├── ChatAddedSubscription.graphql │ ├── ChatFragment.graphql │ ├── ChatListPaginationQuery.graphql │ ├── ChatPaginationQuery.graphql │ ├── ChatViewQuery.graphql │ ├── DeleteHumanMessagesMutation.graphql │ ├── DeleteMessageMutation.graphql │ ├── HandleFragment.graphql │ ├── LoginWithVerificationCodeMutation.graphql │ ├── MessageAddedSubscription.graphql │ ├── MessageDeletedSubscription.graphql │ ├── MessageFragment.graphql │ ├── MessageRemoveVoteMutation.graphql │ ├── MessageSetVoteMutation.graphql │ ├── SendMessageMutation.graphql │ ├── SendVerificationCodeForLoginMutation.graphql │ ├── ShareMessagesMutation.graphql │ ├── SignupWithVerificationCodeMutation.graphql │ ├── StaleChatUpdateMutation.graphql │ ├── SubscriptionsMutation.graphql │ ├── SummarizePlainPostQuery.graphql │ ├── SummarizeQuotePostQuery.graphql │ ├── SummarizeSharePostQuery.graphql │ ├── UserSnippetFragment.graphql │ ├── ViewerInfoQuery.graphql │ ├── ViewerMessageLimitUpdatedSubscription.graphql │ ├── ViewerStateFragment.graphql │ └── ViewerStateUpdatedSubscription.graphql ├── presets.js ├── secrets.js ├── sentencepiece │ ├── llama.model │ ├── mistral.model │ ├── nerdstash.model │ └── nerdstash_v2.model ├── sprites.js ├── stable-diffusion.js ├── thumbnails.js ├── tokenizers.js ├── transformers.mjs ├── translate.js ├── util.js ├── validator │ └── TavernCardValidator.js └── vectors.js ├── start.sh └── statsHelpers.js /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | npm-debug.log 4 | readme* 5 | Start.bat 6 | /dist 7 | /backups/ 8 | cloudflared.exe 9 | access.log 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | [*.{js, conf, json}] 9 | charset = utf-8 10 | indent_style = space 11 | indent_size = 4 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request ✨ 2 | description: Suggest an idea for future development of this project 3 | title: '[FEATURE_REQUEST] ' 4 | labels: ['enhancement'] 5 | 6 | body: 7 | 8 | # Field 1 - Did the user searched for similar requests 9 | - type: dropdown 10 | id: similarRequest 11 | attributes: 12 | label: Have you searched for similar requests? 13 | description: 14 | options: 15 | - 'No' 16 | - 'Yes' 17 | validations: 18 | required: false 19 | 20 | # Field 2 - Is it bug-related 21 | - type: textarea 22 | id: issue 23 | attributes: 24 | label: Is your feature request related to a problem? If so, please describe. 25 | description: 26 | placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 27 | validations: 28 | required: false 29 | 30 | # Field 3 - Describe feature 31 | - type: textarea 32 | id: solution 33 | attributes: 34 | label: Describe the solution you'd like 35 | placeholder: An outline of how you would like this to be implemented, include as much details as possible 36 | validations: 37 | required: true 38 | 39 | # Field 4 - Describe alternatives 40 | - type: textarea 41 | id: alternatives 42 | attributes: 43 | label: Describe alternatives you've considered 44 | placeholder: A clear and concise description of any alternative solutions or features you've considered. 45 | validations: 46 | required: false 47 | 48 | # Field 5 - Additional context 49 | - type: textarea 50 | id: addcontext 51 | attributes: 52 | label: Additional context 53 | placeholder: Add any other context or screenshots about the feature request here. 54 | validations: 55 | required: false 56 | 57 | # Field 6 - Priority 58 | - type: dropdown 59 | id: priority 60 | attributes: 61 | label: Priority 62 | description: How urgent is the development of this feature 63 | options: 64 | - Low (Nice-to-have) 65 | - Medium (Would be very useful) 66 | - High (The app does not function without it) 67 | validations: 68 | required: true 69 | 70 | # Field 7 - Can the user implement 71 | - type: dropdown 72 | id: canImplement 73 | attributes: 74 | label: Is this something you would be keen to implement? 75 | description: Are you raising this ticket in order to get an issue number for your PR? 76 | options: 77 | - 'No' 78 | - 'Maybe' 79 | - 'Yes!' 80 | validations: 81 | required: false 82 | 83 | # Final text 84 | - type: markdown 85 | attributes: 86 | value: |- 87 | ## Thanks 🙏 88 | Thank you for your feature suggestion. 89 | Please note that there is no guarantee that your idea will be implemented. 90 | validations: 91 | required: false 92 | -------------------------------------------------------------------------------- /.github/readme.md: -------------------------------------------------------------------------------- 1 | # SillyTavern-fix 2 | SillyTavern with Poe integration. Result of merging the Poe connection achieved by GlizzyChief to the latest SillyTavern version. This is a prototype and will be updated as bugs arise with the integration. 3 | 4 | ## How to install 5 | 6 | Just follow the steps for the GlizzyChief version, changing only the "git clone" to the version you want. 7 | 8 | - For the integration with latest SillyTavern 9 | 10 | - git clone https://github.com/LegendPoet/SillyTavern-fix.git -b main 11 | 12 | - For the integration with SillyTavern 1.9.7(most stable) 13 | 14 | - git clone https://github.com/LegendPoet/SillyTavern-fix.git -b stable 15 | 16 | 17 | Install or update to the (main) branch only if you need the latest SillyTavern improvements or want to support this new integration by providing feedback and reporting bugs. Otherwise, is recommend use or continue the 1.9.7-fix version(stable). 18 | 19 | From then on, you don't need any additional implementation. The original GlizzyChief project here: https://github.com/GlizzyChief/SillyTavern-1.8.4-fix 20 | 21 | ## It works the same as version 1.8.4? 22 | More or less. Basically this is the reintegration of the Poe options, this time using the GlizzyChief API for the connection. 23 | 24 | ## Credits 25 | All credits go to the SillyTavern team for their great work and continued support and improvements to the interface, as well as GlizzyChief, vfnm and ITSNOTPOEVER, who allow us to continue enjoying Poe with SillyTavern. Thanks guys! 26 | -------------------------------------------------------------------------------- /.github/workflows/build-and-publish-release.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Release (Release) 2 | 3 | on: 4 | push: 5 | branches: 6 | - release 7 | 8 | jobs: 9 | build_and_publish: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v2 15 | 16 | - name: Set up Node.js 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: 18 20 | 21 | - name: Install dependencies 22 | run: npm ci 23 | 24 | - name: Build and package with pkg 25 | run: | 26 | npm install -g pkg 27 | npm run pkg 28 | 29 | - name: Upload binaries to release 30 | uses: softprops/action-gh-release@v1 31 | with: 32 | files: dist/* 33 | tag_name: ci-release 34 | name: Continuous Release (Release) 35 | prerelease: true 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/build-and-publish-staging.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Release (Staging) 2 | 3 | on: 4 | push: 5 | branches: 6 | - staging 7 | 8 | jobs: 9 | build_and_publish: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v2 15 | 16 | - name: Set up Node.js 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: 18 20 | 21 | - name: Install dependencies 22 | run: npm ci 23 | 24 | - name: Build and package with pkg 25 | run: | 26 | npm install -g pkg 27 | npm run pkg 28 | 29 | - name: Upload binaries to release 30 | uses: softprops/action-gh-release@v1 31 | with: 32 | files: dist/* 33 | tag_name: ci-staging 34 | name: Continuous Release (Staging) 35 | prerelease: true 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will publish a docker image for every full release to the GitHub package repository 2 | 3 | name: Create Docker Image on Release 4 | 5 | on: 6 | release: 7 | # Only runs on full releases not pre releases 8 | types: [released] 9 | 10 | env: 11 | # This should allow creation of docker images even in forked repositories 12 | # Image name may not contain uppercase characters, so we can not use the repository name 13 | # Creates a string like: ghcr.io/SillyTavern/sillytavern 14 | image_name: ghcr.io/sillytavern/sillytavern 15 | 16 | jobs: 17 | 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v3 25 | 26 | # Build docker image using dockerfile and tag it with branch name 27 | # Assumes branch name is the version number 28 | - name: Build the Docker image 29 | run: | 30 | docker build . --file Dockerfile --tag $image_name:${{ github.ref_name }} 31 | 32 | # Login into package repository as the person who created the release 33 | - name: Login to GitHub Container Registry 34 | uses: docker/login-action@v1 35 | with: 36 | registry: ghcr.io 37 | username: ${{ github.actor }} 38 | password: ${{ secrets.GITHUB_TOKEN }} 39 | 40 | # Assumes release is the latest and marks image as such 41 | - name: Docker Tag and Push 42 | run: | 43 | docker tag $image_name:${{ github.ref_name }} $image_name:latest 44 | docker push $image_name:${{ github.ref_name }} 45 | docker push $image_name:latest 46 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - run: npm ci 19 | 20 | publish-npm: 21 | needs: build 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - uses: actions/setup-node@v3 26 | with: 27 | node-version: 16 28 | registry-url: https://registry.npmjs.org/ 29 | - run: npm ci 30 | - run: npm publish 31 | env: 32 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 33 | -------------------------------------------------------------------------------- /.github/workflows/update-docs.yml: -------------------------------------------------------------------------------- 1 | name: Update SillyTavern-Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | update_docs: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout current repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Checkout SillyTavern-Docs repository 17 | uses: actions/checkout@v2 18 | with: 19 | repository: SillyTavern/SillyTavern-Docs 20 | path: SillyTavern-Docs 21 | 22 | - name: Clone SillyTavern wiki into SillyTavern-Docs/extensions 23 | run: rm -rf SillyTavern-Docs/extensions && git clone https://github.com/SillyTavern/SillyTavern.wiki.git SillyTavern-Docs/extensions && rm -rf SillyTavern-Docs/extensions/.git 24 | 25 | - name: Copy files 26 | run: | 27 | cp public/notes/content.md SillyTavern-Docs/guidebook.md 28 | cp faq.md SillyTavern-Docs/faq.md 29 | cp readme.md SillyTavern-Docs/readme.md 30 | cp public/notes/update.md SillyTavern-Docs/update.md 31 | 32 | - name: Deploy to external repository 33 | uses: cpina/github-action-push-to-another-repository@main 34 | env: 35 | SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} 36 | with: 37 | # GitHub Action output files 38 | source-directory: SillyTavern-Docs/ 39 | destination-github-username: SillyTavern 40 | destination-repository-name: SillyTavern-Docs 41 | user-email: github-actions[bot]@users.noreply.github.com 42 | user-name: "GitHub Actions" 43 | target-branch: "main" 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/chats/ 3 | public/characters/ 4 | public/User Avatars/ 5 | public/backgrounds/ 6 | public/groups/ 7 | public/group chats/ 8 | public/worlds/ 9 | public/user/ 10 | public/css/bg_load.css 11 | public/themes/ 12 | public/OpenAI Settings/ 13 | public/KoboldAI Settings/ 14 | public/NovelAI Settings/ 15 | public/TextGen Settings/ 16 | public/instruct/ 17 | public/context/ 18 | public/scripts/extensions/third-party/ 19 | public/stats.json 20 | /uploads/ 21 | *.jsonl 22 | /config.conf 23 | /docker/config 24 | .DS_Store 25 | public/settings.json 26 | /thumbnails 27 | whitelist.txt 28 | .vscode 29 | .idea/ 30 | secrets.json 31 | /dist 32 | /backups/ 33 | public/movingUI/ 34 | public/QuickReplies/ 35 | content.log 36 | cloudflared.exe 37 | public/assets/ 38 | access.log 39 | /vectors/ 40 | /cache/ 41 | public/css/user.css 42 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /uploads/ 3 | .DS_Store 4 | /thumbnails 5 | secrets.json 6 | /dist 7 | /backups/ 8 | access.log 9 | -------------------------------------------------------------------------------- /.replit: -------------------------------------------------------------------------------- 1 | 2 | hidden = [".config", "package-lock.json"] 3 | run = "chmod 755 ./start.sh && ./start.sh" 4 | entrypoint = "server.js" 5 | 6 | [[hints]] 7 | regex = "Error \\[ERR_REQUIRE_ESM\\]" 8 | message = "We see that you are using require(...) inside your code. We currently do not support this syntax. Please use 'import' instead when using external modules. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)" 9 | 10 | [nix] 11 | channel = "stable-22_11" 12 | 13 | [env] 14 | XDG_CONFIG_HOME = "/home/runner/$REPL_SLUG/.config" 15 | PATH = "/home/runner/$REPL_SLUG/.config/npm/node_global/bin:/home/runner/$REPL_SLUG/node_modules/.bin" 16 | npm_config_prefix = "/home/runner/$REPL_SLUG/.config/npm/node_global" 17 | 18 | [gitHubImport] 19 | requiredFiles = [".replit", "replit.nix", ".config", "package.json", "package-lock.json"] 20 | 21 | [packager] 22 | language = "nodejs" 23 | 24 | [packager.features] 25 | packageSearch = true 26 | guessImports = true 27 | enabledForHosting = false 28 | 29 | [unitTest] 30 | language = "nodejs" 31 | 32 | [debugger] 33 | support = true 34 | 35 | [debugger.interactive] 36 | transport = "localhost:0" 37 | startCommand = [ "dap-node" ] 38 | 39 | [debugger.interactive.initializeMessage] 40 | command = "initialize" 41 | type = "request" 42 | 43 | [debugger.interactive.initializeMessage.arguments] 44 | clientID = "replit" 45 | clientName = "replit.com" 46 | columnsStartAt1 = true 47 | linesStartAt1 = true 48 | locale = "en-us" 49 | pathFormat = "path" 50 | supportsInvalidatedEvent = true 51 | supportsProgressReporting = true 52 | supportsRunInTerminalRequest = true 53 | supportsVariablePaging = true 54 | supportsVariableType = true 55 | 56 | [debugger.interactive.launchMessage] 57 | command = "launch" 58 | type = "request" 59 | 60 | [debugger.interactive.launchMessage.arguments] 61 | args = [] 62 | console = "externalTerminal" 63 | cwd = "." 64 | environment = [] 65 | pauseForSourceMap = false 66 | program = "./server.js" 67 | request = "launch" 68 | sourceMaps = true 69 | stopOnEntry = false 70 | type = "pwa-node" 71 | 72 | [languages] 73 | 74 | [languages.javascript] 75 | pattern = "**/{*.js,*.jsx,*.ts,*.tsx,*.json}" 76 | 77 | [languages.javascript.languageServer] 78 | start = "typescript-language-server --stdio" 79 | 80 | [deployment] 81 | run = ["sh", "-c", "./start.sh"] 82 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19.1.0-alpine3.16 2 | 3 | # Arguments 4 | ARG APP_HOME=/home/node/app 5 | 6 | # Install system dependencies 7 | RUN apk add gcompat tini git 8 | 9 | # Ensure proper handling of kernel signals 10 | ENTRYPOINT [ "tini", "--" ] 11 | 12 | # Create app directory 13 | WORKDIR ${APP_HOME} 14 | 15 | # Install app dependencies 16 | COPY package*.json post-install.js ./ 17 | RUN \ 18 | echo "*** Install npm packages ***" && \ 19 | npm install && npm cache clean --force 20 | 21 | # Bundle app source 22 | COPY . ./ 23 | 24 | # Copy default chats, characters and user avatars to <folder>.default folder 25 | RUN \ 26 | IFS="," RESOURCES="assets,backgrounds,user,context,instruct,QuickReplies,movingUI,themes,characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings" && \ 27 | \ 28 | echo "*** Store default $RESOURCES in <folder>.default ***" && \ 29 | for R in $RESOURCES; do mv "public/$R" "public/$R.default"; done || true && \ 30 | \ 31 | echo "*** Create symbolic links to config directory ***" && \ 32 | for R in $RESOURCES; do ln -s "../config/$R" "public/$R"; done || true && \ 33 | \ 34 | ln -s "./config/config.conf" "config.conf" || true && \ 35 | ln -s "../config/settings.json" "public/settings.json" || true && \ 36 | ln -s "../../config/bg_load.css" "public/css/bg_load.css" || true && \ 37 | mkdir "config" || true 38 | 39 | # Cleanup unnecessary files 40 | RUN \ 41 | echo "*** Cleanup ***" && \ 42 | mv "./docker/docker-entrypoint.sh" "./" && \ 43 | rm -rf "./docker" && \ 44 | echo "*** Make docker-entrypoint.sh executable ***" && \ 45 | chmod +x "./docker-entrypoint.sh" && \ 46 | echo "*** Convert line endings to Unix format ***" && \ 47 | dos2unix "./docker-entrypoint.sh" 48 | 49 | EXPOSE 8000 50 | 51 | CMD [ "./docker-entrypoint.sh" ] 52 | -------------------------------------------------------------------------------- /Remote-Link.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo ======================================================================================================================== 3 | echo WARNING: Cloudflare Tunnel! 4 | echo ======================================================================================================================== 5 | echo This script downloads and runs the latest cloudflared.exe from Cloudflare to set up an HTTPS tunnel to your SillyTavern! 6 | echo Using the randomly generated temporary tunnel URL, anyone can access your SillyTavern over the Internet while the tunnel 7 | echo is active. Keep the URL safe and secure your SillyTavern installation by setting a username and password in config.conf! 8 | echo. 9 | echo See https://docs.sillytavern.app/usage/remoteconnections/ for more details about how to secure your SillyTavern install. 10 | echo. 11 | echo By continuing you confirm that you're aware of the potential dangers of having a tunnel open and take all responsibility 12 | echo to properly use and secure it! 13 | echo. 14 | echo To abort, press Ctrl+C or close this window now! 15 | echo. 16 | pause 17 | if not exist cloudflared.exe curl -Lo cloudflared.exe https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe 18 | cloudflared.exe tunnel --url localhost:8000 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | We take the security of this project seriously. If you discover any security vulnerabilities or have concerns regarding the security of this repository, please reach out to us immediately. We appreciate your efforts in responsibly disclosing the issue and will make every effort to address it promptly. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | To report a security vulnerability, please follow these steps: 8 | 9 | 1. Go to the **Security** tab of this repository on GitHub. 10 | 2. Click on **"Report a vulnerability"**. 11 | 3. Provide a clear description of the vulnerability and its potential impact. Be as detailed as possible. 12 | 4. If applicable, include steps or a PoC (Proof of Concept) to reproduce the vulnerability. 13 | 5. Submit the report. 14 | 15 | Once we receive the private report notification, we will promptly investigate and assess the reported vulnerability. 16 | 17 | Please do not disclose any potential vulnerabilities in public repositories, issue trackers, or forums until we have had a chance to review and address the issue. 18 | 19 | ## Scope 20 | 21 | This security policy applies to all the code and files within this repository and its dependencies actively maintained by us. If you encounter a security issue in a dependency that is not directly maintained by us, please follow responsible disclosure practices and report it to the respective project. 22 | 23 | While we strive to ensure the security of this project, please note that there may be limitations on resources, response times, and mitigations. 24 | 25 | Thank you for your help in making this project more secure. 26 | -------------------------------------------------------------------------------- /Start.bat: -------------------------------------------------------------------------------- 1 | pushd %~dp0 2 | call npm install --no-audit 3 | node server.js 4 | pause 5 | popd 6 | -------------------------------------------------------------------------------- /Update-Instructions.txt: -------------------------------------------------------------------------------- 1 | How to Update SillyTavern 2 | 3 | The most recent version can be found here: https://docs.sillytavern.app/usage/update/ 4 | 5 | This is not an installation guide. If you need installation instructions, look here: 6 | https://docs.sillytavern.app/installation/windows/ 7 | 8 | This guide assumes you have already installed SillyTavern once, and know how to run it on your OS. 9 | 10 | Linux/Termux: 11 | 12 | You definitely installed via git, so just 'git pull' inside the SillyTavern directory. 13 | 14 | Windows/MacOS: 15 | 16 | Method 1 - GIT 17 | 18 | We always recommend users install using 'git'. Here's why: 19 | 20 | When you have installed via `git clone`, all you have to do to update is type `git pull` in a command line in the ST folder. 21 | You can also try running the 'UpdateAndStart.bat' file, which will almost do the same thing. (Windows only) 22 | Alternatively, if the command prompt gives you problems (and you have GitHub Desktop installed), you can use the 'Repository' menu and select 'Pull'. 23 | The updates are applied automatically and safely. 24 | 25 | Method 2 - ZIP 26 | 27 | If you insist on installing via a zip, here is the tedious process for doing the update: 28 | 29 | 1. Download the new release zip. 30 | 2. Unzip it into a folder OUTSIDE of your current ST installation. 31 | 3. Do the usual setup procedure for your OS to install the NodeJS requirements. 32 | 33 | 4. Copy the following files/folders as necessary(*) from your old ST installation: 34 | 35 | - Backgrounds 36 | - Characters 37 | - Chats 38 | - Groups 39 | - Group chats 40 | - KoboldAI Settings 41 | - NovelAI Settings 42 | - OpenAI Settings 43 | - TextGen Settings (textgen = ooba) 44 | - Themes 45 | - User Avatars 46 | - Worlds 47 | - settings.json 48 | 49 | (*) 'As necessary' = "If you made any custom content related to those folders". 50 | None of the folders are mandatory, so only copy what you need. 51 | 52 | **NB: DO NOT COPY THE ENTIRE /PUBLIC/ FOLDER.** 53 | Doing so could break the new install and prevent new features from being present. 54 | 55 | 5. Paste those items into the /Public/ folder of the new install. 56 | 57 | 6. Start SillyTavern once again with the method appropriate to your OS, and pray you got it right. 58 | 59 | 7. If everything shows up, you can safely delete the old ST folder. 60 | -------------------------------------------------------------------------------- /UpdateAndStart.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd %~dp0 3 | git --version > nul 2>&1 4 | if %errorlevel% neq 0 ( 5 | echo Git is not installed on this system. Skipping update. 6 | echo If you installed with a zip file, you will need to download the new zip and install it manually. 7 | ) else ( 8 | call git pull --rebase --autostash 9 | if %errorlevel% neq 0 ( 10 | REM incase there is still something wrong 11 | echo There were errors while updating. Please download the latest version manually. 12 | ) 13 | ) 14 | call npm install 15 | node server.js 16 | pause 17 | popd 18 | -------------------------------------------------------------------------------- /default/bg_load.css: -------------------------------------------------------------------------------- 1 | #bg1 {background-image: url(../backgrounds/__transparent.png);} 2 | -------------------------------------------------------------------------------- /default/config.conf: -------------------------------------------------------------------------------- 1 | const port = 8000; 2 | const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] 3 | const whitelistMode = true; //Disabling enabling the ip whitelist mode. true/false 4 | const basicAuthMode = false; //Toggle basic authentication for endpoints. 5 | const basicAuthUser = {username: "user", password: "password"}; //Login credentials when basicAuthMode is true. 6 | const disableThumbnails = false; //Disables the generation of thumbnails, opting to use the raw images instead 7 | const autorun = true; //Autorun in the browser. true/false 8 | const enableExtensions = true; //Enables support for TavernAI-extras project 9 | const listen = true; // If true, Can be access from other device or PC. otherwise can be access only from hosting machine. 10 | const allowKeysExposure = false; // If true, private API keys could be fetched to the frontend. 11 | const skipContentCheck = false; // If true, no new default content will be delivered to you. 12 | const thumbnailsQuality = 95; // Quality of thumbnails. 0-100 13 | const disableChatBackup = false; // Disables the backup of chat logs to the /backups folder 14 | 15 | // If true, Allows insecure settings for listen, whitelist, and authentication. 16 | // Change this setting only on "trusted networks". Do not change this value unless you are aware of the issues that can arise from changing this setting and configuring a insecure setting. 17 | const securityOverride = false; 18 | 19 | // Additional settings for extra modules / extensions 20 | const extras = { 21 | // Disables auto-download of models from the HuggingFace Hub. 22 | // You will need to manually download the models and put them into the /cache folder. 23 | disableAutoDownload: false, 24 | // Text classification model for sentiment analysis. HuggingFace ID of a model in ONNX format. 25 | classificationModel: 'Cohee/distilbert-base-uncased-go-emotions-onnx', 26 | // Image captioning model. HuggingFace ID of a model in ONNX format. 27 | captioningModel: 'Xenova/vit-gpt2-image-captioning', 28 | // Feature extraction model. HuggingFace ID of a model in ONNX format. 29 | embeddingModel: 'Xenova/all-mpnet-base-v2', 30 | // GPT-2 text generation model. HuggingFace ID of a model in ONNX format. 31 | promptExpansionModel: 'Cohee/fooocus_expansion-onnx', 32 | }; 33 | 34 | // Request overrides for additional headers 35 | // Format is an array of objects: 36 | // { hosts: [ "<url>" ], headers: { <header>: "<value>" } } 37 | const requestOverrides = []; 38 | 39 | module.exports = { 40 | port, 41 | whitelist, 42 | whitelistMode, 43 | basicAuthMode, 44 | basicAuthUser, 45 | autorun, 46 | enableExtensions, 47 | listen, 48 | disableThumbnails, 49 | allowKeysExposure, 50 | securityOverride, 51 | skipContentCheck, 52 | requestOverrides, 53 | thumbnailsQuality, 54 | extras, 55 | disableChatBackup, 56 | }; 57 | -------------------------------------------------------------------------------- /default/content/Seraphina/admiration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/admiration.png -------------------------------------------------------------------------------- /default/content/Seraphina/amusement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/amusement.png -------------------------------------------------------------------------------- /default/content/Seraphina/anger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/anger.png -------------------------------------------------------------------------------- /default/content/Seraphina/annoyance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/annoyance.png -------------------------------------------------------------------------------- /default/content/Seraphina/approval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/approval.png -------------------------------------------------------------------------------- /default/content/Seraphina/caring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/caring.png -------------------------------------------------------------------------------- /default/content/Seraphina/confusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/confusion.png -------------------------------------------------------------------------------- /default/content/Seraphina/curiosity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/curiosity.png -------------------------------------------------------------------------------- /default/content/Seraphina/desire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/desire.png -------------------------------------------------------------------------------- /default/content/Seraphina/disappointment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/disappointment.png -------------------------------------------------------------------------------- /default/content/Seraphina/disapproval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/disapproval.png -------------------------------------------------------------------------------- /default/content/Seraphina/disgust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/disgust.png -------------------------------------------------------------------------------- /default/content/Seraphina/embarrassment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/embarrassment.png -------------------------------------------------------------------------------- /default/content/Seraphina/excitement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/excitement.png -------------------------------------------------------------------------------- /default/content/Seraphina/fear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/fear.png -------------------------------------------------------------------------------- /default/content/Seraphina/gratitude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/gratitude.png -------------------------------------------------------------------------------- /default/content/Seraphina/grief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/grief.png -------------------------------------------------------------------------------- /default/content/Seraphina/joy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/joy.png -------------------------------------------------------------------------------- /default/content/Seraphina/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/love.png -------------------------------------------------------------------------------- /default/content/Seraphina/nervousness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/nervousness.png -------------------------------------------------------------------------------- /default/content/Seraphina/neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/neutral.png -------------------------------------------------------------------------------- /default/content/Seraphina/optimism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/optimism.png -------------------------------------------------------------------------------- /default/content/Seraphina/pride.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/pride.png -------------------------------------------------------------------------------- /default/content/Seraphina/realization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/realization.png -------------------------------------------------------------------------------- /default/content/Seraphina/relief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/relief.png -------------------------------------------------------------------------------- /default/content/Seraphina/remorse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/remorse.png -------------------------------------------------------------------------------- /default/content/Seraphina/sadness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/sadness.png -------------------------------------------------------------------------------- /default/content/Seraphina/surprise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/Seraphina/surprise.png -------------------------------------------------------------------------------- /default/content/default_CodingSensei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/default_CodingSensei.png -------------------------------------------------------------------------------- /default/content/default_FluxTheCat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/default_FluxTheCat.png -------------------------------------------------------------------------------- /default/content/default_Seraphina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/default_Seraphina.png -------------------------------------------------------------------------------- /default/content/index.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "filename": "default_Seraphina.png", 4 | "type": "character" 5 | }, 6 | { 7 | "filename": "default_CodingSensei.png", 8 | "type": "character" 9 | }, 10 | { 11 | "filename": "default_FluxTheCat.png", 12 | "type": "character" 13 | }, 14 | { 15 | "filename": "Seraphina", 16 | "type": "sprites" 17 | }, 18 | { 19 | "filename": "Eldoria.json", 20 | "type": "world" 21 | }, 22 | { 23 | "filename": "user-default.png", 24 | "type": "avatar" 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /default/content/user-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/default/content/user-default.png -------------------------------------------------------------------------------- /default/user.css: -------------------------------------------------------------------------------- 1 | /* Put custom styles here. */ 2 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | sillytavern: 4 | build: .. 5 | container_name: sillytavern 6 | hostname: sillytavern 7 | image: sillytavern/sillytavern:latest 8 | ports: 9 | - "8000:8000" 10 | volumes: 11 | - "./config:/home/node/app/config" 12 | - "./user:/home/node/app/public/user" 13 | restart: unless-stopped 14 | -------------------------------------------------------------------------------- /docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Initialize missing user files 4 | IFS="," RESOURCES="assets,backgrounds,user,context,instruct,QuickReplies,movingUI,themes,characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings" 5 | for R in $RESOURCES; do 6 | if [ ! -e "config/$R" ]; then 7 | echo "Resource not found, copying from defaults: $R" 8 | cp -r "public/$R.default" "config/$R" 9 | fi 10 | done 11 | 12 | if [ ! -e "config/config.conf" ]; then 13 | echo "Resource not found, copying from defaults: config.conf" 14 | cp -r "default/config.conf" "config/config.conf" 15 | fi 16 | 17 | if [ ! -e "config/settings.json" ]; then 18 | echo "Resource not found, copying from defaults: settings.json" 19 | cp -r "default/settings.json" "config/settings.json" 20 | fi 21 | 22 | if [ ! -e "config/bg_load.css" ]; then 23 | echo "Resource not found, copying from defaults: bg_load.css" 24 | cp -r "default/bg_load.css" "config/bg_load.css" 25 | fi 26 | 27 | CONFIG_FILE="config.conf" 28 | 29 | if grep -q "listen = false" $CONFIG_FILE; then 30 | echo -e "\033[1;31mThe listen parameter is set to false. If you can't connect to the server, edit the \"docker/config/config.conf\" file and restart the container.\033[0m" 31 | sleep 5 32 | fi 33 | 34 | if grep -q "whitelistMode = true" $CONFIG_FILE; then 35 | echo -e "\033[1;31mThe whitelistMode parameter is set to true. If you can't connect to the server, edit the \"docker/config/config.conf\" file and restart the container.\033[0m" 36 | sleep 5 37 | fi 38 | 39 | # Start the server 40 | exec node server.js 41 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "target": "ESNext", 5 | "moduleResolution": "node", 6 | "strictNullChecks": true, 7 | "strictFunctionTypes": true, 8 | "checkJs": true, 9 | "allowUmdGlobalAccess": true, 10 | "allowSyntheticDefaultImports": true, 11 | "resolveJsonModule": true 12 | }, 13 | "exclude": [ 14 | "node_modules", 15 | "**/node_modules/*" 16 | ] 17 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@agnai/sentencepiece-js": "^1.1.1", 4 | "@agnai/web-tokenizers": "^0.1.3", 5 | "@dqbd/tiktoken": "^1.0.2", 6 | "command-exists": "^1.2.9", 7 | "compression": "^1", 8 | "cookie-parser": "^1.4.6", 9 | "cors": "^2.8.5", 10 | "csrf-csrf": "^2.2.3", 11 | "device-detector-js": "^3.0.3", 12 | "express": "^4.18.2", 13 | "google-translate-api-browser": "^3.0.1", 14 | "bing-translate-api": "^2.9.1", 15 | "gpt3-tokenizer": "^1.1.5", 16 | "ip-matching": "^2.1.2", 17 | "ipaddr.js": "^2.0.1", 18 | "jimp": "^0.22.10", 19 | "json5": "^2.2.3", 20 | "lodash": "^4.17.21", 21 | "mime-types": "^2.1.35", 22 | "multer": "^1.4.5-lts.1", 23 | "node-fetch": "^2.6.11", 24 | "open": "^8.4.2", 25 | "png-chunk-text": "^1.0.0", 26 | "png-chunks-encode": "^1.0.0", 27 | "png-chunks-extract": "^1.0.0", 28 | "puppeteer-core": "^21.0.1", 29 | "puppeteer-extra": "^3.3.6", 30 | "puppeteer-extra-plugin-stealth": "^2.11.2", 31 | "random-useragent": "^0.5.0", 32 | "response-time": "^2.3.2", 33 | "sanitize-filename": "^1.6.3", 34 | "sillytavern-transformers": "^2.7.3", 35 | "simple-git": "^3.19.1", 36 | "turndown": "^7.1.2", 37 | "uniqolor": "^1.1.0", 38 | "vectra": "^0.2.2", 39 | "write-file-atomic": "^5.0.1", 40 | "webp-converter": "2.3.2", 41 | "ws": "^8.13.0", 42 | "yargs": "^17.7.1", 43 | "yauzl": "^2.10.0" 44 | }, 45 | "overrides": { 46 | "parse-bmfont-xml": { 47 | "xml2js": "^0.5.0" 48 | }, 49 | "vectra": { 50 | "openai": "^4.17.0" 51 | } 52 | }, 53 | "name": "sillytavern", 54 | "type": "commonjs", 55 | "license": "AGPL-3.0", 56 | "repository": { 57 | "type": "git", 58 | "url": "https://github.com/SillyTavern/SillyTavern.git" 59 | }, 60 | "version": "1.10.9", 61 | "scripts": { 62 | "start": "node server.js", 63 | "start-multi": "node server.js --disableCsrf", 64 | "pkg": "pkg --compress Gzip --no-bytecode --public .", 65 | "postinstall": "node post-install.js" 66 | }, 67 | "bin": { 68 | "sillytavern": "./server.js" 69 | }, 70 | "rules": { 71 | "no-path-concat": "off", 72 | "no-var": "off" 73 | }, 74 | "main": "server.js", 75 | "pkg": { 76 | "targets": [ 77 | "node18-linux-x64", 78 | "node18-macos-x64", 79 | "node18-windows-x64" 80 | ], 81 | "assets": [ 82 | "node_modules/**/*" 83 | ], 84 | "outputPath": "dist", 85 | "scripts": [ 86 | "server.js" 87 | ] 88 | }, 89 | "devDependencies": { 90 | "jquery": "^3.6.4", 91 | "pkg": "^5.8.1", 92 | "pkg-fetch": "^3.5.2" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /post-install.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Scripts to be done before starting the server for the first time. 3 | */ 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const crypto = require('crypto'); 7 | 8 | /** 9 | * Creates the default config files if they don't exist yet. 10 | */ 11 | function createDefaultFiles() { 12 | const files = { 13 | settings: './public/settings.json', 14 | bg_load: './public/css/bg_load.css', 15 | config: './config.conf', 16 | user: './public/css/user.css', 17 | }; 18 | 19 | for (const file of Object.values(files)) { 20 | try { 21 | if (!fs.existsSync(file)) { 22 | const defaultFilePath = path.join('./default', path.parse(file).base); 23 | fs.copyFileSync(defaultFilePath, file); 24 | console.log(`Created default file: ${file}`); 25 | } 26 | } catch (error) { 27 | console.error(`FATAL: Could not write default file: ${file}`, error); 28 | } 29 | } 30 | } 31 | 32 | /** 33 | * Returns the MD5 hash of the given data. 34 | * @param {Buffer} data Input data 35 | * @returns {string} MD5 hash of the input data 36 | */ 37 | function getMd5Hash(data) { 38 | return crypto 39 | .createHash('md5') 40 | .update(data) 41 | .digest('hex'); 42 | } 43 | 44 | /** 45 | * Copies the WASM binaries from the sillytavern-transformers package to the dist folder. 46 | */ 47 | function copyWasmFiles() { 48 | if (!fs.existsSync('./dist')) { 49 | fs.mkdirSync('./dist'); 50 | } 51 | 52 | const listDir = fs.readdirSync('./node_modules/sillytavern-transformers/dist'); 53 | 54 | for (const file of listDir) { 55 | if (file.endsWith('.wasm')) { 56 | const sourcePath = `./node_modules/sillytavern-transformers/dist/${file}`; 57 | const targetPath = `./dist/${file}`; 58 | 59 | // Don't copy if the file already exists and is the same checksum 60 | if (fs.existsSync(targetPath)) { 61 | const sourceChecksum = getMd5Hash(fs.readFileSync(sourcePath)); 62 | const targetChecksum = getMd5Hash(fs.readFileSync(targetPath)); 63 | 64 | if (sourceChecksum === targetChecksum) { 65 | continue; 66 | } 67 | } 68 | 69 | fs.copyFileSync(sourcePath, targetPath); 70 | console.log(`${file} successfully copied to ./dist/${file}`); 71 | } 72 | } 73 | } 74 | 75 | try { 76 | // 1. Create default config files 77 | createDefaultFiles(); 78 | // 2. Copy transformers WASM binaries from node_modules 79 | copyWasmFiles(); 80 | } catch (error) { 81 | console.error(error); 82 | } 83 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Asper-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [5, 0, 1, 3], 3 | "temperature": 1.16, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 175, 7 | "typical_p": 0.96, 8 | "tail_free_sampling": 0.994, 9 | "repetition_penalty": 1.68, 10 | "repetition_penalty_range": 2240, 11 | "repetition_penalty_slope": 1.5, 12 | "repetition_penalty_frequency": 0, 13 | "repetition_penalty_presence": 0.005, 14 | "use_cache": false, 15 | "return_full_text": false, 16 | "prefix": "vanilla", 17 | "cfg_scale": 1, 18 | "phrase_rep_pen": "medium", 19 | "max_context": 7800 20 | } 21 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Blended-Coffee-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [6, 0, 1, 2, 3], 3 | "temperature": 1, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 25, 7 | "top_p": 1, 8 | "tail_free_sampling": 0.925, 9 | "repetition_penalty": 1.6, 10 | "repetition_penalty_frequency": 0.001, 11 | "repetition_penalty_range": 0, 12 | "repetition_penalty_presence": 0, 13 | "use_cache": false, 14 | "return_full_text": false, 15 | "prefix": "vanilla", 16 | "phrase_rep_pen": "medium", 17 | "cfg_scale": 1.55, 18 | "max_context": 7800 19 | } 20 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Blook-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [6, 2, 3, 1, 0], 3 | "temperature": 1, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 0, 7 | "top_p": 0.96, 8 | "tail_free_sampling": 0.96, 9 | "repetition_penalty": 2, 10 | "repetition_penalty_slope": 1, 11 | "repetition_penalty_frequency": 0.02, 12 | "repetition_penalty_range": 0, 13 | "repetition_penalty_presence": 0.3, 14 | "use_cache": false, 15 | "return_full_text": false, 16 | "prefix": "vanilla", 17 | "phrase_rep_pen": "very_aggressive", 18 | "cfg_scale": 1.3, 19 | "max_context": 7800 20 | } 21 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Carefree-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [2, 3, 0, 4, 1], 3 | "temperature": 1.35, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 15, 7 | "top_p": 0.85, 8 | "top_a": 0.1, 9 | "tail_free_sampling": 0.915, 10 | "repetition_penalty": 2.8, 11 | "repetition_penalty_range": 2048, 12 | "repetition_penalty_slope": 0.02, 13 | "repetition_penalty_frequency": 0.02, 14 | "repetition_penalty_presence": 0, 15 | "use_cache": false, 16 | "return_full_text": false, 17 | "prefix": "vanilla", 18 | "cfg_scale": 1, 19 | "phrase_rep_pen": "aggressive", 20 | "max_context": 7800 21 | } 22 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Edgewise-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [4, 0, 5, 3, 2], 3 | "temperature": 1.09, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_p": 0.969, 7 | "top_a": 0.09, 8 | "typical_p": 0.99, 9 | "tail_free_sampling": 0.969, 10 | "repetition_penalty": 1.09, 11 | "repetition_penalty_range": 8192, 12 | "repetition_penalty_slope": 0.069, 13 | "repetition_penalty_frequency": 0.006, 14 | "repetition_penalty_presence": 0.009, 15 | "use_cache": false, 16 | "return_full_text": false, 17 | "prefix": "vanilla", 18 | "cfg_scale": 1, 19 | "phrase_rep_pen": "very_light", 20 | "max_context": 7800 21 | } 22 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Fresh-Coffee-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [0, 1, 2, 3], 3 | "temperature": 1, 4 | "max_length": 40, 5 | "min_length": 1, 6 | "top_k": 25, 7 | "top_p": 1, 8 | "top_a": 0, 9 | "typical_p": 1, 10 | "tail_free_sampling": 0.925, 11 | "repetition_penalty": 1.9, 12 | "repetition_penalty_range": 768, 13 | "repetition_penalty_slope": 3.33, 14 | "repetition_penalty_frequency": 0.0025, 15 | "repetition_penalty_presence": 0.001, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "cfg_scale": 1, 20 | "phrase_rep_pen": "very_light", 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Fresh-Coffee-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [0, 1, 2, 3], 3 | "temperature": 1, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 25, 7 | "top_p": 1, 8 | "tail_free_sampling": 0.925, 9 | "repetition_penalty": 1.9, 10 | "repetition_penalty_range": 768, 11 | "repetition_penalty_slope": 1, 12 | "repetition_penalty_frequency": 0.0025, 13 | "repetition_penalty_presence": 0.001, 14 | "use_cache": false, 15 | "return_full_text": false, 16 | "prefix": "vanilla", 17 | "cfg_scale": 1, 18 | "phrase_rep_pen": "off", 19 | "max_context": 7800 20 | } 21 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Green-Active-Writer-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [6, 0, 8, 5, 3], 3 | "temperature": 1.5, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "typical_p": 0.95, 7 | "tail_free_sampling": 0.95, 8 | "mirostat_lr": 0.2, 9 | "mirostat_tau": 5.5, 10 | "repetition_penalty": 1, 11 | "repetition_penalty_range": 1632, 12 | "repetition_penalty_frequency": 0, 13 | "repetition_penalty_presence": 0, 14 | "use_cache": false, 15 | "return_full_text": false, 16 | "prefix": "vanilla", 17 | "phrase_rep_pen": "very_aggressive", 18 | "cfg_scale": 1.4, 19 | "max_context": 7800 20 | } 21 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Keelback-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [4, 5, 0, 3], 3 | "temperature": 1.18, 4 | "max_length": 40, 5 | "min_length": 1, 6 | "top_a": 0.022, 7 | "top_k": 0, 8 | "top_p": 1, 9 | "typical_p": 0.9, 10 | "tail_free_sampling": 0.956, 11 | "repetition_penalty": 1.25, 12 | "repetition_penalty_range": 4096, 13 | "repetition_penalty_slope": 0.9, 14 | "repetition_penalty_frequency": 0, 15 | "repetition_penalty_presence": 0, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "cfg_scale": 1, 20 | "phrase_rep_pen": "very_light", 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Long-Press-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [0, 4, 1, 5, 3], 3 | "temperature": 1.155, 4 | "max_length": 40, 5 | "min_length": 1, 6 | "top_k": 25, 7 | "top_a": 0.3, 8 | "top_p": 1, 9 | "typical_p": 0.96, 10 | "tail_free_sampling": 0.895, 11 | "repetition_penalty": 1.0125, 12 | "repetition_penalty_range": 2048, 13 | "repetition_penalty_slope": 3.33, 14 | "repetition_penalty_frequency": 0.011, 15 | "repetition_penalty_presence": 0.005, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "cfg_scale": 1, 20 | "phrase_rep_pen": "very_light", 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Pilotfish-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [6, 0, 4, 1, 2, 5, 3], 3 | "temperature": 1.31, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 25, 7 | "top_p": 0.97, 8 | "top_a": 0.18, 9 | "typical_p": 0.98, 10 | "tail_free_sampling": 1, 11 | "repetition_penalty": 1.55, 12 | "repetition_penalty_frequency": 0.00075, 13 | "repetition_penalty_presence": 0.00085, 14 | "repetition_penalty_range": 8192, 15 | "repetition_penalty_slope": 1.8, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "phrase_rep_pen": "medium", 20 | "cfg_scale": 1.35, 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Pro_Writer-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [3, 4, 5, 0], 3 | "temperature": 1.06, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_a": 0.146, 7 | "typical_p": 0.976, 8 | "tail_free_sampling": 0.969, 9 | "repetition_penalty": 1.86, 10 | "repetition_penalty_slope": 2.33, 11 | "repetition_penalty_frequency": 0, 12 | "repetition_penalty_presence": 0, 13 | "repetition_penalty_range": 2048, 14 | "use_cache": false, 15 | "return_full_text": false, 16 | "prefix": "vanilla", 17 | "phrase_rep_pen": "medium", 18 | "cfg_scale": 1.0, 19 | "max_context": 7800 20 | } 21 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Stelenes-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [3, 0, 5], 3 | "temperature": 2.5, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "typical_p": 0.969, 7 | "tail_free_sampling": 0.941, 8 | "repetition_penalty": 1, 9 | "repetition_penalty_range": 1024, 10 | "repetition_penalty_frequency": 0, 11 | "repetition_penalty_presence": 0, 12 | "use_cache": false, 13 | "return_full_text": false, 14 | "prefix": "vanilla", 15 | "phrase_rep_pen": "medium", 16 | "max_context": 7800 17 | } 18 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Talker-Chat-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [1, 5, 0, 2, 3, 4], 3 | "temperature": 1.5, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_k": 10, 7 | "top_p": 0.75, 8 | "top_a": 0.08, 9 | "typical_p": 0.975, 10 | "tail_free_sampling": 0.967, 11 | "repetition_penalty": 2.25, 12 | "repetition_penalty_range": 8192, 13 | "repetition_penalty_slope": 0.09, 14 | "repetition_penalty_frequency": 0, 15 | "repetition_penalty_presence": 0.005, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "cfg_scale": 1, 20 | "phrase_rep_pen": "very_light", 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Tea_Time-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [5, 0, 4], 3 | "temperature": 1, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_a": 0.017, 7 | "typical_p": 0.975, 8 | "repetition_penalty": 3, 9 | "repetition_penalty_slope": 0.09, 10 | "repetition_penalty_frequency": 0, 11 | "repetition_penalty_presence": 0, 12 | "repetition_penalty_range": 7680, 13 | "use_cache": false, 14 | "return_full_text": false, 15 | "prefix": "vanilla", 16 | "phrase_rep_pen": "aggressive", 17 | "cfg_scale": 1.0, 18 | "max_context": 7800 19 | } 20 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Tesseract-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [6, 0, 5], 3 | "temperature": 0.895, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "typical_p": 0.9, 7 | "repetition_penalty": 2, 8 | "repetition_penalty_slope": 3.2, 9 | "repetition_penalty_frequency": 0, 10 | "repetition_penalty_presence": 0, 11 | "repetition_penalty_range": 4048, 12 | "use_cache": false, 13 | "return_full_text": false, 14 | "prefix": "vanilla", 15 | "phrase_rep_pen": "aggressive", 16 | "cfg_scale": 1.3, 17 | "max_context": 7800 18 | } 19 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Vingt-Un-Clio.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [0, 5, 3, 2, 1], 3 | "temperature": 1.21, 4 | "max_length": 40, 5 | "min_length": 1, 6 | "top_k": 0, 7 | "top_p": 0.912, 8 | "top_a": 1, 9 | "typical_p": 0.912, 10 | "tail_free_sampling": 0.921, 11 | "repetition_penalty": 1.21, 12 | "repetition_penalty_range": 321, 13 | "repetition_penalty_slope": 3.33, 14 | "repetition_penalty_frequency": 0.00621, 15 | "repetition_penalty_presence": 0, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "cfg_scale": 1, 20 | "phrase_rep_pen": "very_light", 21 | "max_context": 7800 22 | } 23 | -------------------------------------------------------------------------------- /public/NovelAI Settings/Writers-Daemon-Kayra.settings: -------------------------------------------------------------------------------- 1 | { 2 | "order": [8, 0, 5, 3, 2, 4], 3 | "temperature": 1.5, 4 | "max_length": 150, 5 | "min_length": 1, 6 | "top_a": 0.02, 7 | "top_p": 0.95, 8 | "typical_p": 0.95, 9 | "tail_free_sampling": 0.95, 10 | "mirostat_lr": 0.25, 11 | "mirostat_tau": 5, 12 | "repetition_penalty": 1.625, 13 | "repetition_penalty_range": 2016, 14 | "repetition_penalty_frequency": 0, 15 | "repetition_penalty_presence": 0, 16 | "use_cache": false, 17 | "return_full_text": false, 18 | "prefix": "vanilla", 19 | "phrase_rep_pen": "very_aggressive", 20 | "max_context": 7800 21 | } 22 | -------------------------------------------------------------------------------- /public/backgrounds/__transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/__transparent.png -------------------------------------------------------------------------------- /public/backgrounds/_black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/_black.jpg -------------------------------------------------------------------------------- /public/backgrounds/_white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/_white.jpg -------------------------------------------------------------------------------- /public/backgrounds/bedroom clean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/bedroom clean.jpg -------------------------------------------------------------------------------- /public/backgrounds/bedroom cyberpunk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/bedroom cyberpunk.jpg -------------------------------------------------------------------------------- /public/backgrounds/bedroom red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/bedroom red.jpg -------------------------------------------------------------------------------- /public/backgrounds/bedroom tatami.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/bedroom tatami.jpg -------------------------------------------------------------------------------- /public/backgrounds/cityscape medieval market.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/cityscape medieval market.jpg -------------------------------------------------------------------------------- /public/backgrounds/cityscape medieval night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/cityscape medieval night.jpg -------------------------------------------------------------------------------- /public/backgrounds/cityscape postapoc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/cityscape postapoc.jpg -------------------------------------------------------------------------------- /public/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg -------------------------------------------------------------------------------- /public/backgrounds/japan classroom side.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/japan classroom side.jpg -------------------------------------------------------------------------------- /public/backgrounds/japan classroom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/japan classroom.jpg -------------------------------------------------------------------------------- /public/backgrounds/japan path cherry blossom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/japan path cherry blossom.jpg -------------------------------------------------------------------------------- /public/backgrounds/japan university.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/japan university.jpg -------------------------------------------------------------------------------- /public/backgrounds/landscape autumn great tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape autumn great tree.jpg -------------------------------------------------------------------------------- /public/backgrounds/landscape beach day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape beach day.png -------------------------------------------------------------------------------- /public/backgrounds/landscape beach night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape beach night.jpg -------------------------------------------------------------------------------- /public/backgrounds/landscape mountain lake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape mountain lake.jpg -------------------------------------------------------------------------------- /public/backgrounds/landscape postapoc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape postapoc.jpg -------------------------------------------------------------------------------- /public/backgrounds/landscape winter lake house.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/landscape winter lake house.jpg -------------------------------------------------------------------------------- /public/backgrounds/royal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/royal.jpg -------------------------------------------------------------------------------- /public/backgrounds/tavern day.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/backgrounds/tavern day.jpg -------------------------------------------------------------------------------- /public/context/Pygmalion.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pygmalion", 3 | "story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}", 4 | "chat_start": "", 5 | "example_separator": "" 6 | } 7 | -------------------------------------------------------------------------------- /public/css/bright.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | Theme: Bright 3 | Author: Chris Kempson (http://chriskempson.com) 4 | License: ~ MIT (or more permissive) [via base16-schemes-source] 5 | Maintainer: @highlightjs/core-team 6 | Version: 2021.09.0 7 | */pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e0e0e0;background:#000}.hljs ::selection,.hljs::selection{background-color:#505050;color:#e0e0e0}.hljs-comment{color:#b0b0b0}.hljs-tag{color:#d0d0d0}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#e0e0e0}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#fb0120}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#fc6d24}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#fda331}.hljs-strong{font-weight:700;color:#fda331}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#a1c659}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#76c7b7}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#6fb3d2}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#d381c3}.hljs-emphasis{color:#d381c3;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#be643c}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700} -------------------------------------------------------------------------------- /public/css/character-group-overlay.css: -------------------------------------------------------------------------------- 1 | 2 | #rm_print_characters_block.group_overlay_mode_select .character_select { 3 | transition: background-color 0.4s ease; 4 | margin-bottom: 1px; 5 | background-color: rgba(170, 170, 170, 0.15); 6 | } 7 | 8 | #rm_print_characters_block.group_overlay_mode_select .bogus_folder_select, 9 | #rm_print_characters_block.group_overlay_mode_select .group_select { 10 | cursor: auto; 11 | filter: saturate(0.3); 12 | } 13 | 14 | #rm_print_characters_block.group_overlay_mode_select .bogus_folder_select:hover, 15 | #rm_print_characters_block.group_overlay_mode_select .group_select:hover { 16 | background: none; 17 | } 18 | 19 | #rm_print_characters_block.group_overlay_mode_select .character_select input.bulk_select_checkbox { 20 | display: none !important; 21 | } 22 | 23 | #rm_print_characters_block.group_overlay_mode_select .character_select.character_selected { 24 | background-color: var(--SmartThemeQuoteColor); 25 | } 26 | 27 | #rm_print_characters_block.group_overlay_mode_select .character_select .bulk_select_checkbox { 28 | visibility: hidden; 29 | height: 0 !important; 30 | } 31 | 32 | #character_context_menu.hidden { display: none; } 33 | #character_context_menu { 34 | position: absolute; 35 | padding: 3px; 36 | z-index: 9998; 37 | background-color: var(--black90a); 38 | border: 1px solid var(--black90a); 39 | border-radius: 10px; 40 | } 41 | 42 | #character_context_menu ul li button { 43 | border: 0; 44 | border-bottom-color: currentcolor; 45 | color: var(--SmartThemeQuoteColor); 46 | background-color: transparent; 47 | font-weight: bold; 48 | font-size: 1em; 49 | padding: 0.5em; 50 | border-bottom: 1px dotted var(--SmartThemeQuoteColor); 51 | width: 100%; 52 | cursor: pointer; 53 | } 54 | 55 | #character_context_menu ul li button:hover { 56 | background-color: var(--SmartThemeBlurTintColor); 57 | } 58 | 59 | #character_context_menu ul li:last-child button { 60 | border-bottom: 0; 61 | } 62 | 63 | #character_context_menu ul li #character_context_menu_delete { 64 | color: var(--fullred); 65 | } 66 | 67 | #character_context_menu ul { 68 | list-style-type: none; 69 | padding: 0; 70 | margin: 0; 71 | } 72 | 73 | #character_context_menu .character_context_menu_separator { 74 | height: 1px; 75 | background-color: var(--SmartThemeBotMesBlurTintColor); 76 | } 77 | 78 | #character_context_menu li:hover { 79 | background-color: var(--SmartThemeBotMesBlurTintColor); 80 | } 81 | 82 | #bulkEditButton.bulk_edit_overlay_active { 83 | color: var(--golden); 84 | } 85 | 86 | #bulk_tag_shadow_popup { 87 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); 88 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); 89 | background-color: var(--black30a); 90 | position: absolute; 91 | width: 100%; 92 | height: 100vh; 93 | height: 100svh; 94 | z-index: 9998; 95 | top: 0; 96 | } 97 | 98 | #bulk_tag_shadow_popup #bulk_tag_popup { 99 | padding: 1em; 100 | } 101 | 102 | #bulk_tag_shadow_popup #bulk_tag_popup #dialogue_popup_controls .menu_button { 103 | width: 100px; 104 | padding: 0.25em; 105 | } 106 | -------------------------------------------------------------------------------- /public/css/group-avatars.css: -------------------------------------------------------------------------------- 1 | .avatar_collage { 2 | border-radius: 50%; 3 | position: relative; 4 | overflow: hidden; 5 | } 6 | 7 | .avatar_collage img { 8 | position: absolute; 9 | overflow: hidden; 10 | } 11 | 12 | .collage_2 .img_1 { 13 | left: 0; 14 | top: 0; 15 | max-width: 50%; 16 | max-height: 100%; 17 | width: 50%; 18 | height: 100%; 19 | } 20 | 21 | .collage_2 .img_2 { 22 | left: 50%; 23 | top: 0; 24 | max-width: 50%; 25 | max-height: 100%; 26 | width: 50%; 27 | height: 100%; 28 | } 29 | 30 | .collage_3 .img_1 { 31 | left: 0; 32 | top: 0; 33 | max-width: 50%; 34 | max-height: 50%; 35 | width: 50%; 36 | height: 50%; 37 | } 38 | 39 | .collage_3 .img_2 { 40 | left: 50%; 41 | top: 0; 42 | max-width: 50%; 43 | max-height: 50%; 44 | width: 50%; 45 | height: 50%; 46 | } 47 | 48 | .collage_3 .img_3 { 49 | left: 0; 50 | top: 50%; 51 | max-width: 100%; 52 | max-height: 50%; 53 | width: 100%; 54 | height: 50%; 55 | } 56 | 57 | .collage_4 .img_1 { 58 | left: 0; 59 | top: 0; 60 | max-width: 50%; 61 | max-height: 50%; 62 | width: 50%; 63 | height: 50%; 64 | } 65 | 66 | .collage_4 .img_2 { 67 | left: 50%; 68 | top: 0; 69 | max-width: 50%; 70 | max-height: 50%; 71 | width: 50%; 72 | height: 50%; 73 | } 74 | 75 | .collage_4 .img_3 { 76 | left: 0; 77 | top: 50%; 78 | max-width: 50%; 79 | max-height: 50%; 80 | width: 50%; 81 | height: 50%; 82 | } 83 | 84 | .collage_4 .img_4 { 85 | left: 50%; 86 | top: 50%; 87 | max-width: 50%; 88 | max-height: 50%; 89 | width: 50%; 90 | height: 50%; 91 | } -------------------------------------------------------------------------------- /public/css/loader.css: -------------------------------------------------------------------------------- 1 | #loader { 2 | position: fixed; 3 | margin: 0; 4 | padding: 0; 5 | top: 0; 6 | left: 0; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | z-index: 999999; 11 | width: 100vw; 12 | height: 100vh; 13 | width: 100svw; 14 | height: 100svh; 15 | background-color: var(--SmartThemeBlurTintColor); 16 | /*for some reason the full screen blur does not work on iOS*/ 17 | backdrop-filter: blur(30px); 18 | color: var(--SmartThemeBodyColor); 19 | opacity: 1; 20 | } 21 | 22 | #load-spinner { 23 | transition: all 300ms ease-out; 24 | opacity: 1; 25 | } -------------------------------------------------------------------------------- /public/css/solid.css: -------------------------------------------------------------------------------- 1 | :root, 2 | :host { 3 | --fa-style-family-classic: 'Font Awesome 6 Free'; 4 | --fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; 5 | } 6 | 7 | @font-face { 8 | font-family: 'Font Awesome 6 Free'; 9 | font-style: normal; 10 | font-weight: 900; 11 | font-display: block; 12 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); 13 | } 14 | 15 | .fas, 16 | .fa-solid { 17 | font-weight: 900; 18 | } 19 | 20 | /*! 21 | * Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com 22 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 23 | * Copyright 2023 Fonticons, Inc. 24 | */ -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/favicon.ico -------------------------------------------------------------------------------- /public/img/addbg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/addbg3.png -------------------------------------------------------------------------------- /public/img/ai21.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" width="" height="" viewBox="0 0 60 15" fill="none" 2 | data-inject-url="http://127.0.0.1:8001/img/ai21.svg" class="icon-svg timestamp-icon"> 3 | <g clip-path="url(#clip0--inject-2)"> 4 | <path 5 | d="M16.6207 23.4327L15.7407 20.6609H7.62075L6.74035 23.4327H1.10132L9.25303 0.609131H14.1115L22.361 23.4327H16.6207ZM11.6987 7.12926L8.89437 16.52H14.4377L11.6987 7.12926Z" 6 | fill=""></path> 7 | <path d="M22.9893 0.609131H28.3367V23.4327H22.9893V0.609131Z" fill=""></path> 8 | <path 9 | d="M29.778 18.7697C30.0181 17.6428 30.4422 16.5632 31.0333 15.5743C31.5474 14.7385 32.1914 13.9901 32.941 13.357C33.7068 12.7218 34.5187 12.1443 35.37 11.6294C36.0436 11.2378 36.6685 10.8627 37.2449 10.5043C37.7764 10.178 38.2832 9.81296 38.7611 9.4121C39.1738 9.06912 39.5217 8.65497 39.7883 8.18927C40.0429 7.72502 40.1721 7.20247 40.1632 6.67309C40.1632 5.7602 39.9133 5.10266 39.4134 4.70047C38.8833 4.2885 38.2258 4.07506 37.5548 4.09717C36.7912 4.07408 36.0486 4.34892 35.4841 4.86356C34.9298 5.37448 34.6527 6.2277 34.6527 7.42323H29.4028C29.3934 6.43009 29.5762 5.44452 29.9411 4.52079C30.291 3.64199 30.831 2.85144 31.5222 2.20575C32.2584 1.52916 33.1235 1.00796 34.0657 0.673329C35.1756 0.285645 36.3455 0.0978785 37.5209 0.118755C38.5297 0.114098 39.5341 0.25135 40.5046 0.526479C41.4073 0.777025 42.2539 1.19757 42.999 1.76555C43.731 2.33806 44.3175 3.07539 44.7107 3.9175C45.1549 4.89419 45.3723 5.95876 45.3465 7.0314C45.3582 7.93876 45.1454 8.83495 44.7269 9.64014C44.3262 10.406 43.8154 11.109 43.2108 11.7268C42.6204 12.3291 41.9705 12.87 41.271 13.3411C40.5746 13.8087 39.9441 14.2054 39.3795 14.5311C38.5964 15.0529 37.9496 15.504 37.4394 15.8845C37.0016 16.2011 36.5925 16.5556 36.2169 16.9439C35.9359 17.2322 35.7191 17.5768 35.5808 17.9549C35.4549 18.3444 35.3943 18.752 35.4015 19.1612H45.1837V23.4326H29.3378C29.3099 21.8667 29.4575 20.3027 29.778 18.7697Z" 10 | fill=""></path> 11 | <path 12 | d="M46.1938 4.61724C47.1075 4.63586 48.0205 4.55382 48.9163 4.37261C49.5146 4.25901 50.0784 4.00788 50.5631 3.63905C50.952 3.31635 51.2358 2.88492 51.3782 2.39998C51.5411 1.81652 51.618 1.21237 51.6062 0.606689H56.2708V23.4327H50.891V8.33548H46.1938V4.61724Z" 13 | fill=""></path> 14 | </g> 15 | <defs> 16 | <clipPath id="clip0--inject-2"> 17 | <rect width="117.818" height="24" fill="white" transform="translate(1.09106)"></rect> 18 | </clipPath> 19 | </defs> 20 | </svg> 21 | -------------------------------------------------------------------------------- /public/img/ai4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/ai4.png -------------------------------------------------------------------------------- /public/img/aphrodite.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 | <svg 3 | viewBox="0 0 500 500" 4 | version="1.1" 5 | id="svg6" 6 | sodipodi:docname="aphrodite.svg" 7 | inkscape:version="1.3 (0e150ed, 2023-07-21)" 8 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 9 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 10 | xmlns="http://www.w3.org/2000/svg" 11 | xmlns:svg="http://www.w3.org/2000/svg"> 12 | <defs 13 | id="defs6" /> 14 | <sodipodi:namedview 15 | id="namedview6" 16 | pagecolor="#ffffff" 17 | bordercolor="#000000" 18 | borderopacity="0.25" 19 | inkscape:showpageshadow="2" 20 | inkscape:pageopacity="0.0" 21 | inkscape:pagecheckerboard="0" 22 | inkscape:deskcolor="#d1d1d1" 23 | inkscape:zoom="0.472" 24 | inkscape:cx="251.05932" 25 | inkscape:cy="250" 26 | inkscape:window-width="1280" 27 | inkscape:window-height="449" 28 | inkscape:window-x="0" 29 | inkscape:window-y="25" 30 | inkscape:window-maximized="0" 31 | inkscape:current-layer="svg6" /> 32 | <g 33 | transform="matrix(1.3637143,0,0,1.2306337,286.98714,309.0439)" 34 | id="b08450db-4034-4e8d-9232-9d086fc10fd0" /> 35 | <g 36 | transform="matrix(1.3637143,0,0,1.2306337,286.98714,309.0439)" 37 | id="54daa6c1-4b17-4e19-b0bb-42d1bcbfe659" /> 38 | <g 39 | transform="matrix(1.3637143,0,0,1.2306337,186.0314,431.30731)" 40 | id="g2" /> 41 | <g 42 | transform="matrix(1.3637143,0,0,1.2306337,288.29633,320.27957)" 43 | id="g3" /> 44 | <g 45 | transform="matrix(1.686936,0,0,1.507445,388.05263,106.65182)" 46 | id="g6" 47 | style=""> 48 | <g 49 | id="g5" 50 | style=""> 51 | <path 52 | style="opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;" 53 | vector-effect="non-scaling-stroke" 54 | d="m -189.927,161.041 32.809,-32.022 47.368,38.876 -32.619,43.738 -87.665,49.304 z" 55 | stroke-linecap="round" 56 | id="path3" /> 57 | <path 58 | style="opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;" 59 | vector-effect="non-scaling-stroke" 60 | d="m -64.913,42.392 32.651,28.068 -77.49,97.438 -47.367,-38.878 91.346,-87.359 z" 61 | stroke-linecap="round" 62 | id="path4" /> 63 | <path 64 | style="opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;" 65 | vector-effect="non-scaling-stroke" 66 | d="m 46.895,-67.722 -2.202,2.004 -110.467,107.379 33.512,28.799 95.769,-121.944 0.023,-0.025 c 2.011,-2.328 2.952,-5.03 2.819,-8.105 -0.131,-3.074 -1.3,-5.686 -3.502,-7.834 -2.205,-2.148 -4.846,-3.248 -7.922,-3.3 -3.077,-0.054 -5.754,0.955 -8.03,3.026 z" 67 | stroke-linecap="round" 68 | id="path5" /> 69 | </g> 70 | </g> 71 | </svg> 72 | -------------------------------------------------------------------------------- /public/img/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/img/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/img/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/img/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/img/claude.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" standalone="no"?> 2 | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 3 | "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 4 | <svg version="1.0" xmlns="http://www.w3.org/2000/svg" 5 | width="179.000000pt" height="125.000000pt" viewBox="0 0 179.000000 125.000000" 6 | preserveAspectRatio="xMidYMid meet"> 7 | 8 | <g transform="translate(0.000000,125.000000) scale(0.100000,-0.100000)" 9 | stroke="none"> 10 | <path d="M445 1128 c-27 -68 -56 -141 -65 -163 -10 -22 -70 -173 -134 -335 11 | -65 -162 -121 -304 -126 -315 -15 -31 -120 -304 -120 -310 0 -3 62 -5 138 -5 12 | l138 0 23 58 c12 31 33 84 47 117 13 33 24 66 24 73 0 9 59 12 263 12 l263 0 13 | 16 -37 c9 -21 29 -69 43 -108 15 -38 31 -80 36 -92 8 -22 13 -23 149 -23 77 0 14 | 140 2 140 5 0 4 -83 210 -105 260 -7 17 -16 41 -20 55 -4 14 -15 43 -25 65 15 | -10 22 -52 128 -94 235 -43 107 -84 211 -92 230 -22 51 -28 66 -69 170 -36 94 16 | -47 119 -78 193 l-17 37 -144 0 -143 0 -48 -122z m220 -273 c10 -27 22 -54 25 17 | -60 4 -5 15 -35 25 -65 10 -30 21 -59 25 -65 4 -5 15 -35 25 -65 10 -30 21 18 | -59 26 -65 5 -5 9 -15 9 -22 0 -10 -36 -13 -164 -13 l-164 0 49 128 c28 70 64 19 | 164 81 210 17 46 34 80 38 75 4 -4 15 -30 25 -58z"/> 20 | <path d="M1046 1163 c20 -49 44 -110 54 -138 20 -54 65 -168 80 -200 9 -21 34 21 | -83 165 -415 43 -107 83 -208 91 -225 7 -16 26 -64 42 -105 l29 -75 142 -3 22 | c133 -2 141 -1 132 15 -6 10 -63 151 -126 313 -64 162 -136 342 -160 400 -23 23 | 58 -80 198 -126 313 l-82 207 -138 0 -138 0 35 -87z"/> 24 | </g> 25 | </svg> 26 | -------------------------------------------------------------------------------- /public/img/default-expressions/admiration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/admiration.png -------------------------------------------------------------------------------- /public/img/default-expressions/amusement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/amusement.png -------------------------------------------------------------------------------- /public/img/default-expressions/anger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/anger.png -------------------------------------------------------------------------------- /public/img/default-expressions/annoyance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/annoyance.png -------------------------------------------------------------------------------- /public/img/default-expressions/approval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/approval.png -------------------------------------------------------------------------------- /public/img/default-expressions/caring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/caring.png -------------------------------------------------------------------------------- /public/img/default-expressions/confusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/confusion.png -------------------------------------------------------------------------------- /public/img/default-expressions/curiosity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/curiosity.png -------------------------------------------------------------------------------- /public/img/default-expressions/desire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/desire.png -------------------------------------------------------------------------------- /public/img/default-expressions/desire1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/desire1.png -------------------------------------------------------------------------------- /public/img/default-expressions/desire2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/desire2.png -------------------------------------------------------------------------------- /public/img/default-expressions/disappointment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/disappointment.png -------------------------------------------------------------------------------- /public/img/default-expressions/disapproval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/disapproval.png -------------------------------------------------------------------------------- /public/img/default-expressions/disgust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/disgust.png -------------------------------------------------------------------------------- /public/img/default-expressions/embarrassment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/embarrassment.png -------------------------------------------------------------------------------- /public/img/default-expressions/excitement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/excitement.png -------------------------------------------------------------------------------- /public/img/default-expressions/fear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/fear.png -------------------------------------------------------------------------------- /public/img/default-expressions/gratitude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/gratitude.png -------------------------------------------------------------------------------- /public/img/default-expressions/grief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/grief.png -------------------------------------------------------------------------------- /public/img/default-expressions/joy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/joy.png -------------------------------------------------------------------------------- /public/img/default-expressions/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/love.png -------------------------------------------------------------------------------- /public/img/default-expressions/nervousness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/nervousness.png -------------------------------------------------------------------------------- /public/img/default-expressions/neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/neutral.png -------------------------------------------------------------------------------- /public/img/default-expressions/optimism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/optimism.png -------------------------------------------------------------------------------- /public/img/default-expressions/pride.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/pride.png -------------------------------------------------------------------------------- /public/img/default-expressions/realization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/realization.png -------------------------------------------------------------------------------- /public/img/default-expressions/relief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/relief.png -------------------------------------------------------------------------------- /public/img/default-expressions/remorse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/remorse.png -------------------------------------------------------------------------------- /public/img/default-expressions/sadness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/sadness.png -------------------------------------------------------------------------------- /public/img/default-expressions/surprise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/default-expressions/surprise.png -------------------------------------------------------------------------------- /public/img/five.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/five.png -------------------------------------------------------------------------------- /public/img/mancer.svg: -------------------------------------------------------------------------------- 1 | <svg width="128" height="128" viewBox="0 0 128 128" style="enable-background:new 0 0 128 128;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 2 | <path d="M115.36,61.84L70.22,50.49L114.45,2.4c0.41-0.45,0.43-1.13,0.05-1.6c-0.39-0.48-1.07-0.59-1.59-0.27 L12.3,61.98c-0.41,0.25-0.64,0.72-0.57,1.2c0.06,0.48,0.4,0.87,0.87,1.01l45.07,13.25L13.38,125.6c-0.42,0.46-0.44,1.15-0.04,1.61 c0.24,0.29,0.58,0.44,0.94,0.44c0.22,0,0.45-0.06,0.65-0.19l100.78-63.41c0.42-0.26,0.64-0.75,0.56-1.22 C116.19,62.34,115.84,61.95,115.36,61.84z" /> 3 | </svg> 4 | -------------------------------------------------------------------------------- /public/img/novel.svg: -------------------------------------------------------------------------------- 1 | <svg width="33" height="41" viewBox="0 0 33 41" xmlns="http://www.w3.org/2000/svg"> 2 | <path fill-rule="evenodd" clip-rule="evenodd" d="M5.89418 31.9285C4.51814 29.6818 2.83212 27.8112 0.836131 26.521C0.26793 26.1537 0.124452 25.3382 0.540438 24.8047C4.15593 20.1672 9.79294 8.01868 12.7415 1.40215C13.181 0.416062 14.6883 0.738582 14.6883 1.81816V19.44C13.1242 20.1331 12.0332 21.6992 12.0332 23.5201C12.0332 24.1851 12.1787 24.8161 12.4397 25.383L5.89418 31.9285ZM7.34675 34.6814C8.03773 36.2042 8.61427 37.8368 9.07635 39.5334C9.19588 39.9722 9.59101 40.2824 10.0459 40.2824H16.4937H22.9416C23.3964 40.2824 23.7916 39.9722 23.9111 39.5334C24.3732 37.8368 24.9497 36.2042 25.6407 34.6814L22.211 31.2516L19.3551 34.1075C19.4281 34.3655 19.4672 34.6378 19.4672 34.9192C19.4672 36.5615 18.1358 37.8928 16.4935 37.8928C14.8512 37.8928 13.5198 36.5615 13.5198 34.9192C13.5198 33.2768 14.8512 31.9455 16.4935 31.9455C16.7448 31.9455 16.9888 31.9766 17.2219 32.0353L20.1083 29.1489L18.4762 27.5169C17.879 27.8137 17.2058 27.9806 16.4937 27.9806C15.7816 27.9806 15.1084 27.8137 14.5112 27.5169L7.34675 34.6814ZM27.0933 31.9285C28.4693 29.6818 30.1553 27.8112 32.1513 26.521C32.7195 26.1537 32.863 25.3382 32.447 24.8047C28.8315 20.1672 23.1945 8.01868 20.2459 1.40215C19.8065 0.416062 18.2992 0.738582 18.2992 1.81816V19.44C19.8632 20.1332 20.9542 21.6992 20.9542 23.5201C20.9542 24.1851 20.8087 24.8161 20.5478 25.383L27.0933 31.9285Z" /> 3 | </svg> 4 | -------------------------------------------------------------------------------- /public/img/openai.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg"><path d="m297.06 130.97c7.26-21.79 4.76-45.66-6.85-65.48-17.46-30.4-52.56-46.04-86.84-38.68-15.25-17.18-37.16-26.95-60.13-26.81-35.04-.08-66.13 22.48-76.91 55.82-22.51 4.61-41.94 18.7-53.31 38.67-17.59 30.32-13.58 68.54 9.92 94.54-7.26 21.79-4.76 45.66 6.85 65.48 17.46 30.4 52.56 46.04 86.84 38.68 15.24 17.18 37.16 26.95 60.13 26.8 35.06.09 66.16-22.49 76.94-55.86 22.51-4.61 41.94-18.7 53.31-38.67 17.57-30.32 13.55-68.51-9.94-94.51zm-120.28 168.11c-14.03.02-27.62-4.89-38.39-13.88.49-.26 1.34-.73 1.89-1.07l63.72-36.8c3.26-1.85 5.26-5.32 5.24-9.07v-89.83l26.93 15.55c.29.14.48.42.52.74v74.39c-.04 33.08-26.83 59.9-59.91 59.97zm-128.84-55.03c-7.03-12.14-9.56-26.37-7.15-40.18.47.28 1.3.79 1.89 1.13l63.72 36.8c3.23 1.89 7.23 1.89 10.47 0l77.79-44.92v31.1c.02.32-.13.63-.38.83l-64.41 37.19c-28.69 16.52-65.33 6.7-81.92-21.95zm-16.77-139.09c7-12.16 18.05-21.46 31.21-26.29 0 .55-.03 1.52-.03 2.2v73.61c-.02 3.74 1.98 7.21 5.23 9.06l77.79 44.91-26.93 15.55c-.27.18-.61.21-.91.08l-64.42-37.22c-28.63-16.58-38.45-53.21-21.95-81.89zm221.26 51.49-77.79-44.92 26.93-15.54c.27-.18.61-.21.91-.08l64.42 37.19c28.68 16.57 38.51 53.26 21.94 81.94-7.01 12.14-18.05 21.44-31.2 26.28v-75.81c.03-3.74-1.96-7.2-5.2-9.06zm26.8-40.34c-.47-.29-1.3-.79-1.89-1.13l-63.72-36.8c-3.23-1.89-7.23-1.89-10.47 0l-77.79 44.92v-31.1c-.02-.32.13-.63.38-.83l64.41-37.16c28.69-16.55 65.37-6.7 81.91 22 6.99 12.12 9.52 26.31 7.15 40.1zm-168.51 55.43-26.94-15.55c-.29-.14-.48-.42-.52-.74v-74.39c.02-33.12 26.89-59.96 60.01-59.94 14.01 0 27.57 4.92 38.34 13.88-.49.26-1.33.73-1.89 1.07l-63.72 36.8c-3.26 1.85-5.26 5.31-5.24 9.06l-.04 89.79zm14.63-31.54 34.65-20.01 34.65 20v40.01l-34.65 20-34.65-20z"/></svg> -------------------------------------------------------------------------------- /public/img/openrouter.svg: -------------------------------------------------------------------------------- 1 | <svg width="100%" height="100%" viewBox="0 0 512 512" 2 | xmlns="http://www.w3.org/2000/svg" class="Navbar_logo__INhgK" aria-label="Logo"> 3 | <g clip-path="url(#clip0_205_3)"> 4 | <path d="M3 248.945C18 248.945 76 236 106 219C136 202 136 202 198 158C276.497 102.293 332 120.945 423 120.945" stroke-width="90"></path> 5 | <path d="M511 121.5L357.25 210.268L357.25 32.7324L511 121.5Z"></path> 6 | <path d="M0 249C15 249 73 261.945 103 278.945C133 295.945 133 295.945 195 339.945C273.497 395.652 329 377 420 377" stroke-width="90"></path> 7 | <path d="M508 376.445L354.25 287.678L354.25 465.213L508 376.445Z"></path> 8 | </g> 9 | <defs> 10 | <clipPath id="clip0_205_3"> 11 | <rect width="512" height="512"></rect> 12 | </clipPath> 13 | </defs> 14 | </svg> 15 | -------------------------------------------------------------------------------- /public/img/quill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/img/quill.png -------------------------------------------------------------------------------- /public/img/times-circle.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"/></svg> -------------------------------------------------------------------------------- /public/instruct/Alpaca.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Alpaca", 3 | "system_prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\nWrite {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n", 4 | "input_sequence": "### Instruction:", 5 | "output_sequence": "### Response:", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "", 12 | "wrap": true, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/Koala.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Koala", 3 | "system_prompt": "Write {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n", 4 | "input_sequence": "USER: ", 5 | "output_sequence": "GPT: ", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "BEGINNING OF CONVERSATION: ", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "</s>", 12 | "wrap": false, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/Metharme.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Metharme", 3 | "system_prompt": "Enter roleplay mode. You must act as {{char}}, whose persona follows:", 4 | "input_sequence": "<|user|>", 5 | "output_sequence": "<|model|>", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "<|system|>", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "</s>", 11 | "separator_sequence": "", 12 | "wrap": false, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/OpenOrca-OpenChat.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OpenOrca-OpenChat", 3 | "system_prompt": "You are a helpful assistant. Please answer truthfully and write out your thinking step by step to be sure you get the right answer. If you make a mistake or encounter an error in your thinking, say so out loud and attempt to correct it. If you don't know or aren't sure about something, say so clearly. You will act as a professional logician, mathematician, and physicist. You will also act as the most appropriate type of expert to answer any particular question or solve the relevant problem; state which expert type your are, if so. Also think of any particular named expert that would be ideal to answer the relevant question or solve the relevant problem; name and act as them, if appropriate.\n", 4 | "input_sequence": "User: ", 5 | "output_sequence": "<|end_of_turn|>\nAssistant: ", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "<|end_of_turn|>\n", 12 | "wrap": false, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/Roleplay.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Roleplay", 3 | "system_prompt": "Avoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.", 4 | "input_sequence": "\n### Instruction:", 5 | "output_sequence": "\n### Response:", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "\n### Response (2 paragraphs, engaging, natural, authentic, descriptive, creative):", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "", 12 | "wrap": true, 13 | "macro": true, 14 | "names": true, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/Vicuna 1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vicuna 1.0", 3 | "system_prompt": "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.\n\nWrite {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n", 4 | "input_sequence": "### Human:", 5 | "output_sequence": "### Assistant:", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "", 12 | "wrap": true, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/Vicuna 1.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vicuna 1.1", 3 | "system_prompt": "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.\n\nWrite {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n", 4 | "input_sequence": "\nUSER: ", 5 | "output_sequence": "\nASSISTANT: ", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "BEGINNING OF CONVERSATION:", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "</s>", 12 | "wrap": false, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/WizardLM-13B.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WizardLM-13B", 3 | "system_prompt": "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.\n\nWrite {{char}}'s next detailed reply in a fictional roleplay chat between {{user}} and {{char}}.", 4 | "input_sequence": "USER: ", 5 | "output_sequence": "ASSISTANT: ", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "", 12 | "wrap": true, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/instruct/WizardLM.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WizardLM", 3 | "system_prompt": "Write {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{char}}.\n", 4 | "input_sequence": "", 5 | "output_sequence": "### Response:", 6 | "first_output_sequence": "", 7 | "last_output_sequence": "", 8 | "system_sequence_prefix": "", 9 | "system_sequence_suffix": "", 10 | "stop_sequence": "", 11 | "separator_sequence": "</s>", 12 | "wrap": true, 13 | "macro": true, 14 | "names": false, 15 | "names_force_groups": true, 16 | "activation_regex": "" 17 | } 18 | -------------------------------------------------------------------------------- /public/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "checkJs": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "allowUmdGlobalAccess": true, 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "exclude": [ 10 | "node_modules" 11 | ], 12 | "typeAcquisition": { 13 | "include": [ 14 | "jquery", 15 | "@popperjs/core", 16 | "toastr", 17 | "showdown", 18 | "dompurify", 19 | "moment", 20 | "seedrandom", 21 | "showdown-katex", 22 | "droll", 23 | "handlebars", 24 | "highlight.js", 25 | "localforage" 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/lib/eventemitter.js: -------------------------------------------------------------------------------- 1 | /* Polyfill indexOf. */ 2 | var indexOf; 3 | 4 | if (typeof Array.prototype.indexOf === 'function') { 5 | indexOf = function (haystack, needle) { 6 | return haystack.indexOf(needle); 7 | }; 8 | } else { 9 | indexOf = function (haystack, needle) { 10 | var i = 0, length = haystack.length, idx = -1, found = false; 11 | 12 | while (i < length && !found) { 13 | if (haystack[i] === needle) { 14 | idx = i; 15 | found = true; 16 | } 17 | 18 | i++; 19 | } 20 | 21 | return idx; 22 | }; 23 | }; 24 | 25 | 26 | /* Polyfill EventEmitter. */ 27 | var EventEmitter = function () { 28 | this.events = {}; 29 | }; 30 | 31 | EventEmitter.prototype.on = function (event, listener) { 32 | if (typeof this.events[event] !== 'object') { 33 | this.events[event] = []; 34 | } 35 | 36 | this.events[event].push(listener); 37 | }; 38 | 39 | EventEmitter.prototype.removeListener = function (event, listener) { 40 | var idx; 41 | 42 | if (typeof this.events[event] === 'object') { 43 | idx = indexOf(this.events[event], listener); 44 | 45 | if (idx > -1) { 46 | this.events[event].splice(idx, 1); 47 | } 48 | } 49 | }; 50 | 51 | EventEmitter.prototype.emit = async function (event) { 52 | console.debug('Event emitted: ' + event); 53 | 54 | var i, listeners, length, args = [].slice.call(arguments, 1); 55 | 56 | if (typeof this.events[event] === 'object') { 57 | listeners = this.events[event].slice(); 58 | length = listeners.length; 59 | 60 | for (i = 0; i < length; i++) { 61 | try { 62 | await listeners[i].apply(this, args); 63 | } 64 | catch (err) { 65 | console.error(err); 66 | console.trace('Error in event listener'); 67 | } 68 | } 69 | } 70 | }; 71 | 72 | EventEmitter.prototype.once = function (event, listener) { 73 | this.on(event, function g () { 74 | this.removeListener(event, g); 75 | listener.apply(this, arguments); 76 | }); 77 | }; 78 | 79 | export { EventEmitter } 80 | -------------------------------------------------------------------------------- /public/lib/jquery-cookie-1.4.1.min.js: -------------------------------------------------------------------------------- 1 | /*! jquery.cookie v1.4.1 | MIT */ 2 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); -------------------------------------------------------------------------------- /public/lib/jquery-cropper.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cropper v1.0.1 3 | * https://fengyuanchen.github.io/jquery-cropper 4 | * 5 | * Copyright 2018-present Chen Fengyuan 6 | * Released under the MIT license 7 | * 8 | * Date: 2019-10-19T08:48:33.062Z 9 | */ 10 | !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("jquery"),require("cropperjs")):"function"==typeof define&&define.amd?define(["jquery","cropperjs"],r):r((e=e||self).jQuery,e.Cropper)}(this,function(c,s){"use strict";if(c=c&&c.hasOwnProperty("default")?c.default:c,s=s&&s.hasOwnProperty("default")?s.default:s,c&&c.fn&&s){var e=c.fn.cropper,d="cropper";c.fn.cropper=function(p){for(var e=arguments.length,a=new Array(1<e?e-1:0),r=1;r<e;r++)a[r-1]=arguments[r];var u;return this.each(function(e,r){var t=c(r),n="destroy"===p,o=t.data(d);if(!o){if(n)return;var f=c.extend({},t.data(),c.isPlainObject(p)&&p);o=new s(r,f),t.data(d,o)}if("string"==typeof p){var i=o[p];c.isFunction(i)&&((u=i.apply(o,a))===o&&(u=void 0),n&&t.removeData(d))}}),void 0!==u?u:this},c.fn.cropper.Constructor=s,c.fn.cropper.setDefaults=s.setDefaults,c.fn.cropper.noConflict=function(){return c.fn.cropper=e,this}}}); -------------------------------------------------------------------------------- /public/lib/seedrandom.min.js: -------------------------------------------------------------------------------- 1 | !function(f,a,c){var s,l=256,p="random",d=c.pow(l,6),g=c.pow(2,52),y=2*g,h=l-1;function n(n,t,r){function e(){for(var n=u.g(6),t=d,r=0;n<g;)n=(n+r)*l,t*=l,r=u.g(1);for(;y<=n;)n/=2,t/=2,r>>>=1;return(n+r)/t}var o=[],i=j(function n(t,r){var e,o=[],i=typeof t;if(r&&"object"==i)for(e in t)try{o.push(n(t[e],r-1))}catch(n){}return o.length?o:"string"==i?t:t+"\0"}((t=1==t?{entropy:!0}:t||{}).entropy?[n,S(a)]:null==n?function(){try{var n;return s&&(n=s.randomBytes)?n=n(l):(n=new Uint8Array(l),(f.crypto||f.msCrypto).getRandomValues(n)),S(n)}catch(n){var t=f.navigator,r=t&&t.plugins;return[+new Date,f,r,f.screen,S(a)]}}():n,3),o),u=new m(o);return e.int32=function(){return 0|u.g(4)},e.quick=function(){return u.g(4)/4294967296},e.double=e,j(S(u.S),a),(t.pass||r||function(n,t,r,e){return e&&(e.S&&v(e,u),n.state=function(){return v(u,{})}),r?(c[p]=n,t):n})(e,i,"global"in t?t.global:this==c,t.state)}function m(n){var t,r=n.length,u=this,e=0,o=u.i=u.j=0,i=u.S=[];for(r||(n=[r++]);e<l;)i[e]=e++;for(e=0;e<l;e++)i[e]=i[o=h&o+n[e%r]+(t=i[e])],i[o]=t;(u.g=function(n){for(var t,r=0,e=u.i,o=u.j,i=u.S;n--;)t=i[e=h&e+1],r=r*l+i[h&(i[e]=i[o=h&o+t])+(i[o]=t)];return u.i=e,u.j=o,r})(l)}function v(n,t){return t.i=n.i,t.j=n.j,t.S=n.S.slice(),t}function j(n,t){for(var r,e=n+"",o=0;o<e.length;)t[h&o]=h&(r^=19*t[h&o])+e.charCodeAt(o++);return S(t)}function S(n){return String.fromCharCode.apply(0,n)}if(j(c.random(),a),"object"==typeof module&&module.exports){module.exports=n;try{s=require("crypto")}catch(n){}}else"function"==typeof define&&define.amd?define(function(){return n}):c["seed"+p]=n}("undefined"!=typeof self?self:this,[],Math); -------------------------------------------------------------------------------- /public/lib/select2-search-placeholder.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | var Defaults = $.fn.select2.amd.require('select2/defaults'); 4 | 5 | $.extend(Defaults.defaults, { 6 | searchInputPlaceholder: '', 7 | searchInputCssClass: '', 8 | }); 9 | 10 | var SearchDropdown = $.fn.select2.amd.require('select2/dropdown/search'); 11 | 12 | var _renderSearchDropdown = SearchDropdown.prototype.render; 13 | 14 | SearchDropdown.prototype.render = function(decorated) { 15 | 16 | // invoke parent method 17 | var $rendered = _renderSearchDropdown.apply(this, Array.prototype.slice.apply(arguments)); 18 | 19 | this.$search.attr('placeholder', this.options.get('searchInputPlaceholder')); 20 | this.$search.addClass(this.options.get('searchInputCssClass')); 21 | 22 | return $rendered; 23 | }; 24 | 25 | })(window.jQuery); 26 | -------------------------------------------------------------------------------- /public/lib/showdown-toc.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).showdownToc=t()}(this,(function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}return function(){var r=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).toc;return function(){return[{type:"output",filter:function(n){var o=[];n.replace(/(<h([1-6]).*?id="([^"]*?)".*?>(.+?)<\/h[1-6]>)|(<p>\[toc\]<\/p>)/g,(function(n,c,u,i,p){if("<p>[toc]</p>"===n)o.push({type:"toc"});else{p=p.replace(/<[^>]+>/g,"");var f={anchor:i,level:Number(u),text:p};r&&r.push(f),o.push(function(r){for(var n=1;arguments.length>n;n++){var o=null!=arguments[n]?arguments[n]:{};n%2?t(o,!0).forEach((function(t){e(r,t,o[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(o)):t(o).forEach((function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(o,e))}))}return r}({type:"header"},f))}return""}));var c=[];return o.forEach((function(e,t){if("toc"===e.type)if(o[t+1]&&"header"===o[t+1].type){for(var r=[],n=o[t+1].level,u=t+1;o.length>u&&"toc"!==o[u].type;u++){o[u].level===n&&r.push(o[u])}c.push(r)}else c.push([])})),n=n.replace(/<p>\[toc\]<\/p>[\n]*/g,(function(){var e=c.shift();return e&&e.length?"<ol>".concat(e.map((function(e){var t=e.text;return'<li><a href="#'.concat(e.anchor,'">').concat(t,"</a></li>")})).join(""),"</ol>\n"):""}))}}]}}})); 2 | -------------------------------------------------------------------------------- /public/lib/structured-clone/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2021, Andrea Giammarchi, @WebReflection 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /public/lib/structured-clone/deserialize.js: -------------------------------------------------------------------------------- 1 | import { 2 | VOID, PRIMITIVE, 3 | ARRAY, OBJECT, 4 | DATE, REGEXP, MAP, SET, 5 | ERROR, BIGINT 6 | } from './types.js'; 7 | 8 | const env = typeof self === 'object' ? self : globalThis; 9 | 10 | const deserializer = ($, _) => { 11 | const as = (out, index) => { 12 | $.set(index, out); 13 | return out; 14 | }; 15 | 16 | const unpair = index => { 17 | if ($.has(index)) 18 | return $.get(index); 19 | 20 | const [type, value] = _[index]; 21 | switch (type) { 22 | case PRIMITIVE: 23 | case VOID: 24 | return as(value, index); 25 | case ARRAY: { 26 | const arr = as([], index); 27 | for (const index of value) 28 | arr.push(unpair(index)); 29 | return arr; 30 | } 31 | case OBJECT: { 32 | const object = as({}, index); 33 | for (const [key, index] of value) 34 | object[unpair(key)] = unpair(index); 35 | return object; 36 | } 37 | case DATE: 38 | return as(new Date(value), index); 39 | case REGEXP: { 40 | const {source, flags} = value; 41 | return as(new RegExp(source, flags), index); 42 | } 43 | case MAP: { 44 | const map = as(new Map, index); 45 | for (const [key, index] of value) 46 | map.set(unpair(key), unpair(index)); 47 | return map; 48 | } 49 | case SET: { 50 | const set = as(new Set, index); 51 | for (const index of value) 52 | set.add(unpair(index)); 53 | return set; 54 | } 55 | case ERROR: { 56 | const {name, message} = value; 57 | return as(new env[name](message), index); 58 | } 59 | case BIGINT: 60 | return as(BigInt(value), index); 61 | case 'BigInt': 62 | return as(Object(BigInt(value)), index); 63 | } 64 | return as(new env[type](value), index); 65 | }; 66 | 67 | return unpair; 68 | }; 69 | 70 | /** 71 | * @typedef {Array<string,any>} Record a type representation 72 | */ 73 | 74 | /** 75 | * Returns a deserialized value from a serialized array of Records. 76 | * @param {Record[]} serialized a previously serialized value. 77 | * @returns {any} 78 | */ 79 | export const deserialize = serialized => deserializer(new Map, serialized)(0); 80 | -------------------------------------------------------------------------------- /public/lib/structured-clone/index.js: -------------------------------------------------------------------------------- 1 | import {deserialize} from './deserialize.js'; 2 | import {serialize} from './serialize.js'; 3 | 4 | /** 5 | * @typedef {Array<string,any>} Record a type representation 6 | */ 7 | 8 | /** 9 | * Returns an array of serialized Records. 10 | * @param {any} any a serializable value. 11 | * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with 12 | * a transfer option (ignored when polyfilled) and/or non standard fields that 13 | * fallback to the polyfill if present. 14 | * @returns {Record[]} 15 | */ 16 | export default typeof structuredClone === "function" ? 17 | /* c8 ignore start */ 18 | (any, options) => ( 19 | options && ('json' in options || 'lossy' in options) ? 20 | deserialize(serialize(any, options)) : structuredClone(any) 21 | ) : 22 | (any, options) => deserialize(serialize(any, options)); 23 | /* c8 ignore stop */ 24 | 25 | export {deserialize, serialize}; 26 | -------------------------------------------------------------------------------- /public/lib/structured-clone/json.js: -------------------------------------------------------------------------------- 1 | /*! (c) Andrea Giammarchi - ISC */ 2 | 3 | import {deserialize} from './deserialize.js'; 4 | import {serialize} from './serialize.js'; 5 | 6 | const {parse: $parse, stringify: $stringify} = JSON; 7 | const options = {json: true, lossy: true}; 8 | 9 | /** 10 | * Revive a previously stringified structured clone. 11 | * @param {string} str previously stringified data as string. 12 | * @returns {any} whatever was previously stringified as clone. 13 | */ 14 | export const parse = str => deserialize($parse(str)); 15 | 16 | /** 17 | * Represent a structured clone value as string. 18 | * @param {any} any some clone-able value to stringify. 19 | * @returns {string} the value stringified. 20 | */ 21 | export const stringify = any => $stringify(serialize(any, options)); 22 | -------------------------------------------------------------------------------- /public/lib/structured-clone/monkey-patch.js: -------------------------------------------------------------------------------- 1 | import structuredClone from './index.js'; 2 | 3 | if (!("structuredClone" in globalThis)) { 4 | console.debug("Monkey-patching structuredClone"); 5 | globalThis.structuredClone = structuredClone; 6 | } 7 | -------------------------------------------------------------------------------- /public/lib/structured-clone/types.js: -------------------------------------------------------------------------------- 1 | export const VOID = -1; 2 | export const PRIMITIVE = 0; 3 | export const ARRAY = 1; 4 | export const OBJECT = 2; 5 | export const DATE = 3; 6 | export const REGEXP = 4; 7 | export const MAP = 5; 8 | export const SET = 6; 9 | export const ERROR = 7; 10 | export const BIGINT = 8; 11 | // export const SYMBOL = 9; 12 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /public/scripts/chats.js: -------------------------------------------------------------------------------- 1 | // Move chat functions here from script.js (eventually) 2 | 3 | import { 4 | chat, 5 | getCurrentChatId, 6 | hideSwipeButtons, 7 | saveChatConditional, 8 | showSwipeButtons, 9 | } from "../script.js"; 10 | 11 | /** 12 | * Mark message as hidden (system message). 13 | * @param {number} messageId Message ID 14 | * @param {JQuery<Element>} messageBlock Message UI element 15 | * @returns 16 | */ 17 | export async function hideChatMessage(messageId, messageBlock) { 18 | const chatId = getCurrentChatId(); 19 | 20 | if (!chatId || isNaN(messageId)) return; 21 | 22 | const message = chat[messageId]; 23 | 24 | if (!message) return; 25 | 26 | message.is_system = true; 27 | messageBlock.attr('is_system', String(true)); 28 | 29 | // Reload swipes. Useful when a last message is hidden. 30 | hideSwipeButtons(); 31 | showSwipeButtons(); 32 | 33 | await saveChatConditional(); 34 | } 35 | 36 | /** 37 | * Mark message as visible (non-system message). 38 | * @param {number} messageId Message ID 39 | * @param {JQuery<Element>} messageBlock Message UI element 40 | * @returns 41 | */ 42 | export async function unhideChatMessage(messageId, messageBlock) { 43 | const chatId = getCurrentChatId(); 44 | 45 | if (!chatId || isNaN(messageId)) return; 46 | 47 | const message = chat[messageId]; 48 | 49 | if (!message) return; 50 | 51 | message.is_system = false; 52 | messageBlock.attr('is_system', String(false)); 53 | 54 | // Reload swipes. Useful when a last message is hidden. 55 | hideSwipeButtons(); 56 | showSwipeButtons(); 57 | 58 | await saveChatConditional(); 59 | } 60 | 61 | jQuery(function() { 62 | $(document).on('click', '.mes_hide', async function() { 63 | const messageBlock = $(this).closest('.mes'); 64 | const messageId = Number(messageBlock.attr('mesid')); 65 | await hideChatMessage(messageId, messageBlock); 66 | }); 67 | 68 | $(document).on('click', '.mes_unhide', async function() { 69 | const messageBlock = $(this).closest('.mes'); 70 | const messageId = Number(messageBlock.attr('mesid')); 71 | await unhideChatMessage(messageId, messageBlock); 72 | }); 73 | }) 74 | -------------------------------------------------------------------------------- /public/scripts/extensions/assets/confirm.html: -------------------------------------------------------------------------------- 1 | <div class="m-b-1"> 2 | Are you sure you want to connect to '{{url}}'? 3 | </div> 4 | <div class="flex-container justifyCenter"> 5 | <label class="checkbox_label" for="assets-remember"> 6 | <input type="checkbox" id="assets-remember"> 7 | Don't ask again for this URL 8 | </label> 9 | </div> 10 | -------------------------------------------------------------------------------- /public/scripts/extensions/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Assets", 3 | "loading_order": 15, 4 | "requires": [], 5 | "optional": [], 6 | "js": "index.js", 7 | "css": "style.css", 8 | "author": "Keij#6799", 9 | "version": "0.1.0", 10 | "homePage": "https://github.com/SillyTavern/SillyTavern" 11 | } 12 | -------------------------------------------------------------------------------- /public/scripts/extensions/assets/style.css: -------------------------------------------------------------------------------- 1 | #assets-json-url-field { 2 | width: 85%; 3 | } 4 | 5 | #assets-connect-button { 6 | width: 15%; 7 | margin-left: 5px; 8 | } 9 | 10 | .assets-connect-div { 11 | display: flex; 12 | flex-direction: row; 13 | padding: 5px; 14 | } 15 | 16 | .assets-list-git { 17 | font-size: calc(var(--mainFontSize) * 0.8); 18 | opacity: 0.8; 19 | margin-bottom: 1em; 20 | } 21 | 22 | .assets-list-div h3 { 23 | text-transform: capitalize; 24 | } 25 | 26 | .assets-list-div i a { 27 | color: inherit; 28 | } 29 | 30 | .assets-list-div i { 31 | display: flex; 32 | flex-direction: row; 33 | align-items: center; 34 | justify-content: left; 35 | padding: 5px; 36 | font-style: normal; 37 | } 38 | 39 | .assets-list-div i span { 40 | margin-left: 10px; 41 | } 42 | 43 | .assets-list-div i span:first-of-type { 44 | font-weight: bold; 45 | } 46 | 47 | .asset-download-button { 48 | position: relative; 49 | width: 50px; 50 | padding: 8px 16px; 51 | border: none; 52 | outline: none; 53 | border-radius: 2px; 54 | cursor: pointer; 55 | } 56 | 57 | .asset-download-button:active { 58 | background: #007a63; 59 | } 60 | 61 | .asset-download-button-text { 62 | font: bold 20px "Quicksand", san-serif; 63 | color: #ffffff; 64 | transition: all 0.2s; 65 | } 66 | 67 | .asset-download-button-loading .asset-download-button-text { 68 | visibility: hidden; 69 | opacity: 0; 70 | } 71 | 72 | .asset-download-button-loading::after { 73 | content: ""; 74 | position: absolute; 75 | width: 16px; 76 | height: 16px; 77 | top: 0; 78 | left: 0; 79 | right: 0; 80 | bottom: 0; 81 | margin: auto; 82 | border: 4px solid transparent; 83 | border-top-color: #ffffff; 84 | border-radius: 50%; 85 | animation: asset-download-button-loading-spinner 1s ease infinite; 86 | } 87 | 88 | @keyframes asset-download-button-loading-spinner { 89 | from { 90 | transform: rotate(0turn); 91 | } 92 | 93 | to { 94 | transform: rotate(1turn); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /public/scripts/extensions/assets/window.html: -------------------------------------------------------------------------------- 1 | <div id="assets_ui"> 2 | <div class="inline-drawer"> 3 | <div class="inline-drawer-toggle inline-drawer-header"> 4 | <b>Download Extensions & Assets</b> 5 | <div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div> 6 | </div> 7 | <div class="inline-drawer-content"> 8 | <label for="assets-json-url-field">Assets URL</label> 9 | <div class="assets-connect-div"> 10 | <input id="assets-json-url-field" class="text_pole widthUnset flex1"> 11 | <i id="assets-connect-button" class="menu_button fa-solid fa-plug-circle-exclamation fa-xl redOverlayGlow"></i> 12 | </div> 13 | <div class="inline-drawer-content" id="assets_menu"> 14 | </div> 15 | </div> 16 | </div> 17 | </div> 18 | -------------------------------------------------------------------------------- /public/scripts/extensions/caption/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Image Captioning", 3 | "loading_order": 4, 4 | "requires": [], 5 | "optional": [ 6 | "caption" 7 | ], 8 | "js": "index.js", 9 | "css": "style.css", 10 | "author": "Cohee#1207", 11 | "version": "1.0.0", 12 | "homePage": "https://github.com/SillyTavern/SillyTavern" 13 | } 14 | -------------------------------------------------------------------------------- /public/scripts/extensions/caption/style.css: -------------------------------------------------------------------------------- 1 | #img_form { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /public/scripts/extensions/expressions/add-custom-expression.html: -------------------------------------------------------------------------------- 1 | <h3> 2 | Enter a name for the custom expression: 3 | </h3> 4 | <h4> 5 | Requirements: 6 | </h4> 7 | <ol class="justifyLeft"> 8 | <li> 9 | The name must be unique and not already in use by the default expression. 10 | </li> 11 | <li> 12 | The name must contain only letters, numbers, dashes and underscores. Don't include any file extensions. 13 | </li> 14 | </ol> 15 | -------------------------------------------------------------------------------- /public/scripts/extensions/expressions/list-item.html: -------------------------------------------------------------------------------- 1 | <div id="{{item}}" class="expression_list_item"> 2 | <div class="expression_list_buttons"> 3 | <div class="menu_button expression_list_upload" title="Upload image"> 4 | <i class="fa-solid fa-upload"></i> 5 | </div> 6 | <div class="menu_button expression_list_delete" title="Delete image"> 7 | <i class="fa-solid fa-trash"></i> 8 | </div> 9 | </div> 10 | <div class="expression_list_title {{textClass}}"> 11 | <span>{{item}}</span> 12 | {{#if isCustom}} 13 | <small class="expression_list_custom">(custom)</small> 14 | {{/if}} 15 | </div> 16 | <img class="expression_list_image" src="{{imageSrc}}" /> 17 | </div> 18 | -------------------------------------------------------------------------------- /public/scripts/extensions/expressions/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Character Expressions", 3 | "loading_order": 6, 4 | "requires": [], 5 | "optional": [ 6 | "classify" 7 | ], 8 | "js": "index.js", 9 | "css": "style.css", 10 | "author": "Cohee#1207", 11 | "version": "1.0.0", 12 | "homePage": "https://github.com/SillyTavern/SillyTavern" 13 | } 14 | -------------------------------------------------------------------------------- /public/scripts/extensions/expressions/remove-custom-expression.html: -------------------------------------------------------------------------------- 1 | <h3> 2 | Are you sure you want to remove the expression <tt>"{{expression}}"</tt>? 3 | </h3> 4 | <div> 5 | Uploaded images will not be deleted, but will no longer be used by the extension. 6 | </div> 7 | <br> 8 | -------------------------------------------------------------------------------- /public/scripts/extensions/gallery/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Gallery", 3 | "loading_order": 6, 4 | "requires": [], 5 | "optional": [ 6 | ], 7 | "js": "index.js", 8 | "css": "", 9 | "author": "City-Unit", 10 | "version": "1.5.0", 11 | "homePage": "https://github.com/SillyTavern/SillyTavern" 12 | } 13 | -------------------------------------------------------------------------------- /public/scripts/extensions/memory/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Summarize", 3 | "loading_order": 9, 4 | "requires": [], 5 | "optional": [ 6 | "summarize" 7 | ], 8 | "js": "index.js", 9 | "css": "style.css", 10 | "author": "Cohee#1207", 11 | "version": "1.0.0", 12 | "homePage": "https://github.com/SillyTavern/SillyTavern" 13 | } 14 | -------------------------------------------------------------------------------- /public/scripts/extensions/memory/style.css: -------------------------------------------------------------------------------- 1 | #memory_settings { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | #memory_settings textarea { 7 | font-size: calc(var(--mainFontSize) * 0.9); 8 | line-height: 1.2; 9 | } 10 | 11 | label[for="memory_frozen"], 12 | label[for="memory_skipWIAN"] { 13 | display: flex; 14 | align-items: center; 15 | margin: 0 !important; 16 | } 17 | 18 | label[for="memory_frozen"] input { 19 | margin-right: 10px; 20 | } 21 | 22 | .memory_contents_controls { 23 | display: flex; 24 | flex-direction: row; 25 | align-items: center; 26 | justify-content: space-between; 27 | } -------------------------------------------------------------------------------- /public/scripts/extensions/quick-reply/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Quick Replies", 3 | "loading_order": 12, 4 | "requires": [], 5 | "optional": [], 6 | "js": "index.js", 7 | "css": "style.css", 8 | "author": "RossAscends#1779", 9 | "version": "1.0.0", 10 | "homePage": "https://github.com/SillyTavern/SillyTavern" 11 | } -------------------------------------------------------------------------------- /public/scripts/extensions/quick-reply/style.css: -------------------------------------------------------------------------------- 1 | #quickReplyBar { 2 | outline: none; 3 | padding: 5px 0; 4 | border-bottom: 1px solid var(--SmartThemeBorderColor); 5 | margin: 0; 6 | transition: 0.3s; 7 | opacity: 0.7; 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | width: 100%; 12 | display: none; 13 | max-width: 100%; 14 | overflow-x: auto; 15 | order: 10; 16 | } 17 | 18 | #quickReplies { 19 | margin: 0; 20 | padding: 0; 21 | display: flex; 22 | justify-content: center; 23 | flex-wrap: wrap; 24 | gap: 5px; 25 | width: 100%; 26 | } 27 | 28 | #quickReplies div { 29 | color: var(--SmartThemeBodyColor); 30 | background-color: var(--black50a); 31 | border: 1px solid var(--SmartThemeBorderColor); 32 | border-radius: 10px; 33 | padding: 3px 5px; 34 | width: min-content; 35 | cursor: pointer; 36 | transition: 0.3s; 37 | display: flex; 38 | align-items: center; 39 | justify-content: center; 40 | text-align: center; 41 | } 42 | 43 | #quickReplies div:hover { 44 | opacity: 1; 45 | filter: brightness(1.2); 46 | cursor: pointer; 47 | } -------------------------------------------------------------------------------- /public/scripts/extensions/regex/dropdown.html: -------------------------------------------------------------------------------- 1 | <div class="regex_settings"> 2 | <div class="inline-drawer"> 3 | <div class="inline-drawer-toggle inline-drawer-header"> 4 | <b>Regex</b> 5 | <div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div> 6 | </div> 7 | <div class="inline-drawer-content"> 8 | <div id="open_regex_editor" class="menu_button"> 9 | <i class="fa-solid fa-pen-to-square"></i> 10 | <span>Open Editor</span> 11 | </div> 12 | <hr /> 13 | <label>Saved Scripts</label> 14 | <div id="saved_regex_scripts" class="flex-container regex-script-container flexFlowColumn"></div> 15 | </div> 16 | </div> 17 | </div> 18 | -------------------------------------------------------------------------------- /public/scripts/extensions/regex/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Regex", 3 | "loading_order": 1, 4 | "requires": [], 5 | "optional": [], 6 | "js": "index.js", 7 | "css": "style.css", 8 | "author": "kingbri", 9 | "version": "1.0.0", 10 | "homePage": "https://github.com/SillyTavern/SillyTavern" 11 | } 12 | -------------------------------------------------------------------------------- /public/scripts/extensions/regex/scriptTemplate.html: -------------------------------------------------------------------------------- 1 | <div class="regex-script-label flex-container flexnowrap"> 2 | <span class="drag-handle menu-handle">☰</span> 3 | <div class="regex_script_name flexGrow overflow-hidden"></div> 4 | <div class="flex-container flexnowrap"> 5 | <label class="checkbox flex-container" for="regex_disable"> 6 | <input type="checkbox" name="regex_disable" class="disable_regex" /> 7 | <span class="regex-toggle-on fa-solid fa-toggle-on" title="Disable script"></span> 8 | <span class="regex-toggle-off fa-solid fa-toggle-off" title="Enable script"></span> 9 | </label> 10 | <div class="edit_existing_regex menu_button"> 11 | <i class="fa-solid fa-pencil"></i> 12 | </div> 13 | <div class="delete_regex menu_button"> 14 | <i class="fa-solid fa-trash"></i> 15 | </div> 16 | </div> 17 | </div> 18 | -------------------------------------------------------------------------------- /public/scripts/extensions/regex/style.css: -------------------------------------------------------------------------------- 1 | .regex_settings .menu_button { 2 | width: fit-content; 3 | display: flex; 4 | gap: 10px; 5 | flex-direction: row; 6 | } 7 | 8 | .regex_settings .checkbox { 9 | align-items: center; 10 | } 11 | 12 | .regex-script-container { 13 | margin-top: 10px; 14 | margin-bottom: 10px; 15 | } 16 | 17 | .regex-script-label { 18 | align-items: center; 19 | border: 1px solid var(--SmartThemeBorderColor); 20 | border-radius: 10px; 21 | padding: 0 5px; 22 | margin-top: 1px; 23 | margin-bottom: 1px; 24 | } 25 | 26 | input.disable_regex { 27 | display: none !important; 28 | } 29 | 30 | .regex-toggle-off { 31 | cursor: pointer; 32 | opacity: 0.5; 33 | filter: grayscale(0.5); 34 | } 35 | 36 | .regex-toggle-on { 37 | cursor: pointer; 38 | } 39 | 40 | .disable_regex:checked ~ .regex-toggle-off { 41 | display: block; 42 | } 43 | 44 | .disable_regex:checked ~ .regex-toggle-on { 45 | display: none; 46 | } 47 | 48 | .disable_regex:not(:checked) ~ .regex-toggle-off { 49 | display: none; 50 | } 51 | 52 | .disable_regex:not(:checked) ~ .regex-toggle-on { 53 | display: block; 54 | } 55 | -------------------------------------------------------------------------------- /public/scripts/extensions/stable-diffusion/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Image Generation", 3 | "loading_order": 10, 4 | "requires": [], 5 | "optional": [ 6 | "sd" 7 | ], 8 | "generate_interceptor": "SD_ProcessTriggers", 9 | "js": "index.js", 10 | "css": "style.css", 11 | "author": "Cohee#1207", 12 | "version": "1.0.0", 13 | "homePage": "https://github.com/SillyTavern/SillyTavern" 14 | } 15 | -------------------------------------------------------------------------------- /public/scripts/extensions/stable-diffusion/style.css: -------------------------------------------------------------------------------- 1 | .sd_settings label:not(.checkbox_label) { 2 | display: block; 3 | } 4 | 5 | #sd_gen { 6 | /*order: 100; 7 | width: 40px; 8 | height: 40px; 9 | margin: 0; 10 | padding: 1px; */ 11 | outline: none; 12 | border: none; 13 | cursor: pointer; 14 | transition: 0.3s; 15 | opacity: 0.7; 16 | display: flex; 17 | align-items: center; 18 | /* justify-content: center; */ 19 | } 20 | 21 | #sd_gen:hover { 22 | opacity: 1; 23 | filter: brightness(1.2); 24 | } 25 | 26 | #sd_dropdown { 27 | z-index: 30000; 28 | backdrop-filter: blur(--SmartThemeBlurStrength); 29 | } 30 | -------------------------------------------------------------------------------- /public/scripts/extensions/token-counter/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Token Counter", 3 | "loading_order": 15, 4 | "requires": [], 5 | "optional": [], 6 | "js": "index.js", 7 | "css": "style.css", 8 | "author": "Cohee#1207", 9 | "version": "1.0.0", 10 | "homePage": "https://github.com/SillyTavern/SillyTavern" 11 | } 12 | -------------------------------------------------------------------------------- /public/scripts/extensions/token-counter/style.css: -------------------------------------------------------------------------------- 1 | #tokenized_chunks_display > code { 2 | color: black; 3 | text-shadow: none; 4 | padding: 2px; 5 | display: inline-block; 6 | } 7 | -------------------------------------------------------------------------------- /public/scripts/extensions/translate/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Chat Translation", 3 | "loading_order": 1, 4 | "requires": [], 5 | "optional": [], 6 | "js": "index.js", 7 | "css": "style.css", 8 | "author": "Cohee#1207", 9 | "version": "1.0.0", 10 | "homePage": "https://github.com/SillyTavern/SillyTavern" 11 | } 12 | -------------------------------------------------------------------------------- /public/scripts/extensions/translate/style.css: -------------------------------------------------------------------------------- 1 | .translation_settings .menu_button { 2 | width: fit-content; 3 | display: flex; 4 | gap: 10px; 5 | flex-direction: row; 6 | } 7 | -------------------------------------------------------------------------------- /public/scripts/extensions/tts/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "TTS", 3 | "loading_order": 10, 4 | "requires": [], 5 | "optional": [ 6 | "silero-tts", 7 | "edge-tts", 8 | "coqui-tts" 9 | ], 10 | "js": "index.js", 11 | "css": "style.css", 12 | "author": "Ouoertheo#7264", 13 | "version": "1.0.0", 14 | "homePage": "None" 15 | } 16 | -------------------------------------------------------------------------------- /public/scripts/extensions/tts/style.css: -------------------------------------------------------------------------------- 1 | #tts_media_control { 2 | /* order: 100; */ 3 | /* width: 40px; 4 | height: 40px; 5 | margin: 0; 6 | padding: 1px; */ 7 | outline: none; 8 | border: none; 9 | cursor: pointer; 10 | /* transition: 0.3s; 11 | opacity: 0.7; */ 12 | display: flex; 13 | align-items: center; 14 | /* justify-content: center; */ 15 | 16 | } 17 | 18 | #ttsExtensionMenuItem { 19 | transition: 0.3s; 20 | opacity: 0.7; 21 | } 22 | 23 | #ttsExtensionMenuItem:hover { 24 | opacity: 1; 25 | filter: brightness(1.2); 26 | } 27 | 28 | #tts_media_control:hover { 29 | opacity: 1; 30 | filter: brightness(1.2); 31 | } 32 | 33 | .voice_preview { 34 | margin: 0.25rem 0.5rem; 35 | display: flex; 36 | justify-content: space-between; 37 | align-items: center; 38 | gap: 0.5rem; 39 | } 40 | 41 | .voice_preview .voice_name { 42 | text-align: left; 43 | flex: 1; 44 | } 45 | 46 | .voice_preview .voice_lang { 47 | width: 4rem; 48 | text-align: left; 49 | } 50 | 51 | .voice_preview .fa-play { 52 | cursor: pointer; 53 | } 54 | 55 | .tts-button { 56 | margin: 0; 57 | outline: none; 58 | border: none; 59 | cursor: pointer; 60 | transition: 0.3s; 61 | opacity: 0.7; 62 | align-items: center; 63 | justify-content: center; 64 | 65 | } 66 | 67 | .tts-button:hover { 68 | opacity: 1; 69 | } 70 | 71 | .tts_block { 72 | display: flex; 73 | align-items: baseline; 74 | column-gap: 5px; 75 | flex-wrap: wrap; 76 | } 77 | 78 | .tts_custom_voices { 79 | display: flex; 80 | align-items: baseline; 81 | gap: 5px; 82 | } 83 | 84 | .novel_tts_hints { 85 | font-size: calc(0.9 * var(--mainFontSize)); 86 | display: flex; 87 | flex-direction: column; 88 | gap: 5px; 89 | margin-bottom: 5px; 90 | } 91 | -------------------------------------------------------------------------------- /public/scripts/extensions/vectors/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "Vector Storage", 3 | "loading_order": 100, 4 | "requires": [], 5 | "optional": [], 6 | "generate_interceptor": "vectors_rearrangeChat", 7 | "js": "index.js", 8 | "css": "", 9 | "author": "Cohee#1207", 10 | "version": "1.0.0", 11 | "homePage": "https://github.com/SillyTavern/SillyTavern" 12 | } 13 | -------------------------------------------------------------------------------- /public/scripts/f-localStorage.js: -------------------------------------------------------------------------------- 1 | ////////////////// LOCAL STORAGE HANDLING ///////////////////// 2 | 3 | export function SaveLocal(target, val) { 4 | localStorage.setItem(target, val); 5 | console.debug('SaveLocal -- ' + target + ' : ' + val); 6 | } 7 | export function LoadLocal(target) { 8 | console.debug('LoadLocal -- ' + target); 9 | return localStorage.getItem(target); 10 | 11 | } 12 | export function LoadLocalBool(target) { 13 | let result = localStorage.getItem(target) === 'true'; 14 | return result; 15 | } 16 | export function CheckLocal() { 17 | console.log("----------local storage---------"); 18 | var i; 19 | for (i = 0; i < localStorage.length; i++) { 20 | console.log(localStorage.key(i) + " : " + localStorage.getItem(localStorage.key(i))); 21 | } 22 | console.log("------------------------------"); 23 | } 24 | 25 | export function ClearLocal() { localStorage.clear(); console.log('Removed All Local Storage'); } 26 | 27 | ///////////////////////////////////////////////////////////////////////// 28 | -------------------------------------------------------------------------------- /public/scripts/loader.js: -------------------------------------------------------------------------------- 1 | const ELEMENT_ID = 'loader'; 2 | 3 | export function showLoader() { 4 | const container = $('<div></div>').attr('id', ELEMENT_ID); 5 | const loader = $('<div></div>').attr('id', 'load-spinner').addClass('fa-solid fa-gear fa-spin fa-3x') 6 | container.append(loader); 7 | $('body').append(container); 8 | 9 | } 10 | 11 | export function hideLoader() { 12 | //Sets up a 2-step animation. Spinner blurs/fades out, and then the loader shadow does the same. 13 | $(`#load-spinner`).on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { 14 | //console.log('FADING BLUR SCREEN') 15 | $(`#${ELEMENT_ID}`) 16 | .animate({ opacity: 0 }, 300, function () { 17 | //console.log('REMOVING LOADER') 18 | $(`#${ELEMENT_ID}`).remove() 19 | }) 20 | }) 21 | 22 | //console.log('BLURRING SPINNER') 23 | $(`#load-spinner`) 24 | .css({ 25 | 'filter': 'blur(15px)', 26 | 'opacity': '0', 27 | }) 28 | } -------------------------------------------------------------------------------- /public/scripts/mancer-settings.js: -------------------------------------------------------------------------------- 1 | import { setGenerationParamsFromPreset } from "../script.js"; 2 | import { getDeviceInfo } from "./RossAscends-mods.js"; 3 | import { textgenerationwebui_settings } from "./textgen-settings.js"; 4 | 5 | let models = []; 6 | 7 | export async function loadMancerModels(data) { 8 | if (!Array.isArray(data)) { 9 | console.error('Invalid Mancer models data', data); 10 | return; 11 | } 12 | 13 | models = data; 14 | 15 | $('#mancer_model').empty(); 16 | for (const model of data) { 17 | const option = document.createElement('option'); 18 | option.value = model.id; 19 | option.text = model.name; 20 | option.selected = model.id === textgenerationwebui_settings.mancer_model; 21 | $('#mancer_model').append(option); 22 | } 23 | } 24 | 25 | function onMancerModelSelect() { 26 | const modelId = String($('#mancer_model').val()); 27 | textgenerationwebui_settings.mancer_model = modelId; 28 | $('#api_button_textgenerationwebui').trigger('click'); 29 | 30 | const limits = models.find(x => x.id === modelId)?.limits; 31 | setGenerationParamsFromPreset({ max_length: limits.context, genamt: limits.completion }); 32 | } 33 | 34 | function getMancerModelTemplate(option) { 35 | const model = models.find(x => x.id === option?.element?.value); 36 | 37 | if (!option.id || !model) { 38 | return option.text; 39 | } 40 | 41 | return $((` 42 | <div class="flex-container flexFlowColumn"> 43 | <div><strong>${DOMPurify.sanitize(model.name)}</strong> | <span>${model.limits?.context} ctx</span></div> 44 | </div> 45 | `)); 46 | } 47 | 48 | jQuery(function () { 49 | $('#mancer_model').on('change', onMancerModelSelect); 50 | 51 | const deviceInfo = getDeviceInfo(); 52 | if (deviceInfo && deviceInfo.device.type === 'desktop') { 53 | $('#mancer_model').select2({ 54 | placeholder: 'Select a model', 55 | searchInputPlaceholder: 'Search models...', 56 | searchInputCssClass: 'text_pole', 57 | width: '100%', 58 | templateResult: getMancerModelTemplate, 59 | }); 60 | } 61 | }); 62 | -------------------------------------------------------------------------------- /public/scripts/server-history.js: -------------------------------------------------------------------------------- 1 | import { saveSettingsDebounced } from "../script.js"; 2 | import { power_user } from "./power-user.js"; 3 | import { isValidUrl } from "./utils.js"; 4 | 5 | /** 6 | * @param {{ term: string; }} request 7 | * @param {function} resolve 8 | * @param {string} serverLabel 9 | */ 10 | function findServers(request, resolve, serverLabel) { 11 | if (!power_user.servers) { 12 | power_user.servers = []; 13 | } 14 | 15 | const needle = request.term.toLowerCase(); 16 | const result = power_user.servers.filter(x => x.label == serverLabel).sort((a, b) => b.lastConnection - a.lastConnection).map(x => x.url).slice(0, 5); 17 | const hasExactMatch = result.findIndex(x => x.toLowerCase() == needle) !== -1; 18 | 19 | if (request.term && !hasExactMatch) { 20 | result.unshift(request.term); 21 | } 22 | 23 | resolve(result); 24 | } 25 | 26 | function selectServer(event, ui, serverLabel) { 27 | // unfocus the input 28 | $(event.target).val(ui.item.value).trigger('input').trigger('blur'); 29 | 30 | $('[data-server-connect]').each(function () { 31 | const serverLabels = String($(this).data('server-connect')).split(','); 32 | 33 | if (serverLabels.includes(serverLabel)) { 34 | $(this).trigger('click'); 35 | } 36 | }); 37 | } 38 | 39 | function createServerAutocomplete() { 40 | const inputElement = $(this); 41 | const serverLabel = inputElement.data('server-history'); 42 | 43 | inputElement 44 | .autocomplete({ 45 | source: (i, o) => findServers(i, o, serverLabel), 46 | select: (e, u) => selectServer(e, u, serverLabel), 47 | minLength: 0, 48 | }) 49 | .focus(onInputFocus); // <== show tag list on click 50 | } 51 | 52 | function onInputFocus() { 53 | $(this).autocomplete('search', $(this).val()); 54 | } 55 | 56 | function onServerConnectClick() { 57 | const serverLabels = String($(this).data('server-connect')).split(','); 58 | 59 | serverLabels.forEach(serverLabel => { 60 | if (!power_user.servers) { 61 | power_user.servers = []; 62 | } 63 | 64 | const value = String($(`[data-server-history="${serverLabel}"]`).val()).toLowerCase().trim(); 65 | 66 | // Don't save empty values or invalid URLs 67 | if (!value || !isValidUrl(value)) { 68 | return; 69 | } 70 | 71 | const server = power_user.servers.find(x => x.url === value && x.label === serverLabel); 72 | 73 | if (!server) { 74 | power_user.servers.push({ label: serverLabel, url: value, lastConnection: Date.now() }); 75 | } else { 76 | server.lastConnection = Date.now(); 77 | } 78 | 79 | saveSettingsDebounced(); 80 | }); 81 | } 82 | 83 | jQuery(function () { 84 | $('[data-server-history]').each(createServerAutocomplete); 85 | $(document).on('click', '[data-server-connect]', onServerConnectClick); 86 | }); 87 | -------------------------------------------------------------------------------- /public/scripts/setting-search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Search for settings that match the search string and highlight them. 3 | */ 4 | async function searchSettings() { 5 | removeHighlighting(); // Remove previous highlights 6 | const searchString = String($("#settingsSearch").val()); 7 | const searchableText = $("#user-settings-block-content"); // Get the HTML block 8 | if (searchString.trim() !== "") { 9 | highlightMatchingElements(searchableText[0], searchString); // Highlight matching elements 10 | } 11 | } 12 | 13 | /** 14 | * Check if the element is a child of a header element 15 | * @param {HTMLElement | Text | Document | Comment} element Settings block HTML element 16 | * @returns {boolean} True if the element is a child of a header element, false otherwise 17 | */ 18 | function isParentHeader(element) { 19 | return $(element).closest('h4, h3').length > 0; 20 | } 21 | 22 | /** 23 | * Recursively highlight elements that match the search string 24 | * @param {HTMLElement | Text | Document | Comment} element Settings block HTML element 25 | * @param {string} searchString Search string 26 | */ 27 | function highlightMatchingElements(element, searchString) { 28 | $(element).contents().each(function () { 29 | const isTextNode = this.nodeType === Node.TEXT_NODE; 30 | const isElementNode = this.nodeType === Node.ELEMENT_NODE; 31 | 32 | if (isTextNode && this.nodeValue.trim() !== "" && !isParentHeader(this)) { 33 | const parentElement = $(this).parent(); 34 | const elementText = this.nodeValue; 35 | 36 | if (elementText.toLowerCase().includes(searchString.toLowerCase())) { 37 | parentElement.addClass('highlighted'); // Add CSS class to highlight matched elements 38 | } 39 | } else if (isElementNode && !$(this).is("h4")) { 40 | highlightMatchingElements(this, searchString); 41 | } 42 | }); 43 | } 44 | 45 | /** 46 | * Remove highlighting from previously highlighted elements. 47 | */ 48 | function removeHighlighting() { 49 | $(".highlighted").removeClass("highlighted"); // Remove CSS class from previously highlighted elements 50 | } 51 | 52 | jQuery(() => { 53 | $('#settingsSearch').on('input change', searchSettings); 54 | }); 55 | -------------------------------------------------------------------------------- /public/scripts/showdown-exclusion.js: -------------------------------------------------------------------------------- 1 | import { power_user } from './power-user.js'; 2 | 3 | // Showdown extension to make chat separators (dinkuses) ignore markdown formatting 4 | export const markdownExclusionExt = () => { 5 | if (!power_user) { 6 | console.log("Showdown-dinkus extension: power_user wasn't found! Returning."); 7 | return [] 8 | } 9 | 10 | let combinedExcludeString = ''; 11 | if (power_user.context.chat_start) { 12 | combinedExcludeString += `${power_user.context.chat_start},`; 13 | } 14 | 15 | if (power_user.context.example_separator) { 16 | combinedExcludeString += `${power_user.context.example_separator},`; 17 | } 18 | 19 | if (power_user.markdown_escape_strings) { 20 | combinedExcludeString += power_user.markdown_escape_strings; 21 | } 22 | 23 | const escapedExclusions = combinedExcludeString 24 | .split(",") 25 | .filter((element) => element.length > 0) 26 | .map((element) => `(${element.split('').map((char) => `\\${char}`).join('')})`); 27 | 28 | 29 | // No exclusions? No extension! 30 | if (!combinedExcludeString || combinedExcludeString.length === 0 || escapedExclusions.length === 0) { 31 | return []; 32 | } 33 | 34 | const replaceRegex = new RegExp(`^(${escapedExclusions.join("|")})\n`, "gm"); 35 | return [{ 36 | type: "lang", 37 | regex: replaceRegex, 38 | replace: ((match) => match.replace(replaceRegex, `\u0000${match} \n`)) 39 | }]; 40 | } 41 | -------------------------------------------------------------------------------- /public/scripts/templates/debug.html: -------------------------------------------------------------------------------- 1 | <h3 data-i18n="Debug Menu">Debug Menu</h3> 2 | <div data-i18n="Debug Warning"> 3 | Functions in this category are for advanced users only. Don't click anything if you're not sure about the consequences. 4 | </div> 5 | <table id="debug_table" class="responsiveTable"> 6 | {{#each functions}} 7 | {{#with this}} 8 | <tr> 9 | <td> 10 | <div class="justifyLeft"> 11 | <b>{{this.name}}</b> 12 | </div> 13 | <div class="justifyLeft"> 14 | {{this.description}} 15 | </div> 16 | <div class="flex-container justifyCenter"> 17 | <div class="menu_button menu_button_icon" data-debug-function="{{this.functionId}}" data-i18n="Execute"> 18 | Execute 19 | </div> 20 | </div> 21 | </td> 22 | </tr> 23 | {{/with}} 24 | {{/each}} 25 | </table> 26 | -------------------------------------------------------------------------------- /public/scripts/templates/formatting.html: -------------------------------------------------------------------------------- 1 | Text formatting commands: 2 | <ul> 3 | <li><tt>*text*</tt> - displays as <i>italics</i></li> 4 | <li><tt>**text**</tt> - displays as <b>bold</b></li> 5 | <li><tt>***text***</tt> - displays as <b><i>bold italics</i></b></li> 6 | <li><tt>```text```</tt> - displays as a code block (new lines allowed between the backticks)</li> 7 | </ul> 8 | <pre><code> like this</code></pre> 9 | <ul> 10 | <li><tt>`text`</tt> - displays as <code>inline code</code></li> 11 | <li><tt> text</tt> - displays as a blockquote (note the space after >)</li> 12 | <blockquote>like this</blockquote> 13 | <li><tt># text</tt> - displays as a large header (note the space)</li> 14 | <h1>like this</h1> 15 | <li><tt>## text</tt> - displays as a medium header (note the space)</li> 16 | <h2>like this</h2> 17 | <li><tt>### text</tt> - displays as a small header (note the space)</li> 18 | <h3>like this</h3> 19 | <li><tt>$$ text $$</tt> - renders a LaTeX formula (if enabled)</li> 20 | <li><tt>$ text $</tt> - renders an AsciiMath formula (if enabled)</li> 21 | </ul> 22 | -------------------------------------------------------------------------------- /public/scripts/templates/help.html: -------------------------------------------------------------------------------- 1 | Hello there! Please select the help topic you would like to learn more about: 2 | <ul> 3 | <li><a href="#" data-displayHelp="1">Slash Commands</a> (or <tt>/help slash</tt>)</li> 4 | <li><a href="#" data-displayHelp="2">Formatting</a> (or <tt>/help format</tt>)</li> 5 | <li><a href="#" data-displayHelp="3">Hotkeys</a> (or <tt>/help hotkeys</tt>)</li> 6 | <li><a href="#" data-displayHelp="4">{{Macros}}</a> (or <tt>/help macros</tt>)</li> 7 | </ul> 8 | <br> 9 | <b> 10 | Still got questions left? The <a target="_blank" href="https://docs.sillytavern.app/">Official SillyTavern Documentation Website</a> has much more information! 11 | </b> 12 | -------------------------------------------------------------------------------- /public/scripts/templates/hotkeys.html: -------------------------------------------------------------------------------- 1 | Hotkeys/Keybinds: 2 | <ul> 3 | <li><tt>Up</tt> = Edit last message in chat</li> 4 | <li><tt>Ctrl+Up</tt> = Edit last USER message in chat</li> 5 | <li><tt>Left</tt> = swipe left</li> 6 | <li><tt>Right</tt> = swipe right (NOTE: swipe hotkeys are disabled when chatbar has something typed into it)</li> 7 | <li><tt>Enter</tt> (with chat bar selected) = send your message to AI</li> 8 | <li><tt>Ctrl+Enter</tt> = Regenerate the last AI response</li> 9 | <li><tt>Alt+Enter</tt> = Continue the last AI response</li> 10 | <li><tt>Escape</tt> = stop AI response generation, close UI panels, cancel message edit</li> 11 | <li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li> 12 | <li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li> 13 | </ul> 14 | -------------------------------------------------------------------------------- /public/scripts/templates/macros.html: -------------------------------------------------------------------------------- 1 | System-wide Replacement Macros (in order of evaluation): 2 | <ul> 3 | <li><tt>{{original}}</tt> – global prompts defined in API settings. Only valid in Advanced Definitions prompt overrides.</li> 4 | <li><tt>{{input}}</tt> – the user input</li> 5 | <li><tt>{{description}}</tt> – the Character's Description</li> 6 | <li><tt>{{personality}}</tt> – the Character's Personality</li> 7 | <li><tt>{{scenario}}</tt> – the Character's Scenario</li> 8 | <li><tt>{{persona}}</tt> – your current Persona Description</li> 9 | <li><tt>{{mesExamples}}</tt> – the Character's Dialogue Examples</li> 10 | <li><tt>{{user}}</tt> – your current Persona username</li> 11 | <li><tt>{{char}}</tt> – the Character's name</li> 12 | <li><tt>{{lastMessageId}}</tt> – index # of the latest chat message. Useful for slash command batching.</li> 13 | <li><tt>{{// (note)}}</tt> – you can leave a note here, and the macro will be replaced with blank content. Not visible for the AI.</li> 14 | <li><tt>{{time}}</tt> – the current time</li> 15 | <li><tt>{{date}}</tt> – the current date</li> 16 | <li><tt>{{weekday}}</tt> – the current weekday</li> 17 | <li><tt>{{isotime}}</tt> – the current ISO date (YYYY-MM-DD)</li> 18 | <li><tt>{{isodate}}</tt> – the current ISO time (24-hour clock)</li> 19 | <li><tt>{{datetimeformat …}}</tt> – the current date/time in the specified format, e. g. for German date/time: <tt>{{datetimeformat DD.MM.YYYY HH:mm}}</tt></li> 20 | <li><tt>{{time_UTC±#}}</tt> – the current time in the specified UTC time zone offset, e.g. UTC-4 or UTC+2</li> 21 | <li><tt>{{idle_duration}}</tt> – the time since the last user message was sent</li> 22 | <li><tt>{{bias "text here"}}</tt> – sets a behavioral bias for the AI until the next user input. Quotes around the text are important.</li> 23 | <li><tt>{{random:(args)}}</tt> – returns a random item from the list. (ex: {{random:1,2,3,4}} will return 1 of the 4 numbers at random. Works with text lists too.</li> 24 | <li><tt>{{roll:(formula)}}</tt> – rolls a dice. (ex: {{roll:1d6}} will roll a 6- sided dice and return a number between 1 and 6)</li> 25 | <li><tt>{{banned "text here"}}</tt> – dynamically add text in the quotes to banned words sequences, if Text Generation WebUI backend used. Do nothing for others backends. Can be used anywhere (Character description, WI, AN, etc.) Quotes around the text are important.</li> 26 | </ul> 27 | -------------------------------------------------------------------------------- /public/scripts/templates/welcome.html: -------------------------------------------------------------------------------- 1 | <h3> 2 | <span id="version_display_welcome">SillyTavern</span> 3 | <div id="version_display_welcome"></div> 4 | </h3> 5 | <a href="https://docs.sillytavern.app/usage/update/"" target=" _blank"> 6 | Want to update? 7 | </a> 8 | <hr> 9 | <h3>How to start chatting?</h3> 10 | <ol> 11 | <li>Click <code><i class="fa-solid fa-plug"></i></code> and select a <a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank">Chat API</a>.</li> 12 | <li>Click <code><i class="fa-solid fa-address-card"></i></code> and pick a character</li> 13 | </ol> 14 | <hr> 15 | <h3> 16 | Want more characters? 17 | </h3> 18 | <i> 19 | Not controlled by SillyTavern team. 20 | </i> 21 | <ul> 22 | <li> 23 | <a target="_blank" href="https://discord.gg/pygmalionai"> 24 | Pygmalion AI Discord 25 | </a> 26 | </li> 27 | <li> 28 | <a target="_blank" href="https://chub.ai/"> 29 | Chub (NSFW) 30 | </a> 31 | </li> 32 | </ul> 33 | <hr> 34 | <h3>Confused or lost?</h3> 35 | <ul> 36 | <li> 37 | <span class="note-link-span">?</span> - click these icons! 38 | </li> 39 | <li> 40 | Enter <code>/?</code> in the chat bar 41 | </li> 42 | <li> 43 | <a target="_blank" href="https://docs.sillytavern.app/"> 44 | SillyTavern Documentation Site 45 | </a> 46 | </li> 47 | <li> 48 | <a target="_blank" href="https://docs.sillytavern.app/extras/installation/"> 49 | Extras Installation Guide 50 | </a> 51 | </li> 52 | </ul> 53 | 54 | <hr> 55 | <h3>Still have questions?</h3> 56 | <ul> 57 | <li> 58 | <a target="_blank" href="https://discord.gg/RZdyAEUPvj"> 59 | Join the SillyTavern Discord 60 | </a> 61 | </li> 62 | <li> 63 | <a target="_blank" href="https://github.com/SillyTavern/SillyTavern/issues"> 64 | Post a GitHub issue 65 | </a> 66 | </li> 67 | <li> 68 | <a target="_blank" href="https://github.com/SillyTavern/SillyTavern#questions-or-suggestions"> 69 | Contact the developers 70 | </a> 71 | </li> 72 | </ul> 73 | -------------------------------------------------------------------------------- /public/sounds/message.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/sounds/message.mp3 -------------------------------------------------------------------------------- /public/sounds/silence.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/sounds/silence.mp3 -------------------------------------------------------------------------------- /public/st-launcher.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/st-launcher.ico -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Black.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Black.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-BlackItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-BlackItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-BlackItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-BlackItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Bold.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Bold.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-BoldItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-BoldItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraBold.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraBold.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraLight.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraLight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraLight.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ExtraLightItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Italic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Italic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Light.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Light.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-LightItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-LightItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Medium.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Medium.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-MediumItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-MediumItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-MediumItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-MediumItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Regular.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Regular.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-SemiBold.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-SemiBold.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-SemiBoldItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Thin.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-Thin.woff2 -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ThinItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ThinItalic.woff -------------------------------------------------------------------------------- /public/webfonts/NotoSans/NotoSans-ThinItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/NotoSans/NotoSans-ThinItalic.woff2 -------------------------------------------------------------------------------- /public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /replit.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: { 2 | deps = [ 3 | pkgs.nodejs-18_x 4 | pkgs.nodePackages.typescript-language-server 5 | pkgs.yarn 6 | pkgs.replitPackages.jest 7 | ]; 8 | } -------------------------------------------------------------------------------- /src/ai_horde/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ZeldaFan0225 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/ai_horde/index.mjs: -------------------------------------------------------------------------------- 1 | import AIHorde from './index.js' 2 | export default AIHorde 3 | export { AIHorde } -------------------------------------------------------------------------------- /src/caption.js: -------------------------------------------------------------------------------- 1 | const TASK = 'image-to-text'; 2 | 3 | /** 4 | * @param {import("express").Express} app 5 | * @param {any} jsonParser 6 | */ 7 | function registerEndpoints(app, jsonParser) { 8 | app.post('/api/extra/caption', jsonParser, async (req, res) => { 9 | try { 10 | const { image } = req.body; 11 | 12 | const module = await import('./transformers.mjs'); 13 | const rawImage = await module.default.getRawImage(image); 14 | 15 | if (!rawImage) { 16 | console.log('Failed to parse captioned image'); 17 | return res.sendStatus(400); 18 | } 19 | 20 | const pipe = await module.default.getPipeline(TASK); 21 | const result = await pipe(rawImage); 22 | const text = result[0].generated_text; 23 | console.log('Image caption:', text); 24 | 25 | return res.json({ caption: text }); 26 | } catch (error) { 27 | console.error(error); 28 | return res.sendStatus(500); 29 | } 30 | }); 31 | } 32 | 33 | module.exports = { 34 | registerEndpoints, 35 | }; 36 | -------------------------------------------------------------------------------- /src/character-card-parser.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const extract = require('png-chunks-extract'); 4 | const PNGtext = require('png-chunk-text'); 5 | 6 | const parse = async (cardUrl, format) => { 7 | let fileFormat = format === undefined ? 'png' : format; 8 | 9 | switch (fileFormat) { 10 | case 'png': 11 | const buffer = fs.readFileSync(cardUrl); 12 | const chunks = extract(buffer); 13 | 14 | const textChunks = chunks.filter(function (chunk) { 15 | return chunk.name === 'tEXt'; 16 | }).map(function (chunk) { 17 | return PNGtext.decode(chunk.data); 18 | }); 19 | 20 | if (textChunks.length === 0) { 21 | console.error('PNG metadata does not contain any character data.'); 22 | throw new Error('No PNG metadata.'); 23 | } 24 | 25 | return Buffer.from(textChunks[0].text, 'base64').toString('utf8'); 26 | default: 27 | break; 28 | } 29 | }; 30 | 31 | module.exports = { 32 | parse: parse 33 | }; 34 | -------------------------------------------------------------------------------- /src/chat-completion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a prompt from the ChatML objects to the format used by Claude. 3 | * @param {object[]} messages Array of messages 4 | * @param {boolean} addHumanPrefix Add Human prefix 5 | * @param {boolean} addAssistantPostfix Add Assistant postfix 6 | * @returns {string} Prompt for Claude 7 | * @copyright Prompt Conversion script taken from RisuAI by kwaroran (GPLv3). 8 | */ 9 | function convertClaudePrompt(messages, addHumanPrefix, addAssistantPostfix) { 10 | // Claude doesn't support message names, so we'll just add them to the message content. 11 | for (const message of messages) { 12 | if (message.name && message.role !== "system") { 13 | message.content = message.name + ": " + message.content; 14 | delete message.name; 15 | } 16 | } 17 | 18 | let requestPrompt = messages.map((v) => { 19 | let prefix = ''; 20 | switch (v.role) { 21 | case "assistant": 22 | prefix = "\n\nAssistant: "; 23 | break 24 | case "user": 25 | prefix = "\n\nHuman: "; 26 | break 27 | case "system": 28 | // According to the Claude docs, H: and A: should be used for example conversations. 29 | if (v.name === "example_assistant") { 30 | prefix = "\n\nA: "; 31 | } else if (v.name === "example_user") { 32 | prefix = "\n\nH: "; 33 | } else { 34 | prefix = "\n\n"; 35 | } 36 | break 37 | } 38 | return prefix + v.content; 39 | }).join(''); 40 | 41 | if (addHumanPrefix) { 42 | requestPrompt = "\n\nHuman: " + requestPrompt; 43 | } 44 | 45 | if (addAssistantPostfix) { 46 | requestPrompt = requestPrompt + '\n\nAssistant: '; 47 | } 48 | 49 | return requestPrompt; 50 | } 51 | 52 | module.exports = { 53 | convertClaudePrompt, 54 | } 55 | -------------------------------------------------------------------------------- /src/classify.js: -------------------------------------------------------------------------------- 1 | const TASK = 'text-classification'; 2 | 3 | /** 4 | * @param {import("express").Express} app 5 | * @param {any} jsonParser 6 | */ 7 | function registerEndpoints(app, jsonParser) { 8 | const cacheObject = {}; 9 | 10 | app.post('/api/extra/classify/labels', jsonParser, async (req, res) => { 11 | try { 12 | const module = await import('./transformers.mjs'); 13 | const pipe = await module.default.getPipeline(TASK); 14 | const result = Object.keys(pipe.model.config.label2id); 15 | return res.json({ labels: result }); 16 | } catch (error) { 17 | console.error(error); 18 | return res.sendStatus(500); 19 | } 20 | }); 21 | 22 | app.post('/api/extra/classify', jsonParser, async (req, res) => { 23 | try { 24 | const { text } = req.body; 25 | 26 | async function getResult(text) { 27 | if (cacheObject.hasOwnProperty(text)) { 28 | return cacheObject[text]; 29 | } else { 30 | const module = await import('./transformers.mjs'); 31 | const pipe = await module.default.getPipeline(TASK); 32 | const result = await pipe(text, { topk: 5 }); 33 | result.sort((a, b) => b.score - a.score); 34 | cacheObject[text] = result; 35 | return result; 36 | } 37 | } 38 | 39 | console.log('Classify input:', text); 40 | const result = await getResult(text); 41 | console.log('Classify output:', result); 42 | 43 | return res.json({ classification: result }); 44 | } catch (error) { 45 | console.error(error); 46 | return res.sendStatus(500); 47 | } 48 | }); 49 | } 50 | 51 | module.exports = { 52 | registerEndpoints, 53 | }; 54 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | const DIRECTORIES = { 2 | worlds: 'public/worlds/', 3 | avatars: 'public/User Avatars', 4 | images: 'public/img/', 5 | userImages: 'public/user/images/', 6 | groups: 'public/groups/', 7 | groupChats: 'public/group chats', 8 | chats: 'public/chats/', 9 | characters: 'public/characters/', 10 | backgrounds: 'public/backgrounds', 11 | novelAI_Settings: 'public/NovelAI Settings', 12 | koboldAI_Settings: 'public/KoboldAI Settings', 13 | openAI_Settings: 'public/OpenAI Settings', 14 | textGen_Settings: 'public/TextGen Settings', 15 | thumbnails: 'thumbnails/', 16 | thumbnailsBg: 'thumbnails/bg/', 17 | thumbnailsAvatar: 'thumbnails/avatar/', 18 | themes: 'public/themes', 19 | movingUI: 'public/movingUI', 20 | extensions: 'public/scripts/extensions', 21 | instruct: 'public/instruct', 22 | context: 'public/context', 23 | backups: 'backups/', 24 | quickreplies: 'public/QuickReplies', 25 | assets: 'public/assets', 26 | }; 27 | 28 | const UNSAFE_EXTENSIONS = [ 29 | ".php", 30 | ".exe", 31 | ".com", 32 | ".dll", 33 | ".pif", 34 | ".application", 35 | ".gadget", 36 | ".msi", 37 | ".jar", 38 | ".cmd", 39 | ".bat", 40 | ".reg", 41 | ".sh", 42 | ".py", 43 | ".js", 44 | ".jse", 45 | ".jsp", 46 | ".pdf", 47 | ".html", 48 | ".htm", 49 | ".hta", 50 | ".vb", 51 | ".vbs", 52 | ".vbe", 53 | ".cpl", 54 | ".msc", 55 | ".scr", 56 | ".sql", 57 | ".iso", 58 | ".img", 59 | ".dmg", 60 | ".ps1", 61 | ".ps1xml", 62 | ".ps2", 63 | ".ps2xml", 64 | ".psc1", 65 | ".psc2", 66 | ".msh", 67 | ".msh1", 68 | ".msh2", 69 | ".mshxml", 70 | ".msh1xml", 71 | ".msh2xml", 72 | ".scf", 73 | ".lnk", 74 | ".inf", 75 | ".reg", 76 | ".doc", 77 | ".docm", 78 | ".docx", 79 | ".dot", 80 | ".dotm", 81 | ".dotx", 82 | ".xls", 83 | ".xlsm", 84 | ".xlsx", 85 | ".xlt", 86 | ".xltm", 87 | ".xltx", 88 | ".xlam", 89 | ".ppt", 90 | ".pptm", 91 | ".pptx", 92 | ".pot", 93 | ".potm", 94 | ".potx", 95 | ".ppam", 96 | ".ppsx", 97 | ".ppsm", 98 | ".pps", 99 | ".ppam", 100 | ".sldx", 101 | ".sldm", 102 | ".ws", 103 | ]; 104 | 105 | const PALM_SAFETY = [ 106 | { 107 | category: "HARM_CATEGORY_UNSPECIFIED", 108 | threshold: "BLOCK_NONE" 109 | }, 110 | { 111 | category: "HARM_CATEGORY_DEROGATORY", 112 | threshold: "BLOCK_NONE" 113 | }, 114 | { 115 | category: "HARM_CATEGORY_TOXICITY", 116 | threshold: "BLOCK_NONE" 117 | }, 118 | { 119 | category: "HARM_CATEGORY_VIOLENCE", 120 | threshold: "BLOCK_NONE" 121 | }, 122 | { 123 | category: "HARM_CATEGORY_SEXUAL", 124 | threshold: "BLOCK_NONE" 125 | }, 126 | { 127 | category: "HARM_CATEGORY_MEDICAL", 128 | threshold: "BLOCK_NONE" 129 | }, 130 | { 131 | category: "HARM_CATEGORY_DANGEROUS", 132 | threshold: "BLOCK_NONE" 133 | } 134 | ]; 135 | 136 | const UPLOADS_PATH = './uploads'; 137 | 138 | module.exports = { 139 | DIRECTORIES, 140 | UNSAFE_EXTENSIONS, 141 | UPLOADS_PATH, 142 | PALM_SAFETY, 143 | } 144 | -------------------------------------------------------------------------------- /src/embedding.js: -------------------------------------------------------------------------------- 1 | const TASK = 'feature-extraction'; 2 | 3 | /** 4 | * @param {string} text - The text to vectorize 5 | * @returns {Promise<number[]>} - The vectorized text in form of an array of numbers 6 | */ 7 | async function getTransformersVector(text) { 8 | const module = await import('./transformers.mjs'); 9 | const pipe = await module.default.getPipeline(TASK); 10 | const result = await pipe(text, { pooling: 'mean', normalize: true }); 11 | const vector = Array.from(result.data); 12 | return vector; 13 | } 14 | 15 | module.exports = { 16 | getTransformersVector, 17 | } 18 | -------------------------------------------------------------------------------- /src/middleware/basicAuthMiddleware.js: -------------------------------------------------------------------------------- 1 | /** 2 | * When applied, this middleware will ensure the request contains the required header for basic authentication and only 3 | * allow access to the endpoint after successful authentication. 4 | */ 5 | const { getConfig } = require('./../util.js'); 6 | 7 | const unauthorizedResponse = (res) => { 8 | res.set('WWW-Authenticate', 'Basic realm="SillyTavern", charset="UTF-8"'); 9 | return res.status(401).send('Authentication required'); 10 | }; 11 | 12 | const basicAuthMiddleware = function (request, response, callback) { 13 | const config = getConfig(); 14 | const authHeader = request.headers.authorization; 15 | 16 | if (!authHeader) { 17 | return unauthorizedResponse(response); 18 | } 19 | 20 | const [scheme, credentials] = authHeader.split(' '); 21 | 22 | if (scheme !== 'Basic' || !credentials) { 23 | return unauthorizedResponse(response); 24 | } 25 | 26 | const [username, password] = Buffer.from(credentials, 'base64') 27 | .toString('utf8') 28 | .split(':'); 29 | 30 | if (username === config.basicAuthUser.username && password === config.basicAuthUser.password) { 31 | return callback(); 32 | } else { 33 | return unauthorizedResponse(response); 34 | } 35 | } 36 | 37 | module.exports = basicAuthMiddleware; 38 | -------------------------------------------------------------------------------- /src/openai-vectors.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch').default; 2 | const { SECRET_KEYS, readSecret } = require('./secrets'); 3 | 4 | /** 5 | * Gets the vector for the given text from OpenAI ada model 6 | * @param {string} text - The text to get the vector for 7 | * @returns {Promise<number[]>} - The vector for the text 8 | */ 9 | async function getOpenAIVector(text) { 10 | const key = readSecret(SECRET_KEYS.OPENAI); 11 | 12 | if (!key) { 13 | console.log('No OpenAI key found'); 14 | throw new Error('No OpenAI key found'); 15 | } 16 | 17 | const response = await fetch('https://api.openai.com/v1/embeddings', { 18 | method: 'POST', 19 | headers: { 20 | 'Content-Type': 'application/json', 21 | Authorization: `Bearer ${key}`, 22 | }, 23 | body: JSON.stringify({ 24 | input: text, 25 | model: 'text-embedding-ada-002', 26 | }) 27 | }); 28 | 29 | if (!response.ok) { 30 | const text = await response.text(); 31 | console.log('OpenAI request failed', response.statusText, text); 32 | throw new Error('OpenAI request failed'); 33 | } 34 | 35 | const data = await response.json(); 36 | const vector = data?.data[0]?.embedding; 37 | 38 | if (!Array.isArray(vector)) { 39 | console.log('OpenAI response was not an array'); 40 | throw new Error('OpenAI response was not an array'); 41 | } 42 | 43 | return vector; 44 | } 45 | 46 | module.exports = { 47 | getOpenAIVector, 48 | }; 49 | -------------------------------------------------------------------------------- /src/palm-vectors.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch').default; 2 | const { SECRET_KEYS, readSecret } = require('./secrets'); 3 | 4 | /** 5 | * Gets the vector for the given text from PaLM gecko model 6 | * @param {string} text - The text to get the vector for 7 | * @returns {Promise<number[]>} - The vector for the text 8 | */ 9 | async function getPaLMVector(text) { 10 | const key = readSecret(SECRET_KEYS.PALM); 11 | 12 | if (!key) { 13 | console.log('No PaLM key found'); 14 | throw new Error('No PaLM key found'); 15 | } 16 | 17 | const response = await fetch(`https://generativelanguage.googleapis.com/v1beta2/models/embedding-gecko-001:embedText?key=${key}`, { 18 | method: 'POST', 19 | headers: { 20 | 'Content-Type': 'application/json', 21 | }, 22 | body: JSON.stringify({ 23 | text: text, 24 | }) 25 | }); 26 | 27 | if (!response.ok) { 28 | const text = await response.text(); 29 | console.log('PaLM request failed', response.statusText, text); 30 | throw new Error('PaLM request failed'); 31 | } 32 | 33 | const data = await response.json(); 34 | 35 | // Access the "value" dictionary 36 | const vector = data.embedding.value; 37 | 38 | return vector; 39 | } 40 | 41 | module.exports = { 42 | getPaLMVector, 43 | }; 44 | -------------------------------------------------------------------------------- /src/poe_graphql/AddHumanMessageMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation AddHumanMessageMutation( 2 | $chatId: BigInt! 3 | $bot: String! 4 | $query: String! 5 | $source: MessageSource 6 | $withChatBreak: Boolean! = false 7 | ) { 8 | messageCreateWithStatus( 9 | chatId: $chatId 10 | bot: $bot 11 | query: $query 12 | source: $source 13 | withChatBreak: $withChatBreak 14 | ) { 15 | message { 16 | id 17 | __typename 18 | messageId 19 | text 20 | linkifiedText 21 | authorNickname 22 | state 23 | vote 24 | voteReason 25 | creationTime 26 | suggestedReplies 27 | chat { 28 | id 29 | shouldShowDisclaimer 30 | } 31 | } 32 | messageLimit{ 33 | canSend 34 | numMessagesRemaining 35 | resetTime 36 | shouldShowReminder 37 | } 38 | chatBreak { 39 | id 40 | __typename 41 | messageId 42 | text 43 | linkifiedText 44 | authorNickname 45 | state 46 | vote 47 | voteReason 48 | creationTime 49 | suggestedReplies 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/poe_graphql/AddMessageBreakMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation AddMessageBreakMutation($chatId: BigInt!) { 2 | messageBreakCreate(chatId: $chatId) { 3 | message { 4 | id 5 | __typename 6 | messageId 7 | text 8 | linkifiedText 9 | authorNickname 10 | state 11 | vote 12 | voteReason 13 | creationTime 14 | suggestedReplies 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/poe_graphql/AutoSubscriptionMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation AutoSubscriptionMutation($subscriptions: [AutoSubscriptionQuery!]!) { 2 | autoSubscribe(subscriptions: $subscriptions) { 3 | viewer { 4 | id 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/poe_graphql/BioFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment BioFragment on Viewer { 2 | id 3 | poeUser { 4 | id 5 | uid 6 | bio 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/poe_graphql/ChatAddedSubscription.graphql: -------------------------------------------------------------------------------- 1 | subscription ChatAddedSubscription { 2 | chatAdded { 3 | ...ChatFragment 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/poe_graphql/ChatFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment ChatFragment on Chat { 2 | id 3 | chatId 4 | defaultBotNickname 5 | shouldShowDisclaimer 6 | } 7 | -------------------------------------------------------------------------------- /src/poe_graphql/ChatPaginationQuery.graphql: -------------------------------------------------------------------------------- 1 | query ChatPaginationQuery($bot: String!, $before: String, $last: Int! = 10) { 2 | chatOfBot(bot: $bot) { 3 | id 4 | __typename 5 | messagesConnection(before: $before, last: $last) { 6 | pageInfo { 7 | hasPreviousPage 8 | } 9 | edges { 10 | node { 11 | id 12 | __typename 13 | messageId 14 | text 15 | linkifiedText 16 | authorNickname 17 | state 18 | vote 19 | voteReason 20 | creationTime 21 | suggestedReplies 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/poe_graphql/ChatViewQuery.graphql: -------------------------------------------------------------------------------- 1 | query ChatViewQuery($bot: String!) { 2 | chatOfBot(bot: $bot) { 3 | id 4 | chatId 5 | defaultBotNickname 6 | shouldShowDisclaimer 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/poe_graphql/DeleteHumanMessagesMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation DeleteHumanMessagesMutation($messageIds: [BigInt!]!) { 2 | messagesDelete(messageIds: $messageIds) { 3 | viewer { 4 | id 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/poe_graphql/DeleteMessageMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation deleteMessageMutation( 2 | $messageIds: [BigInt!]! 3 | ) { 4 | messagesDelete(messageIds: $messageIds) { 5 | edgeIds 6 | } 7 | } -------------------------------------------------------------------------------- /src/poe_graphql/HandleFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment HandleFragment on Viewer { 2 | id 3 | poeUser { 4 | id 5 | uid 6 | handle 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/poe_graphql/LoginWithVerificationCodeMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation LoginWithVerificationCodeMutation( 2 | $verificationCode: String! 3 | $emailAddress: String 4 | $phoneNumber: String 5 | ) { 6 | loginWithVerificationCode( 7 | verificationCode: $verificationCode 8 | emailAddress: $emailAddress 9 | phoneNumber: $phoneNumber 10 | ) { 11 | status 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/poe_graphql/MessageAddedSubscription.graphql: -------------------------------------------------------------------------------- 1 | subscription subscriptions_messageAdded_Subscription( 2 | $chatId: BigInt! 3 | ) { 4 | messageAdded(chatId: $chatId) { 5 | id 6 | messageId 7 | creationTime 8 | clientNonce 9 | state 10 | ...ChatMessage_message 11 | ...chatHelpers_isBotMessage 12 | } 13 | } 14 | 15 | fragment ChatMessageDownvotedButton_message on Message { 16 | ...MessageFeedbackReasonModal_message 17 | ...MessageFeedbackOtherModal_message 18 | } 19 | 20 | fragment ChatMessageDropdownMenu_message on Message { 21 | id 22 | messageId 23 | vote 24 | text 25 | author 26 | ...chatHelpers_isBotMessage 27 | } 28 | 29 | fragment ChatMessageFeedbackButtons_message on Message { 30 | id 31 | messageId 32 | vote 33 | voteReason 34 | ...ChatMessageDownvotedButton_message 35 | } 36 | 37 | fragment ChatMessageOverflowButton_message on Message { 38 | text 39 | ...ChatMessageDropdownMenu_message 40 | ...chatHelpers_isBotMessage 41 | } 42 | 43 | fragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message { 44 | messageId 45 | } 46 | 47 | fragment ChatMessageSuggestedReplies_message on Message { 48 | suggestedReplies 49 | author 50 | ...ChatMessageSuggestedReplies_SuggestedReplyButton_message 51 | } 52 | 53 | fragment ChatMessage_message on Message { 54 | id 55 | messageId 56 | text 57 | author 58 | linkifiedText 59 | state 60 | contentType 61 | ...ChatMessageSuggestedReplies_message 62 | ...ChatMessageFeedbackButtons_message 63 | ...ChatMessageOverflowButton_message 64 | ...chatHelpers_isHumanMessage 65 | ...chatHelpers_isBotMessage 66 | ...chatHelpers_isChatBreak 67 | ...chatHelpers_useTimeoutLevel 68 | ...MarkdownLinkInner_message 69 | ...IdAnnotation_node 70 | } 71 | 72 | fragment IdAnnotation_node on Node { 73 | __isNode: __typename 74 | id 75 | } 76 | 77 | fragment MarkdownLinkInner_message on Message { 78 | messageId 79 | } 80 | 81 | fragment MessageFeedbackOtherModal_message on Message { 82 | id 83 | messageId 84 | } 85 | 86 | fragment MessageFeedbackReasonModal_message on Message { 87 | id 88 | messageId 89 | } 90 | 91 | fragment chatHelpers_isBotMessage on Message { 92 | ...chatHelpers_isHumanMessage 93 | ...chatHelpers_isChatBreak 94 | } 95 | 96 | fragment chatHelpers_isChatBreak on Message { 97 | author 98 | } 99 | 100 | fragment chatHelpers_isHumanMessage on Message { 101 | author 102 | } 103 | 104 | fragment chatHelpers_useTimeoutLevel on Message { 105 | id 106 | state 107 | text 108 | messageId 109 | author 110 | chat { 111 | chatId 112 | defaultBotNickname 113 | id 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/poe_graphql/MessageDeletedSubscription.graphql: -------------------------------------------------------------------------------- 1 | subscription subscriptions_messageDeleted_Subscription( 2 | $chatId: BigInt! 3 | ) { 4 | messageDeleted(chatId: $chatId) { 5 | id 6 | messageId 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/poe_graphql/MessageFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment MessageFragment on Message { 2 | id 3 | __typename 4 | messageId 5 | text 6 | linkifiedText 7 | authorNickname 8 | state 9 | vote 10 | voteReason 11 | creationTime 12 | suggestedReplies 13 | } 14 | -------------------------------------------------------------------------------- /src/poe_graphql/MessageRemoveVoteMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation MessageRemoveVoteMutation($messageId: BigInt!) { 2 | messageRemoveVote(messageId: $messageId) { 3 | message { 4 | ...MessageFragment 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/poe_graphql/MessageSetVoteMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation MessageSetVoteMutation($messageId: BigInt!, $voteType: VoteType!, $reason: String) { 2 | messageSetVote(messageId: $messageId, voteType: $voteType, reason: $reason) { 3 | message { 4 | ...MessageFragment 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/poe_graphql/SendMessageMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation chatHelpers_sendMessageMutation_Mutation( 2 | $chatId: BigInt! 3 | $bot: String! 4 | $query: String! 5 | $source: MessageSource 6 | $withChatBreak: Boolean! 7 | ) { 8 | messageEdgeCreate(chatId: $chatId, bot: $bot, query: $query, source: $source, withChatBreak: $withChatBreak) { 9 | chatBreak { 10 | cursor 11 | node { 12 | id 13 | messageId 14 | text 15 | author 16 | suggestedReplies 17 | creationTime 18 | state 19 | } 20 | id 21 | } 22 | message { 23 | cursor 24 | node { 25 | id 26 | messageId 27 | text 28 | author 29 | suggestedReplies 30 | creationTime 31 | state 32 | chat { 33 | shouldShowDisclaimer 34 | id 35 | } 36 | } 37 | id 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/poe_graphql/SendVerificationCodeForLoginMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation SendVerificationCodeForLoginMutation( 2 | $emailAddress: String 3 | $phoneNumber: String 4 | ) { 5 | sendVerificationCode( 6 | verificationReason: login 7 | emailAddress: $emailAddress 8 | phoneNumber: $phoneNumber 9 | ) { 10 | status 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/poe_graphql/ShareMessagesMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation ShareMessagesMutation( 2 | $chatId: BigInt! 3 | $messageIds: [BigInt!]! 4 | $comment: String 5 | ) { 6 | messagesShare(chatId: $chatId, messageIds: $messageIds, comment: $comment) { 7 | shareCode 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/poe_graphql/SignupWithVerificationCodeMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation SignupWithVerificationCodeMutation( 2 | $verificationCode: String! 3 | $emailAddress: String 4 | $phoneNumber: String 5 | ) { 6 | signupWithVerificationCode( 7 | verificationCode: $verificationCode 8 | emailAddress: $emailAddress 9 | phoneNumber: $phoneNumber 10 | ) { 11 | status 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/poe_graphql/StaleChatUpdateMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation StaleChatUpdateMutation($chatId: BigInt!) { 2 | staleChatUpdate(chatId: $chatId) { 3 | message { 4 | ...MessageFragment 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/poe_graphql/SubscriptionsMutation.graphql: -------------------------------------------------------------------------------- 1 | mutation subscriptionsMutation( 2 | $subscriptions: [AutoSubscriptionQuery!]! 3 | ) { 4 | autoSubscribe(subscriptions: $subscriptions) { 5 | viewer { 6 | id 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/poe_graphql/SummarizePlainPostQuery.graphql: -------------------------------------------------------------------------------- 1 | query SummarizePlainPostQuery($comment: String!) { 2 | summarizePlainPost(comment: $comment) 3 | } 4 | -------------------------------------------------------------------------------- /src/poe_graphql/SummarizeQuotePostQuery.graphql: -------------------------------------------------------------------------------- 1 | query SummarizeQuotePostQuery($comment: String, $quotedPostId: BigInt!) { 2 | summarizeQuotePost(comment: $comment, quotedPostId: $quotedPostId) 3 | } 4 | -------------------------------------------------------------------------------- /src/poe_graphql/SummarizeSharePostQuery.graphql: -------------------------------------------------------------------------------- 1 | query SummarizeSharePostQuery($comment: String!, $chatId: BigInt!, $messageIds: [BigInt!]!) { 2 | summarizeSharePost(comment: $comment, chatId: $chatId, messageIds: $messageIds) 3 | } 4 | -------------------------------------------------------------------------------- /src/poe_graphql/UserSnippetFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment UserSnippetFragment on PoeUser { 2 | id 3 | uid 4 | bio 5 | handle 6 | fullName 7 | viewerIsFollowing 8 | isPoeOnlyUser 9 | profilePhotoURLTiny: profilePhotoUrl(size: tiny) 10 | profilePhotoURLSmall: profilePhotoUrl(size: small) 11 | profilePhotoURLMedium: profilePhotoUrl(size: medium) 12 | profilePhotoURLLarge: profilePhotoUrl(size: large) 13 | isFollowable 14 | } 15 | -------------------------------------------------------------------------------- /src/poe_graphql/ViewerInfoQuery.graphql: -------------------------------------------------------------------------------- 1 | query ViewerInfoQuery { 2 | viewer { 3 | id 4 | uid 5 | ...ViewerStateFragment 6 | ...BioFragment 7 | ...HandleFragment 8 | hasCompletedMultiplayerNux 9 | poeUser { 10 | id 11 | ...UserSnippetFragment 12 | } 13 | messageLimit{ 14 | canSend 15 | numMessagesRemaining 16 | resetTime 17 | shouldShowReminder 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/poe_graphql/ViewerMessageLimitUpdatedSubscription.graphql: -------------------------------------------------------------------------------- 1 | subscription subscriptions_viewerMessageLimitUpdated_Subscription { 2 | viewerMessageLimitUpdated { 3 | ...SettingsSubscriptionSection_viewer 4 | id 5 | } 6 | } 7 | 8 | fragment SettingsSubscriptionPaywallModal_viewer on Viewer { 9 | ...WebSubscriptionPaywall_viewer 10 | } 11 | 12 | fragment SettingsSubscriptionSectionNonSubscriberView_viewer on Viewer { 13 | ...SettingsSubscriptionPaywallModal_viewer 14 | } 15 | 16 | fragment SettingsSubscriptionSectionSubscriberView_viewer on Viewer { 17 | subscription { 18 | isActive 19 | expiresTime 20 | purchaseType 21 | isAnnualSubscription 22 | willCancelAtPeriodEnd 23 | id 24 | } 25 | } 26 | 27 | fragment SettingsSubscriptionSection_viewer on Viewer { 28 | availableBots { 29 | displayName 30 | messageLimit { 31 | canSend 32 | numMessagesRemaining 33 | resetTime 34 | dailyBalance 35 | dailyLimit 36 | monthlyBalance 37 | monthlyLimit 38 | monthlyBalanceRefreshTime 39 | shouldShowRemainingMessageCount 40 | } 41 | id 42 | } 43 | subscription { 44 | isActive 45 | id 46 | } 47 | isEligibleForWebSubscriptions 48 | ...SettingsSubscriptionSectionNonSubscriberView_viewer 49 | ...SettingsSubscriptionSectionSubscriberView_viewer 50 | ...WebSubscriptionSuccessMessage_viewer 51 | } 52 | 53 | fragment SubscriptionMessageLimitExplanation_viewer on Viewer { 54 | availableBots { 55 | displayName 56 | messageLimit { 57 | monthlyLimit 58 | } 59 | id 60 | } 61 | } 62 | 63 | fragment WebSubscriptionPaywall_viewer on Viewer { 64 | ...SubscriptionMessageLimitExplanation_viewer 65 | webSubscriptionPriceInfo { 66 | monthlyPrice 67 | yearlyPrice 68 | yearlyPricePerMonth 69 | yearlyPercentageSavings 70 | id 71 | } 72 | } 73 | 74 | fragment WebSubscriptionSuccessMessage_viewer on Viewer { 75 | subscription { 76 | isActive 77 | expiresTime 78 | willCancelAtPeriodEnd 79 | id 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/poe_graphql/ViewerStateFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment ViewerStateFragment on Viewer { 2 | id 3 | __typename 4 | iosMinSupportedVersion: integerGate(gateName: "poe_ios_min_supported_version") 5 | iosMinEncouragedVersion: integerGate( 6 | gateName: "poe_ios_min_encouraged_version" 7 | ) 8 | macosMinSupportedVersion: integerGate( 9 | gateName: "poe_macos_min_supported_version" 10 | ) 11 | macosMinEncouragedVersion: integerGate( 12 | gateName: "poe_macos_min_encouraged_version" 13 | ) 14 | showPoeDebugPanel: booleanGate(gateName: "poe_show_debug_panel") 15 | enableCommunityFeed: booleanGate(gateName: "enable_poe_shares_feed") 16 | linkifyText: booleanGate(gateName: "poe_linkify_response") 17 | enableSuggestedReplies: booleanGate(gateName: "poe_suggested_replies") 18 | removeInviteLimit: booleanGate(gateName: "poe_remove_invite_limit") 19 | enableInAppPurchases: booleanGate(gateName: "poe_enable_in_app_purchases") 20 | availableBots { 21 | nickname 22 | displayName 23 | profilePicture 24 | isDown 25 | disclaimer 26 | subtitle 27 | poweredBy 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/poe_graphql/ViewerStateUpdatedSubscription.graphql: -------------------------------------------------------------------------------- 1 | subscription subscriptions_viewerStateUpdated_Subscription { 2 | viewerStateUpdated { 3 | id 4 | ...ChatPageBotSwitcher_viewer 5 | } 6 | } 7 | 8 | fragment BotHeader_bot on Bot { 9 | displayName 10 | messageLimit { 11 | dailyLimit 12 | } 13 | ...BotImage_bot 14 | ...BotLink_bot 15 | ...IdAnnotation_node 16 | ...botHelpers_useViewerCanAccessPrivateBot 17 | ...botHelpers_useDeletion_bot 18 | } 19 | 20 | fragment BotImage_bot on Bot { 21 | displayName 22 | ...botHelpers_useDeletion_bot 23 | ...BotImage_useProfileImage_bot 24 | } 25 | 26 | fragment BotImage_useProfileImage_bot on Bot { 27 | image { 28 | __typename 29 | ... on LocalBotImage { 30 | localName 31 | } 32 | ... on UrlBotImage { 33 | url 34 | } 35 | } 36 | ...botHelpers_useDeletion_bot 37 | } 38 | 39 | fragment BotLink_bot on Bot { 40 | displayName 41 | } 42 | 43 | fragment ChatPageBotSwitcher_viewer on Viewer { 44 | availableBots { 45 | id 46 | handle 47 | ...BotHeader_bot 48 | } 49 | } 50 | 51 | fragment IdAnnotation_node on Node { 52 | __isNode: __typename 53 | id 54 | } 55 | 56 | fragment botHelpers_useDeletion_bot on Bot { 57 | deletionState 58 | } 59 | 60 | fragment botHelpers_useViewerCanAccessPrivateBot on Bot { 61 | isPrivateBot 62 | viewerIsCreator 63 | } 64 | -------------------------------------------------------------------------------- /src/sentencepiece/llama.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/src/sentencepiece/llama.model -------------------------------------------------------------------------------- /src/sentencepiece/mistral.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/src/sentencepiece/mistral.model -------------------------------------------------------------------------------- /src/sentencepiece/nerdstash.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/src/sentencepiece/nerdstash.model -------------------------------------------------------------------------------- /src/sentencepiece/nerdstash_v2.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LegendPoet/SillyTavern-fix/3cdfc85343deacc3ec96b957fe59d877864a1ed5/src/sentencepiece/nerdstash_v2.model -------------------------------------------------------------------------------- /src/transformers.mjs: -------------------------------------------------------------------------------- 1 | import { pipeline, env, RawImage, Pipeline } from 'sillytavern-transformers'; 2 | import { getConfigValue } from './util.js'; 3 | import path from 'path'; 4 | import _ from 'lodash'; 5 | 6 | configureTransformers(); 7 | 8 | function configureTransformers() { 9 | // Limit the number of threads to 1 to avoid issues on Android 10 | env.backends.onnx.wasm.numThreads = 1; 11 | // Use WASM from a local folder to avoid CDN connections 12 | env.backends.onnx.wasm.wasmPaths = path.join(process.cwd(), 'dist') + path.sep; 13 | } 14 | 15 | const tasks = { 16 | 'text-classification': { 17 | defaultModel: 'Cohee/distilbert-base-uncased-go-emotions-onnx', 18 | pipeline: null, 19 | configField: 'extras.classificationModel', 20 | }, 21 | 'image-to-text': { 22 | defaultModel: 'Xenova/vit-gpt2-image-captioning', 23 | pipeline: null, 24 | configField: 'extras.captioningModel', 25 | }, 26 | 'feature-extraction': { 27 | defaultModel: 'Xenova/all-mpnet-base-v2', 28 | pipeline: null, 29 | configField: 'extras.embeddingModel', 30 | }, 31 | 'text-generation': { 32 | defaultModel: 'Cohee/fooocus_expansion-onnx', 33 | pipeline: null, 34 | configField: 'extras.promptExpansionModel', 35 | }, 36 | } 37 | 38 | /** 39 | * Gets a RawImage object from a base64-encoded image. 40 | * @param {string} image Base64-encoded image 41 | * @returns {Promise<RawImage|null>} Object representing the image 42 | */ 43 | async function getRawImage(image) { 44 | try { 45 | const buffer = Buffer.from(image, 'base64'); 46 | const byteArray = new Uint8Array(buffer); 47 | const blob = new Blob([byteArray]); 48 | 49 | const rawImage = await RawImage.fromBlob(blob); 50 | return rawImage; 51 | } catch { 52 | return null; 53 | } 54 | } 55 | 56 | /** 57 | * Gets the model to use for a given transformers.js task. 58 | * @param {string} task The task to get the model for 59 | * @returns {string} The model to use for the given task 60 | */ 61 | function getModelForTask(task) { 62 | const defaultModel = tasks[task].defaultModel; 63 | 64 | try { 65 | const model = getConfigValue(tasks[task].configField, null); 66 | return model || defaultModel; 67 | } catch (error) { 68 | console.warn('Failed to read config.conf, using default classification model.'); 69 | return defaultModel; 70 | } 71 | } 72 | 73 | /** 74 | * Gets the transformers.js pipeline for a given task. 75 | * @param {string} task The task to get the pipeline for 76 | * @returns {Promise<Pipeline>} Pipeline for the task 77 | */ 78 | async function getPipeline(task) { 79 | if (tasks[task].pipeline) { 80 | return tasks[task].pipeline; 81 | } 82 | 83 | const cache_dir = path.join(process.cwd(), 'cache'); 84 | const model = getModelForTask(task); 85 | const localOnly = getConfigValue('extras.disableAutoDownload', false); 86 | console.log('Initializing transformers.js pipeline for task', task, 'with model', model); 87 | const instance = await pipeline(task, model, { cache_dir, quantized: true, local_files_only: localOnly }); 88 | tasks[task].pipeline = instance; 89 | return instance; 90 | } 91 | 92 | export default { 93 | getPipeline, 94 | getRawImage, 95 | } 96 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! command -v npm &> /dev/null 4 | then 5 | read -p "npm is not installed. Do you want to install nodejs and npm? (y/n)" choice 6 | case "$choice" in 7 | y|Y ) 8 | echo "Installing nvm..." 9 | export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" 10 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 11 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash 12 | source ~/.bashrc 13 | nvm install --lts 14 | nvm use --lts;; 15 | n|N ) 16 | echo "Nodejs and npm will not be installed." 17 | exit;; 18 | * ) 19 | echo "Invalid option. Nodejs and npm will not be installed." 20 | exit;; 21 | esac 22 | fi 23 | 24 | # if running on replit patch whitelist 25 | if [ ! -z "$REPL_ID" ]; then 26 | echo -e "Running on Repl.it... \nPatching Whitelist..." 27 | sed -i 's|whitelistMode = true|whitelistMode = false|g' "config.conf" 28 | fi 29 | 30 | echo "Installing Node Modules..." 31 | npm i --no-audit 32 | 33 | echo "Entering SillyTavern..." 34 | node "$(dirname "$0")/server.js" 35 | --------------------------------------------------------------------------------