Compare commits

...

282 Commits

Author SHA1 Message Date
Cohee
99e3c22311 Refactor firstLoadInit to include initCustomSelectedSamplers and addDebugFunctions 2025-05-11 12:28:33 +03:00
Cohee
09f2b2f731 Handle unknown chat completion sources gracefully by logging an error and returning an empty string 2025-05-11 11:09:15 +03:00
Cohee
fc1020a8e4 Refactor sequence breaker parsing in getTextGenGenerationData function 2025-05-11 11:07:13 +03:00
Cohee
9305c29780 Merge pull request #3986 from 50h100a/pr_xtcdry
Update parameters for Mancer: +XTC, +DRY, -Mirostat
2025-05-11 10:56:31 +03:00
50h100a
2aa5addb1d Mancer parameters:
- Add XTC
- Add DRY
- Remove Mirostat
2025-05-10 19:04:32 -04:00
Cohee
e6530cb22d Install jimp plugins explicitly 2025-05-10 18:19:22 +03:00
Cohee
44b7a09cb6 Prompt Manager: add source display of pulled prompts (#3981)
* Prompt Manager: add source display of pulled prompts

* Fix copilot comments
2025-05-10 16:28:18 +03:00
Cohee
4c56f3068a Merge pull request #3983 from cloak1505/staging 2025-05-10 16:13:36 +03:00
cloak1505
cc75768668 Actual copy and paste
Turns out the doc is already alphabetized but with dead providers moved to the top, so I didn't have to alphabetize the whole list and manually remove the dead ones.
2025-05-10 05:42:15 -05:00
cloak1505
c7963d683f Update and alphabetize OpenRouter providers list 2025-05-09 23:41:19 -05:00
Cohee
b2ed69aac2 Merge pull request #3980 from SillyTavern/fix-lcpp-caption
Fix llama.cpp captioning
2025-05-09 23:29:06 +03:00
Cohee
aef005007f Do not remove data URI prefix from llamacpp caption requests 2025-05-09 23:23:34 +03:00
Cohee
8a4da487dd llamacpp: use generic CC endpoint for captioning 2025-05-09 22:33:25 +03:00
Cohee
c6a64d8526 xAI: fix model not saving to presets 2025-05-09 00:24:36 +03:00
Cohee
104d4ccebc Merge pull request #3971 from SillyTavern/ccllaauuddee
Assorted Claude adjustments
2025-05-09 00:02:30 +03:00
Cohee
596353389b DeepSeek: don't send empty required arrays in tool definitions 2025-05-08 21:22:58 +03:00
Cohee
c1c77a6a60 Claude: add web search tool, adjust prefill voiding
Closes #3968
2025-05-08 20:51:38 +03:00
Cohee
da7f97b663 Claude: "Auto" effort = no thinking 2025-05-08 20:28:35 +03:00
Cohee
b71b94d410 Merge pull request #3964 from SillyTavern/click-to-edit
Decouple "click to edit" from document mode
2025-05-07 23:29:06 +03:00
Cohee
fa8ea7c60d mistral-medium-2505 2025-05-07 20:09:56 +03:00
Cohee
7a4d6ecfde Migrate old preference for "click to edit" setting based on chat display style 2025-05-07 11:12:41 +00:00
Cohee
5c027634ff Merge pull request #3961 from DocShotgun/staging 2025-05-07 00:32:48 +03:00
DocShotgun
3be991591f Remove special handling of nsigma for llama.cpp
* 0 now changed to disable/no-op upstream
2025-05-06 14:11:00 -07:00
Cohee
5e31a21d8d Decouple "click to edit" from document mode 2025-05-06 22:02:20 +03:00
Cohee
0f1bb766f6 Merge pull request #3963 from sirius422/staging
Add support for gemini-2.5-pro-preview-05-06
2025-05-06 19:43:49 +03:00
DocShotgun
4a5d0df92f Translate nsigma 0 to -1 to disable for llama.cpp 2025-05-06 09:31:55 -07:00
sirius422
edb9702055 Add support for gemini-2.5-pro-preview-05-06 2025-05-07 00:29:26 +08:00
DocShotgun
bf8b3b5013 Remove tfs_z alias for llama.cpp
* This sampler is no longer supported in llama.cpp
2025-05-06 00:39:25 -07:00
DocShotgun
bf66a39579 Update llama.cpp textgen settings
* Add min_keep, a llama.cpp-exclusive setting for constraining the effect of truncation samplers
* Enable nsigma for llama.cpp, and add llama.cpp alias top_n_sigma, add nsigma to the llama.cpp sampler order block
* Allow a negative value of nsigma as this represents 'disabled' in llama.cpp (while 0 is deterministic)
* Remove tfs and top_a as these are not supported by llama.cpp (tfs was removed, and top_a was never supported)
* Correct the identification string for typical_p in the llama.cpp sampler order block
* Add penalties to the llama.cpp sampler order block
2025-05-06 00:32:29 -07:00
Cohee
6625e4036e Add clipboard script commands
Closes #3958
2025-05-05 21:58:06 +03:00
Cohee
c626700226 Merge pull request #3955 from SillyTavern/pin-styles
Add style pin feature for greeting messages
2025-05-05 21:09:15 +03:00
Cohee
835c731bcd Merge pull request #3957 from RivelleDays/staging
Update zh-tw.json
2025-05-05 16:44:29 +03:00
Rivelle
78b42905f4 Update zh-tw.json 2025-05-05 21:21:44 +08:00
Rivelle
7b777fb803 Update zh-tw.json 2025-05-05 20:24:12 +08:00
Cohee
fc43ae3891 Merge branch 'staging' into pin-styles 2025-05-04 23:06:19 +03:00
Cohee
df07fa8c94 Merge pull request #3803 from SillyTavern/ffmpeg-videobg
Upload video bg via converter extension
2025-05-04 23:03:19 +03:00
Cohee
573ada296e Merge branch 'staging' into ffmpeg-videobg 2025-05-04 22:05:15 +03:00
Cohee
636ecef28a Merge pull request #3953 from Samueras/release 2025-05-04 20:55:23 +03:00
Samueras
3db2db1c65 Removed Swipe_right from legacy export
Removed Swipe_right from legacy export
2025-05-04 18:20:40 +02:00
Samueras
f0fbd7e3d4 added swipe left and right to st-context
Added swipe_right and swipe_left to st-context as a swipe group.
2025-05-04 18:17:44 +02:00
Samueras
99f47de88b Export Swipe left and right
Exporting the swipe_left and the swipe_right functions
2025-05-04 18:15:28 +02:00
Cohee
ca29de4704 Add style pin feature for greeting messages 2025-05-04 17:48:36 +03:00
Cohee
bb9fe64652 Merge pull request #3930 from Yokayo/staging
Update ru-ru translation
2025-05-04 14:10:12 +03:00
Cohee
4e0685f998 Revert comment 2025-05-04 14:05:44 +03:00
Cohee
bf9ef8fa0f Remove debug logs 2025-05-04 14:00:55 +03:00
Samueras
3165537ce8 Update script.js
Added trailing comma
2025-05-04 12:12:50 +02:00
Samueras
5f79c0c262 Export swipe_right in public/script.js 2025-05-04 12:05:45 +02:00
Samueras
27f2fac916 Export swipe_right in public/script.js and add swipe_right to getContext in st-context.js 2025-05-04 11:59:17 +02:00
Cohee
1e57342639 Use objects for pagination select creation 2025-05-04 12:56:23 +03:00
Cohee
b25322b844 Merge pull request #3933 from SillyTavern/feat/ext-installer-branch
Add branch selection on extension installer
2025-05-04 12:35:05 +03:00
Cohee
a122109e0c Add new model option 'embed-v4.0' to Cohere vectorization settings
Closes #3951
2025-05-04 12:26:44 +03:00
Yokayo
b9383ace1e eslint fixes 2 2025-05-03 18:16:02 +07:00
Yokayo
e27fca6628 eslint fixes 2025-05-03 18:14:26 +07:00
Yokayo
1822c4f91b More work on tl 2025-05-03 18:12:18 +07:00
Cohee
ec2876aefe Merge pull request #3941 from cloak1505/meth-patch
Remove Pygmalion instruct template (duplicate of Metharme)
2025-05-03 01:25:48 +03:00
Cohee
5fa64361c2 Merge pull request #3948 from InspectorCaracal/patch-3
Adds a check for jailbreaks existing in new TC PHI
2025-05-03 01:19:16 +03:00
Cohee
07a6017443 Remove redundant condition 2025-05-03 01:18:58 +03:00
InspectorCaracal
b8f7675d8c don't inject empty jb 2025-05-02 14:57:51 -06:00
Cohee
becaee8f35 Merge pull request #3946 from InspectorCaracal/add-sys-name
Add a named argument of "name" to the `/sys` slash command
2025-05-02 00:58:37 +03:00
Cal
c677f0324a Add argument to command 2025-05-01 15:16:51 -06:00
Cohee
a089727591 Extract templates, replace pagination format 2025-05-01 17:46:02 +03:00
Cohee
62b02bec3f Merge pull request #3940 from wickedcode01/bug-fixed
Fix the issue where deleting files on Windows may cause the application to crash.
2025-05-01 17:00:11 +03:00
Cohee
60232c73cc Merge pull request #3942 from huisman/update_ollama_github
Update links to ollama gihub
2025-05-01 15:03:02 +03:00
huisman
2301b5324a Update ollama links to current ollama github url 2025-05-01 11:29:39 +00:00
cloak1505
db2971c82d Remove Pygmalion instruct template (duplicate of Metharme)
ST already applies user sequence as stop string, so Pygmalion's <|user|> stop_sequence is meaningless.
2025-05-01 03:24:28 -05:00
wickedcode
d3bb625efe fix: recommend to use unlinkSync instead of rmSync, which has a better compatibility handling non-English characters 2025-05-01 03:09:25 -04:00
wickedcode
7431b0e8aa fix: replace rmSync with unlinkSync to resolve an issue deleting files with non-English characters in their names 2025-05-01 02:23:19 -04:00
Cohee
2c0dcdc449 Refactor git operations to use baseDir 2025-04-30 23:54:14 +03:00
Cohee
63b48b9211 Log a warning on an unknown input type 2025-04-30 22:58:43 +03:00
Cohee
ef59afcec1 Specify tag support in messaging 2025-04-30 22:56:35 +03:00
Cohee
9cff3861b4 Fix path.join to extension 2025-04-30 22:41:50 +03:00
Cohee
757b7d5371 Merge branch 'staging' into feat/ext-installer-branch 2025-04-30 22:38:55 +03:00
Cohee
b3a3b9d347 Fix npm audit in tests 2025-04-30 22:36:24 +03:00
Cohee
999a43b2e5 Merge branch 'staging' into feat/ext-installer-branch 2025-04-30 22:35:01 +03:00
Cohee
048ea943bc Merge pull request #3926 from SillyTavern/tc-phi
TC sysprompt: Add Post-History Instructions control
2025-04-30 22:34:22 +03:00
Cohee
511ae39b0b Move margin class 2025-04-30 22:23:12 +03:00
Cohee
63e7139a81 Clean-up i18n 2025-04-30 22:00:09 +03:00
Cohee
8dc7aa0c20 Add post_history field to default prompts 2025-04-30 21:07:06 +03:00
Cohee
8c42de7565 Merge branch 'staging' into tc-phi 2025-04-30 21:04:36 +03:00
Cohee
7deef1aa12 Merge pull request #3937 from Ristellise/staging
Check for `error` as well when parsing streaming responses
2025-04-30 16:31:05 +03:00
Shinon
98e96b8c07 Check for error as well when parsing streaming responses 2025-04-30 21:23:13 +08:00
Cohee
a5d63b064a Merge pull request #3928 from BismuthGlass/feature/regex-test-match
Add both `test` and `match` regex commands
2025-04-29 21:44:17 +03:00
Cohee
6aeced98a6 Prefer const. I love const 2025-04-29 21:22:51 +03:00
Crow
6cb1eb3fe6 Change return to empty string on no single match 2025-04-29 15:21:45 +01:00
Yokayo
e4d389a5b6 eslint fix 2025-04-29 17:24:49 +07:00
Yokayo
7eb23a2fcc Work on tl 2025-04-29 17:23:18 +07:00
Yokayo
db67633af6 Merge branch 'SillyTavern:staging' into staging 2025-04-29 17:16:15 +07:00
Crow
0cd0ce2374 Fix example formatting on /replace 2025-04-29 06:38:30 +01:00
Crow
5ddc8f17a0 Fix pattern checking on /replace 2025-04-29 06:37:48 +01:00
Crow
1c40ea10f4 Format examples correctly 2025-04-29 06:37:08 +01:00
Crow
729830c2fc Validate pattern 2025-04-29 06:19:59 +01:00
Cohee
71e92af09d Fix console verbiage for global extensions 2025-04-29 02:02:20 +03:00
Cohee
3340009a29 Add branch management functionality for extensions 2025-04-29 02:00:25 +03:00
Cohee
310b0f30cd Add branch selection on extension installer
Closes #3865
2025-04-28 22:53:22 +03:00
Cohee
0ca4cc08bb Sync OpenRouter providers list 2025-04-28 21:57:47 +03:00
Yokayo
666d5712c7 A bit more clarity 2025-04-28 19:03:18 +07:00
Yokayo
c453e94486 eslint fixes #2 2025-04-28 18:56:43 +07:00
Yokayo
f0d01d35a6 eslint fixes 2025-04-28 18:55:10 +07:00
Yokayo
11908f7363 Work on tl 2025-04-28 18:45:16 +07:00
Crow
d5002863e0 Add both test and match regex commands
These commands match the behavior of the javascript `Regex.test()`
and `String.match()` / `String.matchAll()` functions.
2025-04-28 11:13:48 +01:00
Cohee
775ae0f557 TC sysprompt: Add Post-History Instructions control
Closes #3920
2025-04-28 00:14:57 +03:00
Cohee
97e1f482c1 Add class to AdvancedFormatting 2025-04-27 23:19:21 +03:00
Cohee
05daddb60c Fix KoboldCpp saved vectors retrieval 2025-04-27 23:18:39 +03:00
Cohee
ed895b7c3e Merge pull request #3889 from BismuthGlass/feature/wi_global_matches
World Info chat-independent data matching
2025-04-27 21:00:57 +03:00
Cohee
6fb664fe24 Merge pull request #3919 from cloak1505/gemini-patch
Prune Google models
2025-04-27 20:36:47 +03:00
Cohee
0f8b610454 Prettify captioning model redirects 2025-04-27 20:36:14 +03:00
cloak1505
d8bc38c0b0 Make the redirection note slightly less eye bleeding 2025-04-27 12:31:19 -05:00
Cohee
54e880ef32 Align matching sources in two columns 2025-04-27 19:35:17 +03:00
Cohee
28ca8176f8 Merge pull request #3857 from wrvsrx/allow-readonly-install
Allow read-only installation
2025-04-27 19:12:12 +03:00
Cohee
0aad86c0b6 Add /colab to .dockerignore and .npmignore 2025-04-27 19:07:52 +03:00
Cohee
12badb3d67 Fix Docker build 2025-04-27 18:29:27 +03:00
Cohee
31cc05ae46 Move setPermissionsSync to util 2025-04-27 18:23:57 +03:00
Cohee
3e0697b7c7 Lintfix 2025-04-27 15:16:46 +03:00
Cohee
7c54a74ffa Add another ugli ahh list for no grounding models 2025-04-27 15:11:23 +03:00
Cohee
15daf19a08 Streaming endpoint is no longer busted
But still ass
2025-04-27 14:58:23 +03:00
Cohee
61c7f53d22 Move endpoint version to conifg. Refactor ugli model lists 2025-04-27 14:56:51 +03:00
Cohee
10f51b703b Merge pull request #3921 from A1KESH1/Update-zh-cn-translations
Update zh-cn translation
2025-04-27 14:06:17 +03:00
爱克狮
dd1c506694 Update zh-cn.json 2025-04-27 16:50:42 +08:00
爱克狮
9c9ed1593a Update zh-cn translation 2025-04-27 16:44:31 +08:00
cloak1505
acc05e633d gemini-exp to max_1mil context 2025-04-26 20:38:35 -05:00
cloak1505
4599797baf Revert responsive Google models per Cohee's executive order
I was wrong on a few models. At least Gemini still fits on a 1440p monitor.
2025-04-26 20:04:50 -05:00
cloak1505
340be02777 Default HARM_CATEGORY_CIVIC_INTEGRITY to OFF
All models support either all BLOCK_NONE, or all OFF.
2025-04-26 18:43:56 -05:00
Cohee
3e11a90b3c Add message and example counts to itemization templates 2025-04-27 02:26:43 +03:00
cloak1505
fc09be75a6 Almost done with Google pruning
* Put back 1.5-latest
* Put back missing flash 002 (same deal about safetySettings like pro 001 vs 002)
* Remove dead models and gemma from BLOCK_NONE check
2025-04-26 17:54:34 -05:00
cloak1505
af64ac001a Update caption_multimodal_model
And fix optgroup typo
2025-04-26 14:33:47 -05:00
cloak1505
c6a047651b Add 'learn' to visionSupportedModels
Also remove dead gemini-exp models
2025-04-26 14:23:10 -05:00
cloak1505
023976444f Oops, gemini-1.5-pro-001 is still live 2025-04-26 14:04:31 -05:00
cloak1505
05e60ff00b Exclude gemini-2.0-flash-lite from web search 2025-04-26 13:04:00 -05:00
cloak1505
a764e5ce54 Exclude LearnLM from web search 2025-04-26 12:51:26 -05:00
cloak1505
01d52f140a Update "Use system prompt" 2025-04-26 12:19:06 -05:00
cloak1505
28d42e5200 Prune Google models 2025-04-26 11:39:44 -05:00
Cohee
37c97db969 Merge pull request #3916 from SillyTavern/fix-instruct-regex
Check instruct activation regex before selecting context template
2025-04-26 14:25:35 +03:00
Cohee
84f339cdd6 Merge pull request #3913 from SillyTavern/fix-continue-suffix
Fix continuation suffix trimming
2025-04-26 01:47:52 +03:00
Cohee
a927ab557a Check instruct activation regex before selecting bound context template match 2025-04-26 01:47:07 +03:00
Cohee
6848b38bb7 Merge pull request #3900 from equal-l2/vision-cleanup
Vision cleanup
2025-04-26 01:21:42 +03:00
Cohee
e621f0d967 Remove model name check in convertGooglePrompt 2025-04-26 00:34:21 +03:00
Cohee
76aa17e08f Merge pull request #3911 from cloak1505/staging
Normalize instruct names behavior and repair Lightning 1.1's system prompt
2025-04-26 00:10:01 +03:00
cloak1505
321efa354a Update index.json 2025-04-25 15:35:44 -05:00
cloak1505
82c86c9ce6 Clean Lightning 1.1 2025-04-25 14:57:42 -05:00
Cohee
dafc4e8098 Merge pull request #3915 from SillyTavern/feat/refactor-wi-init
Refactor WI init to init function for more consistent startup
2025-04-25 22:28:55 +03:00
Cohee
005a495e96 Move config migration from post-install to src 2025-04-25 22:22:44 +03:00
Wolfsblvt
6eb89bd21c fix some linting 2025-04-25 20:58:28 +02:00
Wolfsblvt
05c010223b Move function above init
Well, I like that init is last in nearly all files...
2025-04-25 20:49:47 +02:00
Wolfsblvt
a667e14c8b Make global WI placeholder translatable 2025-04-25 20:45:13 +02:00
Cohee
cb32fb354c Merge pull request #3914 from cloak1505/google-patch
Print full Google response
2025-04-25 21:45:05 +03:00
Wolfsblvt
470a0964f7 Initialize world info during app startup
Moves world info event binding from jQuery document-ready handler
to explicit initialization function for better control flow
Ensures world info setup occurs after core dependencies are loaded
2025-04-25 20:43:13 +02:00
Cohee
776d220374 Why was it a warning level 2025-04-25 21:40:59 +03:00
cloak1505
93ea8b6a22 ESLint woes 2025-04-25 13:37:56 -05:00
cloak1505
ea7ff5b1c2 inspect depth 5 2025-04-25 13:22:33 -05:00
cloak1505
bd1d393e5d Print full Google response 2025-04-25 13:05:14 -05:00
Cohee
421c924c22 Do not append empty joiners 2025-04-25 21:01:53 +03:00
Cohee
5c4794812f Move creatorNotes macro init 2025-04-25 20:54:24 +03:00
Cohee
b3e51c8b1c Fix continuation suffix trimming
Fixes #3901
2025-04-25 20:20:53 +03:00
Cohee
74f441d0ba Merge pull request #3912 from kallewoof/202504-glm-4-sop-nl
trivial: remove extraneous \n after sop token
2025-04-25 19:14:56 +03:00
Karl-Johan Alm
cf7edd99a7 trivial: remove extraneous \n after sop token 2025-04-26 00:08:02 +09:00
cloak1505
2151ae7aaa Normalize instruct "names_behavior" to "force" for those that don't require "none" or "always 2025-04-25 09:40:49 -05:00
cloak1505
81fec97f54 Repair Lightning 1.1's system prompt 2025-04-25 09:22:10 -05:00
Cohee
4ce7e97ab3 Merge pull request #3908 from cloak1505/staging
Remove last message role restriction for Cohere
2025-04-25 13:27:59 +03:00
Cohee
abb6706601 Merge pull request #3906 from kallewoof/202504-glm-4-presets
chat preset: GLM-4
2025-04-25 13:25:08 +03:00
Karl-Johan Alm
2d366117dd chat preset: GLM-4 2025-04-25 15:22:51 +09:00
Crow
b233cc2480 Add extra field docs 2025-04-25 03:23:14 +01:00
Crow
bb9f765ce3 Add pointer cursor to Additional Matching Sources drawer header 2025-04-25 03:17:13 +01:00
Crow
a3d7b540c7 Change field names to match required fields 2025-04-25 03:11:36 +01:00
cloak1505
a4442899f6 Remove last message role restriction for Cohere 2025-04-24 19:35:05 -05:00
Crow
b5280bbfc7 Add type data for v2DataWorldInfoEntryExtensionInfos match fields 2025-04-25 00:51:47 +01:00
Crow
9248bf1f63 Add creatorNotes macro expansion 2025-04-25 00:49:56 +01:00
Crow
6ddd395211 Move new globalScanData args to the end 2025-04-25 00:49:12 +01:00
Crow
178391e450 Add i18n for Additional Matching Sources header 2025-04-24 23:25:35 +01:00
Crow
f8b9c1f9f5 Move matching sources to bottom of entry editor 2025-04-24 20:30:13 +01:00
Crow
994f51c18e Add back chat param 2025-04-24 20:22:47 +01:00
Crow
5504021374 Add missing machCharacterPersonality to World Info Definition 2025-04-24 20:21:52 +01:00
Crow
4d483e7814 Change handleOptionalSelect name 2025-04-24 20:21:24 +01:00
Crow
7b1baed0d7 Revert world_entry_form_control css class changes 2025-04-24 20:16:10 +01:00
Crow
d7780ee4bb Fix character card lorebook imports / exports 2025-04-24 20:13:18 +01:00
Crow
be591b2494 Revert original settings to their former place 2025-04-24 19:15:32 +01:00
equal-l2
3fd12b28dc Merge branch 'staging' into vision-cleanup 2025-04-25 01:49:40 +09:00
equal-l2
903839c9c5 Use array syntax for excluding non-vision OpenAI models
Co-authored-by: Wolfsblvt <wolfsblvt@gmail.com>
2025-04-25 01:40:13 +09:00
Cohee
c16be2ec0e Change UI for failed integrity checks 2025-04-24 15:20:43 +00:00
Cohee
5b031ed5b4 Merge pull request #3902 from SillyTavern/openrouter-reasoning-effort
Add reasoning effort control for CC OpenRouter
2025-04-23 22:08:32 +03:00
Cohee
5241b22a73 Add reasoning effort control for CC OpenRouter
Closes #3890
2025-04-23 21:38:31 +03:00
Cohee
01c6544e22 Move server-main to /src 2025-04-23 20:50:46 +03:00
Cohee
d97aa0a270 CONFIG_FILE => CONFIG_PATH 2025-04-23 20:46:36 +03:00
Cohee
cfc41163e2 Merge pull request #3893 from SillyTavern/gemini-2.5-thinking
Thinking Budget 2.5: Electric Googaloo
2025-04-23 20:36:02 +03:00
Cohee
50cdaadba0 Only verify parts length 2025-04-23 20:05:28 +03:00
Cohee
cf44ac8c1f Don't add sys instruction if empty 2025-04-23 20:04:00 +03:00
equal-l2
3e8f9e2680 Fix for eslint 2025-04-24 00:02:43 +09:00
Cohee
5509b088e2 Add a blurb for OpenAI reasoning effort 2025-04-23 14:57:14 +00:00
Cohee
24f6b11cb9 Auto == medium for Claude 2025-04-23 14:54:54 +00:00
Cohee
bdf4241d18 Default to "Auto" reasoning effort 2025-04-23 14:54:34 +00:00
Cohee
d6c4b6f419 Google: Multipart system instruction 2025-04-23 14:50:01 +00:00
equal-l2
44c5ce9a30 Exclude o1-mini from vision supported models 2025-04-23 23:45:58 +09:00
equal-l2
65aec223a3 Vision models clean-up 2025-04-23 23:45:58 +09:00
Cohee
6878c79fc8 Prevent send on Enter when IME composing
Fixes #2398
2025-04-23 09:26:15 +00:00
wrvsrx
26a520af10 Support specifing config.yaml in cli 2025-04-23 11:18:30 +08:00
Cohee
f81bbbea08 Fix effort blurb title 2025-04-23 01:02:28 +03:00
Cohee
f61d600c05 ok buddy claude 2025-04-23 00:59:12 +03:00
Cohee
e43023fde7 Cut option labels 2025-04-23 00:54:03 +03:00
Cohee
266fa5cbf8 Make auto (undefined) actually work 2025-04-23 00:45:49 +03:00
Cohee
5c8b8f4b98 Refactor getReasoningEffort 2025-04-23 00:44:14 +03:00
Cohee
bee3cee740 Go team dropdown 2025-04-23 00:38:28 +03:00
Cohee
0520f3ccf4 Fix gpt-4o-mini snapshots 2025-04-22 23:28:49 +03:00
Cohee
fe4f0c2ea6 Merge pull request #3898 from awaae001/staging
feat(slash-commands): Add /goto-floor command and implement message highlighting
2025-04-22 22:37:08 +03:00
Cohee
870abe0776 Code clean-up 2025-04-22 22:36:01 +03:00
awaae001
b39b7998ce refactor(slash-commands): 优化消息定位和滚动效果 2025-04-23 01:34:29 +08:00
awaae001
59ebf2e5b8 refactor(slash-commands): 重命名 goto-floor 命令为 chat-jump
- 将命令名称从 'goto-floor' 修改为 'chat-jump',以更好地反映其功能
2025-04-23 01:12:57 +08:00
awaae001
ee11f021eb refactor(slash-commands): 优化 /goto-floor 命令并添加高亮功能
- 重新组织消息加载和滚动逻辑,提高命令成功率
- 添加消息元素高亮功能,使用 flashHighlight 或临时 CSS 类
2025-04-23 01:04:52 +08:00
awaae001
ceeaeea123 feat(slash-commands): 优化 /goto-floor 命令并加载所有消息
- 在执行 /goto-floor 命令前加载所有消息,确保目标元素存在
- 添加加载消息的步骤,解决因懒加载导致的元素找不到问题
2025-04-23 00:45:05 +08:00
awaae001
6d0318eb36 refactor(slash-commands): 优化 /goto-floor 命令的代码格式和注释
- 修正 EDLint 标记错误
2025-04-23 00:05:35 +08:00
awaae001
485d07b91f feat(slash-commands): 添加 /goto-floor 命令并实现消息高亮
- 新增 /goto-floor 命令,允许用户滚动到指定的消息索引
- 实现消息高亮功能,滚动到指定消息后进行突出显示
- 添加相关的 CSS 样式,确保高亮效果在不同浏览器中兼容
2025-04-22 23:51:40 +08:00
Cohee
4bcfe6c2be 0.7 is fine too 2025-04-21 21:21:41 +03:00
Cohee
b9a6361662 Merge pull request #3887 from Erquint/staging
Make scrollbars make sense.
2025-04-21 21:19:49 +03:00
Cohee
a95056db40 Thinking Budget 2.5: Electric Googaloo 2025-04-21 21:10:40 +03:00
Cohee
361b557509 Remove padding from enlarged image container 2025-04-21 19:51:30 +03:00
Cohee
6ace6a07d7 Revert font-size on html, increase sb width 2025-04-21 19:45:08 +03:00
Cohee
689637b36c Merge pull request #3891 from SillyTavern/staging
Staging
2025-04-21 18:51:57 +03:00
Cohee
d726aa5563 Update release version 2025-04-21 18:09:17 +03:00
Cohee
98b12e2bba Make rem units scale with the font size slider 2025-04-21 17:46:44 +03:00
Gness Erquint
320b188d47 Using em instead of rem for scrollbar width. 2025-04-21 17:39:24 +03:00
Gness Erquint
2fa1c69f3e Show scrollbar track only when hovered. 2025-04-21 17:34:55 +03:00
Crow
4db07402c4 Change double quotes to single quotes 2025-04-20 23:26:47 +01:00
Crow
b38673a5cd Fix matching issues for depth prompt 2025-04-20 23:15:30 +01:00
Crow
14582e67a0 Fix world info entry saves for match fields 2025-04-20 22:56:06 +01:00
Crow
2683549be8 Fix save bug 2025-04-20 22:40:44 +01:00
Cohee
b3e012bea3 Merge pull request #3888 from KTibow/patch-1
change language when context size exceeded
2025-04-21 00:26:40 +03:00
Kendell R
dd3d3226eb update per cohee recommendations 2025-04-20 14:20:13 -07:00
Kendell R
c63ef20919 change language when context size exceeded 2025-04-20 13:58:11 -07:00
Crow
f1b6a329c9 Remove newlines 2025-04-20 21:57:33 +01:00
Crow
a261e87d4c Pass global scan data to WI prompt generator 2025-04-20 21:56:01 +01:00
Crow
50379f6b6e Change character note to character depth prompt 2025-04-20 21:42:48 +01:00
Crow
d2ffefd24c Implement WI matching on global data 2025-04-20 21:09:19 +01:00
Crow
aa75fe2877 Revert global WI settings changes 2025-04-20 21:09:19 +01:00
Crow
b685c4f5bf Change match options to checkboxes 2025-04-20 21:09:19 +01:00
Crow
7748c315d7 Add WIGlobalScanData type 2025-04-20 21:09:19 +01:00
Crow
349d46d74a Change matchCreatorNotes name 2025-04-20 21:09:19 +01:00
Crow
8deaefc3a6 Fix field names 2025-04-20 21:09:19 +01:00
Crow
297cfe3098 Change matchCharacterMetadata to matchCreatorsNotes 2025-04-20 21:09:19 +01:00
Crow
750e8c89a7 Add WIEntry support for new match options 2025-04-20 21:09:19 +01:00
Crow
5bed367a32 Add controls for different WI matching targets
To accomodate new settings, the WI Entry panels were reworked
slightly to add a drawer. Both Global and Entry settings are
present.
2025-04-20 21:09:19 +01:00
Gness Erquint
7be1b039ac Make scrollbars make sense. 2025-04-20 22:44:33 +03:00
Cohee
fc892b4514 Merge pull request #3884 from Cyberes/improve-generic-import
downloadGenericPng() handle missing file PNG extension
2025-04-19 22:44:19 +03:00
Cohee
afe29c61cc Use getHostFromUrl for error log 2025-04-19 22:43:16 +03:00
Cohee
c28d0dec79 Merge pull request #3885 from Cyberes/whitelist-import-char-archive
add char-archive to whitelistImportDomains
2025-04-19 22:41:46 +03:00
Cohee
7f22def794 Merge pull request #3881 from DreamGenX/dg_lucid
DreamGen Lucid
2025-04-19 22:01:37 +03:00
Cyberes
13099c43a9 add char-archive to whitelistImportDomains 2025-04-19 12:30:14 -06:00
Cyberes
1a1464800f downloadGenericPng() handle missing file PNG extension, log generic import url, add error message for when generic import site is not whitelisted 2025-04-19 12:22:43 -06:00
DreamGenX
21f98f11e5 DreamGen Lucid 2025-04-19 15:18:06 +02:00
DreamGenX
dc6407ee8f DreamGen Lucid 2025-04-19 15:04:00 +02:00
Cohee
586ce36167 Merge pull request #3868 from YunZLu/staging
Fix Edge Browser TTS Compatibility
2025-04-19 01:15:14 +03:00
Cohee
3ba7291c35 Merge pull request #3873 from Teashrock/staging
Implemented /getglobalbooks STScript command
2025-04-19 01:05:43 +03:00
Cohee
75d0cf828a Fix callback return types 2025-04-19 01:05:14 +03:00
Cohee
9d8283e4c7 Fix assets_menu selector 2025-04-18 22:42:12 +03:00
Cohee
352a8c3c97 Fix TTS provider settings
Fixes #3877
2025-04-18 22:03:17 +03:00
Teashrock
e3f5949cc1 Implemented /getglobalbooks STScript command 2025-04-18 12:32:52 +03:00
Cohee
41e6161b1d Merge pull request #3870 from DAurielS/2.5-flash
Add Gemini 2.5 Flash Preview to Model List (Makersuite)
2025-04-18 12:02:43 +03:00
Daryl
7ef9ba4f03 Added support for system instructions for gemini 2.5 flash 2025-04-17 17:49:52 -04:00
Daryl
e0b7c9ef4c Fixed image viewing capabilities and added option for caption extension 2025-04-17 17:34:35 -04:00
Daryl
53dd3aed4e Cleaning up and checking for vision support 2025-04-17 16:48:27 -04:00
Daryl
c89c1beffd Added support for Gemini 2.5 Flash Preview 04/17 from Google AI Studio 2025-04-17 16:18:34 -04:00
YunZLu
41c2dd16f2 fix(eslint): resolve no-trailing-spaces error 2025-04-18 04:12:37 +08:00
YunZLu
d7cc70256a cleaned all redundant comments 2025-04-18 03:58:04 +08:00
Cohee
8f63edfd30 Fix handling of text parts in convertGooglePrompt function
Fixes #3855
2025-04-17 21:23:58 +03:00
Cohee
dfd78077ec Prevent fetch response status forwarding
Fixes #3864
2025-04-17 13:39:09 +00:00
YunZLu
d511875db9 Fix Edge Browser TTS Compatibility
Edge-compatible fallback for empty Web Speech voice lists
2025-04-17 19:46:49 +08:00
Cohee
7b2f1f7c7a Add o3 and o4-mini 2025-04-16 23:12:40 +03:00
Cohee
ead05934a0 CI: Fix eslint checkout step to use pull request head SHA and repository 2025-04-16 21:44:21 +03:00
Cohee
722b0698e9 Fix reasoning content bleeding into multi-swipes 2025-04-16 21:35:35 +03:00
Cohee
8aa6350c31 Merge pull request #3861 from BismuthGlass/feature/fix-nested-drawers
Fix nested inline-drawer behavior
2025-04-16 21:26:09 +03:00
Subwolf
c3717ff06a Merge pull request #3852 from subzero5544/xAI-grok-reverse-proxy-testing
Adding reverse proxy support to xai chat completion
2025-04-16 21:14:38 +03:00
Crow
3be02b7217 Fix nested inline-drawer behavior 2025-04-16 18:26:42 +01:00
Cohee
8e829c900b Merge pull request #3858 from pl752/staging
Added option to use secondary API URL in vector extension
2025-04-16 20:02:47 +03:00
pl752
07fb92b37d Added vector secondary url placeholder example 2025-04-16 17:39:29 +05:00
pl752
f8bccb472f Adjusted naming and validation 2025-04-16 17:34:58 +05:00
pl752
bfe50403af Forgot semicolons 2025-04-16 16:45:01 +05:00
pl752
5cf3198da1 Added option to use secondary API URL in vector extension 2025-04-16 16:04:33 +05:00
wrvsrx
bf97686dfc Allow read-only installation
Fix #3453.

Thanks to #3499, #3500 and #3521, most of the obstacles to read-only installation have been resolved. This PR addresses the final piece, ensuring that SillyTavern no longer changes directories to `serverDirectory` and outputs files there. Instead, it outputs or copies necessary files to the directory where it is being run. Now, `serverDirectory` is read-only for SillyTavern (i.e., SillyTavern will not attempt to modify `serverDirectory`). Additionally, this PR sets the permissions for copied `default-user` files to be writable, so even if SillyTavern is installed as read-only, the copied `default-user` folder can still be modified.
2025-04-16 09:52:08 +08:00
Cohee
491752599c Localize messages 2025-04-09 21:36:00 +03:00
Cohee
471004b828 Skill issue 2025-04-09 19:57:07 +03:00
Cohee
e9178e52eb Update upload to use fetch 2025-04-09 19:45:33 +03:00
Cohee
2fa6a11650 Merge branch 'staging' into ffmpeg-videobg 2025-04-09 19:37:11 +03:00
Cohee
d05373cdd2 Upload video bg via converter extension 2025-04-03 23:48:01 +03:00
Wolfsblvt
fef36bfc39 Fix deleting swipes overwriting reasoning
- Well, someone forgot about syncing extras and mes data again....
- Built the oppositive function of `syncMesToSwipe`, so we can now call `syncSwipeToMes`

Fixes #3787
2025-03-31 13:35:55 +00:00
InspectorCaracal
235a1372e8 fix group chid data attr 2025-03-23 14:45:10 +02:00
158 changed files with 3239 additions and 1912 deletions

View File

@@ -13,3 +13,4 @@ access.log
/cache
.DS_Store
/public/scripts/extensions/third-party
/colab

1
.github/readme.md vendored
View File

@@ -350,6 +350,7 @@ Start.bat --port 8000 --listen false
| Option | Description | Type |
|-------------------------|----------------------------------------------------------------------|----------|
| `--version` | Show version number | boolean |
| `--configPath` | Override the path to the config.yaml file | string |
| `--dataRoot` | Root directory for data storage | string |
| `--port` | Sets the port under which SillyTavern will run | number |
| `--listen` | SillyTavern will listen on all network interfaces | boolean |

View File

@@ -30,7 +30,8 @@ jobs:
# https://github.com/marketplace/actions/checkout
uses: actions/checkout@v4.2.2
with:
ref: ${{ github.head_ref }}
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Setup Node.js
# Setup Node.js environment

View File

@@ -12,3 +12,4 @@ access.log
.vscode
.git
/public/scripts/extensions/third-party
/colab

View File

@@ -12,15 +12,13 @@ WORKDIR ${APP_HOME}
# Set NODE_ENV to production
ENV NODE_ENV=production
# Install app dependencies
COPY package*.json post-install.js ./
# Bundle app source
COPY . ./
RUN \
echo "*** Install npm packages ***" && \
npm i --no-audit --no-fund --loglevel=error --no-progress --omit=dev && npm cache clean --force
# Bundle app source
COPY . ./
# Copy default chats, characters and user avatars to <folder>.default folder
RUN \
rm -f "config.yaml" || true && \

View File

@@ -155,6 +155,7 @@ whitelistImportDomains:
- cdn.discordapp.com
- files.catbox.moe
- raw.githubusercontent.com
- char-archive.evulid.cc
# API request overrides (for KoboldAI and Text Completion APIs)
## Note: host includes the port number if it's not the default (80 or 443)
## Format is an array of objects:
@@ -233,6 +234,10 @@ claude:
# should be ideal for most use cases.
# Any value other than a non-negative integer will be ignored and caching at depth will not be enabled.
cachingAtDepth: -1
# -- GOOGLE GEMINI API CONFIGURATION --
gemini:
# API endpoint version ("v1beta" or "v1alpha")
apiVersion: 'v1beta'
# -- SERVER PLUGIN CONFIGURATION --
enableServerPlugins: false
# Attempt to automatically update server plugins on startup

View File

@@ -540,7 +540,7 @@
"type": "context"
},
{
"filename": "presets/context/Pygmalion.json",
"filename": "presets/context/Metharme.json",
"type": "context"
},
{
@@ -619,10 +619,6 @@
"filename": "presets/instruct/OpenOrca-OpenChat.json",
"type": "instruct"
},
{
"filename": "presets/instruct/Pygmalion.json",
"type": "instruct"
},
{
"filename": "presets/instruct/Story.json",
"type": "instruct"
@@ -755,6 +751,10 @@
"filename": "presets/sysprompt/Neutral - Chat.json",
"type": "sysprompt"
},
{
"filename": "presets/sysprompt/Lightning 1.1.json",
"type": "sysprompt"
},
{
"filename": "presets/instruct/Mistral V1.json",
"type": "instruct"
@@ -795,6 +795,14 @@
"filename": "presets/context/DeepSeek-V2.5.json",
"type": "context"
},
{
"filename": "presets/instruct/GLM-4.json",
"type": "instruct"
},
{
"filename": "presets/context/GLM-4.json",
"type": "context"
},
{
"filename": "presets/reasoning/DeepSeek.json",
"type": "reasoning"

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": false,
"trim_sentences": false,
"single_line": true,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": false,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>New Roleplay:<|END_OF_TURN_TOKEN|>",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "***",
"chat_start": "***",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": false,
"trim_sentences": true,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nWrite an example narrative / conversation that is not part of the main story.",
"chat_start": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nStart the role-play between {{char}} and {{user}}.",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": false,
"trim_sentences": true,
"single_line": false,

View File

@@ -0,0 +1,10 @@
{
"story_string": "[gMASK]<sop>{{#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}}{{trim}}\n",
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,
"name": "GLM-4"
}

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "### Example:",
"chat_start": "### START ROLEPLAY:",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -1,9 +1,8 @@
{
"story_string": "{{system}}\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{char}}'s description:{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality:{{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{user}}'s persona: {{persona}}\n{{/if}}",
"example_separator": "Example of an interaction:",
"chat_start": "This is the history of the roleplay:",
"story_string": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\n{{system}}\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{char}}'s description:{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality:{{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{user}}'s persona: {{persona}}\n{{/if}}\n\n",
"example_separator": "Example of an interaction:\n",
"chat_start": "This is the history of the roleplay:\n",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,9 +3,8 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,
"name": "Pygmalion"
"name": "Metharme"
}

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "***",
"chat_start": "***",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "This is how {{char}} should talk",
"chat_start": "\nThen the roleplay chat between {{user}} and {{char}} begins.\n",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "",
"chat_start": "",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -3,7 +3,6 @@
"example_separator": "### New Roleplay:",
"chat_start": "### New Roleplay:",
"use_stop_strings": false,
"allow_jailbreak": false,
"always_force_name2": true,
"trim_sentences": false,
"single_line": false,

View File

@@ -6,7 +6,7 @@
"stop_sequence": "<|im_end|>",
"wrap": true,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -8,7 +8,7 @@
"stop_sequence": "<|END_OF_TURN_TOKEN|>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"skip_examples": false,
"output_suffix": "<|END_OF_TURN_TOKEN|>",

View File

@@ -1,22 +1,22 @@
{
"input_sequence": "<|user|>",
"output_sequence": "<|model|>",
"input_sequence": "<|user|>\n",
"output_sequence": "<|assistant|>\n",
"first_output_sequence": "",
"last_output_sequence": "",
"system_sequence": "",
"stop_sequence": "<|user|>",
"system_sequence_prefix": "<|system|>\n",
"system_sequence_suffix": "",
"stop_sequence": "",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "<|system|>",
"system_sequence_suffix": "",
"first_output_sequence": "",
"skip_examples": false,
"output_suffix": "",
"input_suffix": "",
"system_sequence": "",
"system_suffix": "",
"user_alignment_message": "",
"system_same_as_user": true,
"last_system_sequence": "",
"name": "Pygmalion"
"system_same_as_user": true,
"name": "GLM-4"
}

View File

@@ -6,7 +6,7 @@
"stop_sequence": "<end_of_turn>",
"wrap": true,
"macro": true,
"names_behavior": "none",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -1,7 +1,7 @@
{
"input_sequence": "### Instruction:",
"output_sequence": "### Response: (length = unlimited)",
"last_output_sequence": "",
"output_sequence": "### Response:",
"last_output_sequence": "### Response: (length = unlimited)",
"system_sequence": "",
"stop_sequence": "",
"wrap": true,
@@ -12,8 +12,8 @@
"system_sequence_suffix": "",
"first_output_sequence": "",
"skip_examples": false,
"output_suffix": "",
"input_suffix": "",
"output_suffix": "\n\n",
"input_suffix": "\n\n",
"system_suffix": "",
"user_alignment_message": "",
"system_same_as_user": true,

View File

@@ -6,7 +6,7 @@
"stop_sequence": "<|eot_id|>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -6,7 +6,7 @@
"stop_sequence": "<|eot|>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -6,7 +6,7 @@
"stop_sequence": "",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -6,7 +6,7 @@
"stop_sequence": "",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -6,7 +6,7 @@
"stop_sequence": "",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -6,7 +6,7 @@
"stop_sequence": "</s>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",

View File

@@ -8,7 +8,7 @@
"stop_sequence": "<|end|>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"skip_examples": false,
"output_suffix": "<|end|>\n",

View File

@@ -8,7 +8,7 @@
"stop_sequence": "<|end_of_text|>",
"wrap": false,
"macro": true,
"names_behavior": "always",
"names_behavior": "force",
"activation_regex": "",
"skip_examples": false,
"output_suffix": "<|end_of_text|>\n",

View File

@@ -1,4 +1,5 @@
{
"name": "Actor",
"content": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}."
"content": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Assistant - Expert",
"content": "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."
"content": "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.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Assistant - Simple",
"content": "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions."
"content": "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Blank",
"content": ""
"content": "",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Chain of Thought",
"content": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation."
"content": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation.",
"post_history": ""
}

View File

@@ -0,0 +1,5 @@
{
"name": "Lightning 1.1",
"content": "Take the role of {{char}} in a play that leaves a lasting impression on {{user}}. Write {{char}}'s next reply.\nNever skip or gloss over {{char}}s actions. Progress the scene at a naturally slow pace.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Neutral - Chat",
"content": "Write {{char}}'s next reply in a fictional chat between {{char}} and {{user}}."
"content": "Write {{char}}'s next reply in a fictional chat between {{char}} and {{user}}.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Roleplay - Detailed",
"content": "Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions. Keep the story immersive and engaging."
"content": "Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions. Keep the story immersive and engaging.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Roleplay - Immersive",
"content": "[System note: Write one reply only. Do not decide what {{user}} says or does. Write at least one paragraph, up to four. Be descriptive and immersive, providing vivid details about {{char}}'s actions, emotions, and the environment. Write with a high degree of complexity and burstiness. Do not repeat this message.]"
"content": "[System note: Write one reply only. Do not decide what {{user}} says or does. Write at least one paragraph, up to four. Be descriptive and immersive, providing vivid details about {{char}}'s actions, emotions, and the environment. Write with a high degree of complexity and burstiness. Do not repeat this message.]",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Roleplay - Simple",
"content": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}."
"content": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Text Adventure",
"content": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]"
"content": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Writer - Creative",
"content": "You are an intelligent, skilled, versatile writer.\n\nYour task is to write a role-play based on the information below."
"content": "You are an intelligent, skilled, versatile writer.\n\nYour task is to write a role-play based on the information below.",
"post_history": ""
}

View File

@@ -1,4 +1,5 @@
{
"name": "Writer - Realistic",
"content": "Continue writing this story and portray characters realistically."
"content": "Continue writing this story and portray characters realistically.",
"post_history": ""
}

6
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "sillytavern",
"version": "1.12.13",
"version": "1.12.14",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sillytavern",
"version": "1.12.13",
"version": "1.12.14",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
@@ -18,6 +18,7 @@
"@jimp/js-bmp": "^1.6.0",
"@jimp/js-gif": "^1.6.0",
"@jimp/js-tiff": "^1.6.0",
"@jimp/plugin-blit": "^1.6.0",
"@jimp/plugin-circle": "^1.6.0",
"@jimp/plugin-color": "^1.6.0",
"@jimp/plugin-contain": "^1.6.0",
@@ -28,6 +29,7 @@
"@jimp/plugin-flip": "^1.6.0",
"@jimp/plugin-mask": "^1.6.0",
"@jimp/plugin-quantize": "^1.6.0",
"@jimp/plugin-resize": "^1.6.0",
"@jimp/plugin-rotate": "^1.6.0",
"@jimp/plugin-threshold": "^1.6.0",
"@jimp/wasm-avif": "^1.6.0",

View File

@@ -8,6 +8,7 @@
"@jimp/js-bmp": "^1.6.0",
"@jimp/js-gif": "^1.6.0",
"@jimp/js-tiff": "^1.6.0",
"@jimp/plugin-blit": "^1.6.0",
"@jimp/plugin-circle": "^1.6.0",
"@jimp/plugin-color": "^1.6.0",
"@jimp/plugin-contain": "^1.6.0",
@@ -18,6 +19,7 @@
"@jimp/plugin-flip": "^1.6.0",
"@jimp/plugin-mask": "^1.6.0",
"@jimp/plugin-quantize": "^1.6.0",
"@jimp/plugin-resize": "^1.6.0",
"@jimp/plugin-rotate": "^1.6.0",
"@jimp/plugin-threshold": "^1.6.0",
"@jimp/wasm-avif": "^1.6.0",
@@ -109,7 +111,7 @@
"type": "git",
"url": "https://github.com/SillyTavern/SillyTavern.git"
},
"version": "1.12.13",
"version": "1.12.14",
"scripts": {
"start": "node server.js",
"debug": "node --inspect server.js",

View File

@@ -3,133 +3,17 @@
*/
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import process from 'node:process';
import yaml from 'yaml';
import _ from 'lodash';
import chalk from 'chalk';
import { createRequire } from 'node:module';
import { addMissingConfigValues } from './src/config-init.js';
/**
* Colorizes console output.
*/
const color = chalk;
const keyMigrationMap = [
{
oldKey: 'disableThumbnails',
newKey: 'thumbnails.enabled',
migrate: (value) => !value,
},
{
oldKey: 'thumbnailsQuality',
newKey: 'thumbnails.quality',
migrate: (value) => value,
},
{
oldKey: 'avatarThumbnailsPng',
newKey: 'thumbnails.format',
migrate: (value) => (value ? 'png' : 'jpg'),
},
{
oldKey: 'disableChatBackup',
newKey: 'backups.chat.enabled',
migrate: (value) => !value,
},
{
oldKey: 'numberOfBackups',
newKey: 'backups.common.numberOfBackups',
migrate: (value) => value,
},
{
oldKey: 'maxTotalChatBackups',
newKey: 'backups.chat.maxTotalBackups',
migrate: (value) => value,
},
{
oldKey: 'chatBackupThrottleInterval',
newKey: 'backups.chat.throttleInterval',
migrate: (value) => value,
},
{
oldKey: 'enableExtensions',
newKey: 'extensions.enabled',
migrate: (value) => value,
},
{
oldKey: 'enableExtensionsAutoUpdate',
newKey: 'extensions.autoUpdate',
migrate: (value) => value,
},
{
oldKey: 'extras.disableAutoDownload',
newKey: 'extensions.models.autoDownload',
migrate: (value) => !value,
},
{
oldKey: 'extras.classificationModel',
newKey: 'extensions.models.classification',
migrate: (value) => value,
},
{
oldKey: 'extras.captioningModel',
newKey: 'extensions.models.captioning',
migrate: (value) => value,
},
{
oldKey: 'extras.embeddingModel',
newKey: 'extensions.models.embedding',
migrate: (value) => value,
},
{
oldKey: 'extras.speechToTextModel',
newKey: 'extensions.models.speechToText',
migrate: (value) => value,
},
{
oldKey: 'extras.textToSpeechModel',
newKey: 'extensions.models.textToSpeech',
migrate: (value) => value,
},
{
oldKey: 'minLogLevel',
newKey: 'logging.minLogLevel',
migrate: (value) => value,
},
{
oldKey: 'cardsCacheCapacity',
newKey: 'performance.memoryCacheCapacity',
migrate: (value) => `${value}mb`,
},
{
oldKey: 'cookieSecret',
newKey: 'cookieSecret',
migrate: () => void 0,
remove: true,
},
];
/**
* Gets all keys from an object recursively.
* @param {object} obj Object to get all keys from
* @param {string} prefix Prefix to prepend to all keys
* @returns {string[]} Array of all keys in the object
*/
function getAllKeys(obj, prefix = '') {
if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) {
return [];
}
return _.flatMap(Object.keys(obj), key => {
const newPrefix = prefix ? `${prefix}.${key}` : key;
if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
return getAllKeys(obj[key], newPrefix);
} else {
return [newPrefix];
}
});
}
/**
* Converts the old config.conf file to the new config.yaml format.
*/
@@ -156,71 +40,6 @@ function convertConfig() {
}
}
/**
* Compares the current config.yaml with the default config.yaml and adds any missing values.
*/
function addMissingConfigValues() {
try {
const defaultConfig = yaml.parse(fs.readFileSync(path.join(process.cwd(), './default/config.yaml'), 'utf8'));
let config = yaml.parse(fs.readFileSync(path.join(process.cwd(), './config.yaml'), 'utf8'));
// Migrate old keys to new keys
const migratedKeys = [];
for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) {
if (_.has(config, oldKey)) {
if (remove) {
_.unset(config, oldKey);
migratedKeys.push({
oldKey,
newValue: void 0,
});
continue;
}
const oldValue = _.get(config, oldKey);
const newValue = migrate(oldValue);
_.set(config, newKey, newValue);
_.unset(config, oldKey);
migratedKeys.push({
oldKey,
newKey,
oldValue,
newValue,
});
}
}
// Get all keys from the original config
const originalKeys = getAllKeys(config);
// Use lodash's defaultsDeep function to recursively apply default properties
config = _.defaultsDeep(config, defaultConfig);
// Get all keys from the updated config
const updatedKeys = getAllKeys(config);
// Find the keys that were added
const addedKeys = _.difference(updatedKeys, originalKeys);
if (addedKeys.length === 0 && migratedKeys.length === 0) {
return;
}
if (addedKeys.length > 0) {
console.log('Adding missing config values to config.yaml:', addedKeys);
}
if (migratedKeys.length > 0) {
console.log('Migrating config values in config.yaml:', migratedKeys);
}
fs.writeFileSync('./config.yaml', yaml.stringify(config));
} catch (error) {
console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error);
}
}
/**
* Creates the default config files if they don't exist yet.
*/
@@ -283,58 +102,13 @@ function createDefaultFiles() {
}
}
/**
* Returns the MD5 hash of the given data.
* @param {Buffer} data Input data
* @returns {string} MD5 hash of the input data
*/
function getMd5Hash(data) {
return crypto
.createHash('md5')
.update(new Uint8Array(data))
.digest('hex');
}
/**
* Copies the WASM binaries from the sillytavern-transformers package to the dist folder.
*/
function copyWasmFiles() {
if (!fs.existsSync('./dist')) {
fs.mkdirSync('./dist');
}
const listDir = fs.readdirSync('./node_modules/sillytavern-transformers/dist');
for (const file of listDir) {
if (file.endsWith('.wasm')) {
const sourcePath = `./node_modules/sillytavern-transformers/dist/${file}`;
const targetPath = `./dist/${file}`;
// Don't copy if the file already exists and is the same checksum
if (fs.existsSync(targetPath)) {
const sourceChecksum = getMd5Hash(fs.readFileSync(sourcePath));
const targetChecksum = getMd5Hash(fs.readFileSync(targetPath));
if (sourceChecksum === targetChecksum) {
continue;
}
}
fs.copyFileSync(sourcePath, targetPath);
console.log(`${file} successfully copied to ./dist/${file}`);
}
}
}
try {
// 0. Convert config.conf to config.yaml
convertConfig();
// 1. Create default config files
createDefaultFiles();
// 2. Copy transformers WASM binaries from node_modules
copyWasmFiles();
// 3. Add missing config values
addMissingConfigValues();
// 2. Add missing config values
addMissingConfigValues(path.join(process.cwd(), './config.yaml'));
} catch (error) {
console.error(error);
}

View File

@@ -359,10 +359,15 @@
content: attr(external_piece_text);
display: block;
width: 100%;
font-weight: 600;
font-weight: 500;
text-align: center;
}
.completion_prompt_manager_popup_entry_form_control #completion_prompt_manager_popup_entry_form_prompt:disabled {
visibility: hidden;
}
#completion_prompt_manager_popup_entry_source_block {
display: flex;
justify-content: center;
}

View File

@@ -87,7 +87,7 @@
}
#rm_group_members:empty::before {
content: 'Group is empty';
content: attr(group_empty_text);
font-weight: bolder;
width: 100%;
@@ -115,7 +115,7 @@
}
#rm_group_add_members:empty::before {
content: 'No characters available';
content: attr(no_characters_text);
font-weight: bolder;
width: 100%;

View File

@@ -124,6 +124,10 @@
cursor: initial;
}
.world_entry .inline-drawer-header-pointer {
cursor: pointer;
}
.world_entry .killSwitch {
cursor: pointer;
}

11
public/global.d.ts vendored
View File

@@ -55,4 +55,15 @@ declare global {
* @param provider Translation provider
*/
async function translate(text: string, lang: string, provider: string = null): Promise<string>;
interface ConvertVideoArgs {
buffer: Uint8Array;
name: string;
}
/**
* Converts a video file to an animated WebP format using FFmpeg.
* @param args - The arguments for the conversion function.
*/
function convertVideoToAnimatedWebp(args: ConvertVideoArgs): Promise<Uint8Array>;
}

View File

@@ -1284,7 +1284,7 @@
<input class="neo-range-slider" type="range" id="min_p_textgenerationwebui" name="volume" min="0" max="1" step="0.001">
<input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="min_p_textgenerationwebui" id="min_p_counter_textgenerationwebui">
</div>
<div data-tg-type-mode="except" data-tg-type="generic" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<div data-tg-type-mode="except" data-tg-type="generic,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<small>
<span data-i18n="Top A">Top A</span>
<div class="fa-solid fa-circle-info opacity50p" title="Top A sets a threshold for token selection based on the square of the highest token probability.&#13;E.g if the Top-A value is 0.2 and the top token's probability is 50%, tokens with probabilities below 5% (0.2 * 0.5^2) are excluded.&#13;Set to 0 to disable." data-i18n="[title]Top_A_desc"></div>
@@ -1292,7 +1292,7 @@
<input class="neo-range-slider" type="range" id="top_a_textgenerationwebui" name="volume" min="0" max="1" step="0.01">
<input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="top_a_textgenerationwebui" id="top_a_counter_textgenerationwebui">
</div>
<div data-tg-type-mode="except" data-tg-type="generic" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<div data-tg-type-mode="except" data-tg-type="generic,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<small>
<span data-i18n="TFS">TFS</span>
<div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail_Free_Sampling_desc" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution,&#13;by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative.&#13;The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div>
@@ -1308,7 +1308,7 @@
<input class="neo-range-slider" type="range" id="epsilon_cutoff_textgenerationwebui" name="volume" min="0" max="9" step="0.01">
<input class="neo-range-input" type="number" min="0" max="9" step="0.01" data-for="epsilon_cutoff_textgenerationwebui" id="epsilon_cutoff_counter_textgenerationwebui">
</div>
<div data-tg-type="aphrodite,koboldcpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<div data-tg-type="aphrodite,koboldcpp,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<small>
<span data-i18n="Top nsigma">Top nsigma</span>
<div class="fa-solid fa-circle-info opacity50p" title="A sampling method that filters logits based on their statistical properties. It keeps tokens within n standard deviations of the maximum logit value, providing a simpler alternative to top-p/top-k sampling while maintaining sampling stability across different temperatures."></div>
@@ -1316,6 +1316,14 @@
<input class="neo-range-slider" type="range" id="nsigma_textgenerationwebui" name="volume" min="0" max="5" step="0.01">
<input class="neo-range-input" type="number" min="0" max="5" step="0.01" data-for="nsigma_textgenerationwebui" id="nsigma_counter_textgenerationwebui">
</div>
<div data-tg-type="llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<small>
<span data-i18n="Min Keep">Min Keep</span>
<div class="fa-solid fa-circle-info opacity50p" title="A sampling modifier that ensures that truncation samplers such as top-p, min-p, typical-p, and xtc return at least this many tokens. Set to 0 to disable."></div>
</small>
<input class="neo-range-slider" type="range" id="min_keep_textgenerationwebui" name="volume" min="0" max="50" step="1">
<input class="neo-range-input" type="number" min="0" max="50" step="1" data-for="min_keep_textgenerationwebui" id="min_keep_counter_textgenerationwebui">
</div>
<div data-tg-type="ooba,mancer,aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
<small>
<span data-i18n="Eta Cutoff">Eta Cutoff</span>
@@ -1398,7 +1406,7 @@
</div>
</div>
<div data-tg-type="koboldcpp, aphrodite, tabby, ooba, llamacpp" id="xtc_block" class="wide100p">
<div data-tg-type="koboldcpp, aphrodite, mancer, tabby, ooba, llamacpp" id="xtc_block" class="wide100p">
<h4 class="wide100p textAlignCenter">
<label data-i18n="Exclude Top Choices (XTC)">Exclude Top Choices (XTC)</label>
<a href="https://github.com/oobabooga/text-generation-webui/pull/6335" target="_blank">
@@ -1419,7 +1427,7 @@
</div>
</div>
<div data-tg-type="aphrodite, ooba, koboldcpp, tabby, llamacpp" id="dryBlock" class="wide100p">
<div data-tg-type="aphrodite, mancer, ooba, koboldcpp, tabby, llamacpp, dreamgen" id="dryBlock" class="wide100p">
<h4 class="wide100p textAlignCenter" title="DRY penalizes tokens that would extend the end of the input into a sequence that has previously occurred in the input. Set multiplier to 0 to disable." data-i18n="[title]DRY_Repetition_Penalty_desc">
<label data-i18n="DRY Repetition Penalty">DRY Repetition Penalty</label>
<a href="https://github.com/oobabooga/text-generation-webui/pull/5677" target="_blank">
@@ -1485,7 +1493,7 @@
</div>
</div>
</div>
<div data-tg-type="ooba,infermaticai,koboldcpp,llamacpp,mancer,ollama,tabby" id="mirostat_block_ooba" class="wide100p">
<div data-tg-type="ooba,infermaticai,koboldcpp,llamacpp,ollama,tabby" id="mirostat_block_ooba" class="wide100p">
<h4 class="wide100p textAlignCenter">
<label data-i18n="Mirostat (mode=1 is only for llama.cpp)">Mirostat</label>
<div class=" fa-solid fa-circle-info opacity50p " data-i18n="[title]Mirostat_desc" title="Mirostat is a thermostat for output perplexity.&#13;Mirostat matches the output perplexity to that of the input, thus avoiding the repetition trap&#13;(where, as the autoregressive inference produces text, the perplexity of the output tends toward zero)&#13;and the confusion trap (where the perplexity diverges).&#13;For details, see the paper Mirostat: A Neural Text Decoding Algorithm that Directly Controls Perplexity by Basu et al. (2020).&#13;Mode chooses the Mirostat version. 0=disable, 1=Mirostat 1.0 (llama.cpp only), 2=Mirostat 2.0."></div>
@@ -1574,7 +1582,7 @@
<div class="fa-solid fa-circle-info opacity50p " data-i18n="[title]Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative" title="Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative."></div>
</label>
</label>
<label data-tg-type="ooba, llamacpp, tabby, koboldcpp" class="checkbox_label flexGrow flexShrink" for="ban_eos_token_textgenerationwebui">
<label data-tg-type="ooba, llamacpp, tabby, koboldcpp, dreamgen" class="checkbox_label flexGrow flexShrink" for="ban_eos_token_textgenerationwebui">
<input type="checkbox" id="ban_eos_token_textgenerationwebui" />
<label>
<small data-i18n="Ban EOS Token">Ban EOS Token</small>
@@ -1769,11 +1777,12 @@
<div data-name="temperature" draggable="true"><span>Temperature</span><small></small></div>
<div data-name="top_k" draggable="true"><span>Top K</span><small></small></div>
<div data-name="top_p" draggable="true"><span>Top P</span><small></small></div>
<div data-name="typical_p" draggable="true"><span>Typical P</span><small></small></div>
<div data-name="tfs_z" draggable="true"><span>Tail Free Sampling</span><small></small></div>
<div data-name="typ_p" draggable="true"><span>Typical P</span><small></small></div>
<div data-name="min_p" draggable="true"><span>Min P</span><small></small></div>
<div data-name="xtc" draggable="true"><span>Exclude Top Choices</span><small></small></div>
<div data-name="dry" draggable="true"><span>DRY</span><small></small></div>
<div data-name="penalties" draggable="true"><span>Rep/Freq/Pres Penalties</span><small></small></div>
<div data-name="top_n_sigma" draggable="true"><span>Top N-Sigma</span><small></small></div>
</div>
<div id="llamacpp_samplers_default_order" class="menu_button menu_button_icon">
<span data-i18n="Load default order">Load default order</span>
@@ -1954,7 +1963,7 @@
</span>
</div>
</div>
<div class="range-block" data-source="makersuite,openrouter">
<div class="range-block" data-source="makersuite,openrouter,claude">
<label for="openai_enable_web_search" class="checkbox_label flexWrap widthFreeExpand">
<input id="openai_enable_web_search" type="checkbox" />
<span data-i18n="Enable web search">Enable web search</span>
@@ -2025,7 +2034,7 @@
<input id="use_makersuite_sysprompt" type="checkbox" />
<span>
<span data-i18n="Use system prompt">Use system prompt</span>
<i class="opacity50p fa-solid fa-circle-info" title="Gemini 1.5/2.0 Pro/Flash"></i>
<i class="opacity50p fa-solid fa-circle-info" title="Gemini 1.5+, LearnLM"></i>
</span>
</label>
<div class="toggle-description justifyLeft marginBot5">
@@ -2048,16 +2057,20 @@
</span>
</div>
</div>
<div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai">
<div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models.&#10;Currently supported values are low, medium, and high.&#10;Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models.">
<div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai,makersuite,openrouter">
<div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models.&#10;Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models.">
<label for="openai_reasoning_effort">
<span data-i18n="Reasoning Effort">Reasoning Effort</span>
<i data-source="claude" class="opacity50p fa-solid fa-circle-info" title="Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%), but minimum 1024 tokens."></i>
<i data-source="openai,custom,xai,openrouter" class="opacity50p fa-solid fa-circle-info" title="OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level." data-i18n="[title]OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level."></i>
<i data-source="claude,makersuite" class="opacity50p fa-solid fa-circle-info" title="Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent." data-i18n="[title]Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent."></i>
</label>
<select id="openai_reasoning_effort">
<option data-i18n="openai_reasoning_effort_auto" value="auto">Auto</option>
<option data-i18n="openai_reasoning_effort_minimum" value="min">Mininum</option>
<option data-i18n="openai_reasoning_effort_low" value="low">Low</option>
<option data-i18n="openai_reasoning_effort_medium" value="medium">Medium</option>
<option data-i18n="openai_reasoning_effort_high" value="high">High</option>
<option data-i18n="openai_reasoning_effort_maximum" value="max">Maximum</option>
</select>
</div>
</div>
@@ -2494,8 +2507,8 @@
<option value="search" data-i18n="Search" hidden>A-Z</option>
<option value="asc">A-Z</option>
<option value="desc">Z-A</option>
<option value="date_asc">Date Asc</option>
<option value="date_desc">Date Desc</option>
<option data-i18n="Date Asc" value="date_asc">Date Asc</option>
<option data-i18n="Date Desc" value="date_desc">Date Desc</option>
</select>
<select id="featherless_category_selection" class="text_pole">
<option value="" disabled selected data-i18n="category">category</option>
@@ -2505,7 +2518,7 @@
<option value="All" data-i18n="All">All</option>
</select>
<select id="featherless_class_selection" class="text_pole">
<option value="" selected data-i18n="class">All Classes</option>
<option value="" selected data-i18n="All Classes">All Classes</option>
</select>
<div id="featherless_model_pagination_container" class="flex1"></div>
<i id="featherless_model_grid_toggle" class="fa-solid fa-table-cells-large menu_button" data-i18n="[title]Toggle grid view" title="Toggle grid view"></i>
@@ -2618,8 +2631,8 @@
</div>
<div data-tg-type="ollama">
<div class="flex-container flexFlowColumn">
<a href="https://github.com/jmorganca/ollama" target="_blank">
jmorganca/ollama
<a href="https://github.com/ollama/ollama" target="_blank">
ollama/ollama
</a>
</div>
<div class="flex1">
@@ -2762,7 +2775,7 @@
<option value="xai">xAI (Grok)</option>
</optgroup>
</select>
<div class="inline-drawer wide100p" data-source="openai,claude,mistralai,makersuite,deepseek">
<div class="inline-drawer wide100p" data-source="openai,claude,mistralai,makersuite,deepseek,xai">
<div class="inline-drawer-toggle inline-drawer-header">
<b data-i18n="Reverse Proxy">Reverse Proxy</b>
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
@@ -2825,7 +2838,7 @@
</div>
</div>
</div>
<div id="ReverseProxyWarningMessage" data-source="openai,claude,mistralai,makersuite,deepseek">
<div id="ReverseProxyWarningMessage" data-source="openai,claude,mistralai,makersuite,deepseek,xai">
<div class="reverse_proxy_warning">
<b>
<div data-i18n="Using a proxy that you're not running yourself is a risk to your data privacy.">
@@ -2884,10 +2897,7 @@
</optgroup>
<optgroup label="GPT-4o mini">
<option value="gpt-4o-mini">gpt-4o-mini</option>
<option value="gpt-4o-2024-11-20">gpt-4o-2024-11-20</option>
<option value="gpt-4o-2024-08-06">gpt-4o-2024-08-06</option>
<option value="gpt-4o-2024-05-13">gpt-4o-2024-05-13</option>
<option value="chatgpt-4o-latest">chatgpt-4o-latest</option>
<option value="gpt-4o-mini-2024-07-18">gpt-4o-mini-2024-07-18</option>
</optgroup>
<optgroup label="GPT-4.1">
<option value="gpt-4.1">gpt-4.1</option>
@@ -2897,7 +2907,7 @@
<option value="gpt-4.1-nano">gpt-4.1-nano</option>
<option value="gpt-4.1-nano-2025-04-14">gpt-4.1-nano-2025-04-14</option>
</optgroup>
<optgroup label="o1 and o1-mini">
<optgroup label="o1">
<option value="o1">o1</option>
<option value="o1-2024-12-17">o1-2024-12-17</option>
<option value="o1-mini">o1-mini</option>
@@ -2906,9 +2916,15 @@
<option value="o1-preview-2024-09-12">o1-preview-2024-09-12</option>
</optgroup>
<optgroup label="o3">
<option value="o3">o3</option>
<option value="o3-2025-04-16">o3-2025-04-16</option>
<option value="o3-mini">o3-mini</option>
<option value="o3-mini-2025-01-31">o3-mini-2025-01-31</option>
</optgroup>
<optgroup label="o4">
<option value="o4-mini">o4-mini</option>
<option value="o4-mini-2025-04-16">o4-mini-2025-04-16</option>
</optgroup>
<optgroup label="GPT-4.5">
<option value="gpt-4.5-preview">gpt-4.5-preview</option>
<option value="gpt-4.5-preview-2025-02-27">gpt-4.5-preview-2025-02-27</option>
@@ -3139,48 +3155,50 @@
<div>
<h4 data-i18n="Google Model">Google Model</h4>
<select id="model_google_select">
<optgroup label="Primary">
<option value="gemini-2.0-flash">Gemini 2.0 Flash</option>
<option value="gemini-1.5-pro">Gemini 1.5 Pro</option>
<option value="gemini-1.5-flash">Gemini 1.5 Flash</option>
<option value="gemini-1.0-pro">Gemini 1.0 Pro (Deprecated)</option>
<option value="gemini-pro">Gemini Pro (1.0) (Deprecated)</option>
<option value="gemini-ultra">Gemini Ultra (1.0)</option>
<option value="gemini-1.0-ultra-latest">Gemini 1.0 Ultra</option>
<optgroup label="Gemini 2.5">
<option value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option>
<option value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option>
<option value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option>
<option value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option>
</optgroup>
<optgroup label="Gemini 2.0">
<option value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option>
<option value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option>
<option value="gemini-exp-1206">gemini-exp-1206 → 2.5-pro-exp-03-25</option>
<option value="gemini-2.0-flash-001">gemini-2.0-flash-001</option>
<option value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option>
<option value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option>
<option value="gemini-2.0-flash">gemini-2.0-flash</option>
<option value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21 → 2.5-flash-preview-04-17</option>
<option value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219 → 2.5-flash-preview-04-17</option>
<option value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp → 2.5-flash-preview-04-17</option>
<option value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option>
<option value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option>
<option value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option>
</optgroup>
<optgroup label="Gemini 1.5">
<option value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option>
<option value="gemini-1.5-pro-002">gemini-1.5-pro-002</option>
<option value="gemini-1.5-pro-001">gemini-1.5-pro-001</option>
<option value="gemini-1.5-pro">gemini-1.5-pro</option>
<option value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option>
<option value="gemini-1.5-flash-002">gemini-1.5-flash-002</option>
<option value="gemini-1.5-flash-001">gemini-1.5-flash-001</option>
<option value="gemini-1.5-flash">gemini-1.5-flash</option>
<option value="gemini-1.5-flash-8b-001">gemini-1.5-flash-8b-001</option>
<option value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option>
<option value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option>
<option value="gemini-1.5-flash-8b">gemini-1.5-flash-8b</option>
</optgroup>
<optgroup label="Gemma">
<option value="gemma-3-27b-it">Gemma 3 27B</option>
<option value="gemma-3-27b-it">gemma-3-27b-it</option>
<option value="gemma-3-12b-it">gemma-3-12b-it</option>
<option value="gemma-3-4b-it">gemma-3-4b-it</option>
<option value="gemma-3-1b-it">gemma-3-1b-it</option>
</optgroup>
<optgroup label="Subversions">
<option value="gemini-2.5-pro-preview-03-25">Gemini 2.5 Pro Preview 2025-03-25</option>
<option value="gemini-2.5-pro-exp-03-25">Gemini 2.5 Pro Experimental 2025-03-25</option>
<option value="gemini-2.0-pro-exp">Gemini 2.0 Pro Experimental</option>
<option value="gemini-2.0-pro-exp-02-05">Gemini 2.0 Pro Experimental 2025-02-05</option>
<option value="gemini-2.0-flash-lite-preview">Gemini 2.0 Flash-Lite Preview</option>
<option value="gemini-2.0-flash-lite-preview-02-05">Gemini 2.0 Flash-Lite Preview 2025-02-05</option>
<option value="gemini-2.0-flash-001">Gemini 2.0 Flash [001]</option>
<option value="gemini-2.0-flash-thinking-exp">Gemini 2.0 Flash Thinking Experimental</option>
<option value="gemini-2.0-flash-thinking-exp-01-21">Gemini 2.0 Flash Thinking Experimental 2025-01-21</option>
<option value="gemini-2.0-flash-thinking-exp-1219">Gemini 2.0 Flash Thinking Experimental 2024-12-19</option>
<option value="gemini-2.0-flash-exp">Gemini 2.0 Flash Experimental</option>
<option value="gemini-2.0-flash-exp-image-generation">Gemini 2.0 Flash (Image Generation) Experimental</option>
<option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option>
<option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option>
<option value="gemini-exp-1206">Gemini Experimental 2024-12-06</option>
<option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experimental 2024-08-01</option>
<option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experimental 2024-08-27</option>
<option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option>
<option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option>
<option value="gemini-1.5-pro-002">Gemini 1.5 Pro [002]</option>
<option value="gemini-1.5-flash-8b">Gemini 1.5 Flash 8B</option>
<option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experimental 2024-08-27</option>
<option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experimental 2024-08-27</option>
<option value="gemini-1.5-flash-8b-exp-0924">Gemini 1.5 Flash 8B Experimental 2024-09-24</option>
<option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option>
<option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option>
<option value="gemini-1.5-flash-002">Gemini 1.5 Flash [002]</option>
<option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest] (Deprecated)</option>
<option value="gemini-1.0-pro-001">Gemini 1.0 Pro (Tuning) [001] (Deprecated)</option>
<optgroup label="LearnLM">
<option value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option>
<option value="learnlm-1.5-pro-experimental">learnlm-1.5-pro-experimental</option>
</optgroup>
</select>
</div>
@@ -3228,6 +3246,7 @@
<option value="mistral-small-2501">mistral-small-2501</option>
<option value="mistral-small-2503">mistral-small-2503</option>
<option value="mistral-medium-2312">mistral-medium-2312</option>
<option value="mistral-medium-2505">mistral-medium-2505</option>
<option value="mistral-large-2402">mistral-large-2402</option>
<option value="mistral-large-2407">mistral-large-2407</option>
<option value="mistral-large-2411">mistral-large-2411</option>
@@ -3495,7 +3514,7 @@
<div class="drawer-toggle">
<div class="drawer-icon fa-solid fa-font fa-fw closedIcon" title="AI Response Formatting" data-i18n="[title]AI Response Formatting"></div>
</div>
<div id="AdvancedFormatting" class="drawer-content">
<div id="AdvancedFormatting" class="drawer-content closedDrawer">
<div class="flex-container alignItemsBaseline">
<h3 class="margin0 flex1 flex-container alignItemsBaseline">
<span data-i18n="Advanced Formatting">
@@ -3614,11 +3633,6 @@
<small data-i18n="Names as Stop Strings">Names as Stop Strings</small>
</label>
</div>
<label class="checkbox_label" title="Includes Post-History Instructions at the end of the prompt, if defined in the character card AND ''Prefer Char. Instructions'' is enabled.&#10;THIS IS NOT RECOMMENDED FOR TEXT COMPLETION MODELS, CAN LEAD TO BAD OUTPUT." data-i18n="[title]context_allow_post_history_instructions">
<input id="context_allow_jailbreak" type="checkbox" />
<small data-i18n="Allow Post-History Instructions">Allow Post-History Instructions</small>
</label>
</div>
</div>
</div>
@@ -3820,9 +3834,7 @@
</label>
</div>
</h4>
<div id="SystemPromptBlock">
<div id="SystemPromptBlock" class="marginBot10">
<div class="flex-container" title="Select your current System Prompt" data-i18n="[title]Select your current System Prompt">
<select id="sysprompt_select" data-preset-manager-for="sysprompt" class="flex1 text_pole"></select>
<div class="flex-container margin0 justifyCenter gap3px">
@@ -3844,10 +3856,14 @@
</label>
<textarea id="sysprompt_content" class="text_pole textarea_compact autoSetHeight"></textarea>
</div>
</div>
<div>
&nbsp;
<div>
<label for="sysprompt_post_history" class="flex-container">
<small data-i18n="Post-History Instructions">Post-History Instructions</small>
<i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="sysprompt_post_history" title="Expand the editor" data-i18n="[title]Expand the editor"></i>
</label>
<textarea id="sysprompt_post_history" class="text_pole textarea_compact autoSetHeight"></textarea>
</div>
</div>
<div>
@@ -4492,10 +4508,11 @@
<small data-i18n="Tags as Folders">Tags as Folders</small>
<i title="Recent change: Tags must be marked as folders in the Tag Management menu to appear as such. Click here to bring it up." data-i18n="[title]Tags_as_Folders_desc" class="tags_view right_menu_button fa-solid fa-circle-exclamation"></i>
</label>
<label for="click_to_edit" class="checkbox_label" title="Click the message text in the chat log to edit it." data-i18n="[title]Click the message text in the chat log to edit it.">
<input id="click_to_edit" type="checkbox" />
<small data-i18n="Click to Edit">Click to Edit</small>
</label>
</div>
</div>
</div>
<div name="UserSettingsSecondColumn" id="UI-Customization" class="flex-container flexFlowColumn wide100p flexNoGap flex1">
@@ -4773,6 +4790,10 @@
<input id="show_group_chat_queue" type="checkbox" />
<small data-i18n="Show group chat queue">Show group chat queue</small>
</label>
<label class="checkbox_label" for="pin_styles" title="Always render style tags from greetings, even if the message is unloaded due to lazy loading." data-i18n="[title]Always render style tags from greetings, even if the message is unloaded due to lazy loading.">
<input id="pin_styles" type="checkbox" />
<small data-i18n="Pin greeting message styles">Pin greeting message styles</small>
</label>
<div class="inline-drawer wide100p flexFlowColumn">
<div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria">
<b><span data-i18n="Auto-swipe">Auto-swipe</span></b>
@@ -4959,7 +4980,7 @@
<div id="bg_menu_content" class="bg_list">
<form id="form_bg_download" class="bg_example no-border no-shadow" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<label class="input-file">
<input type="file" id="add_bg_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp">
<input type="file" id="add_bg_button" name="avatar" accept="image/*, video/*">
<div class="bg_example no-border no-shadow add_bg_but" style="background-image: url('/img/addbg3.png');"></div>
</label>
</form>
@@ -5526,7 +5547,7 @@
<div class="inline-drawer-content">
<div id="currentGroupMembers" name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1">
<div id="rm_group_members_pagination" class="rm_group_members_pagination group_pagination"></div>
<div id="rm_group_members" class="rm_group_members overflowYAuto flex-container"></div>
<div id="rm_group_members" class="rm_group_members overflowYAuto flex-container" group_empty_text="Group is empty." data-i18n="[group_empty_text]Group is empty."></div>
</div>
</div>
</div>
@@ -5544,7 +5565,7 @@
<div class="tags rm_tag_filter"></div>
</div>
<div id="rm_group_add_members_pagination" class="group_pagination"></div>
<div id="rm_group_add_members" class="overflowYAuto flex-container"></div>
<div id="rm_group_add_members" class="overflowYAuto flex-container" no_characters_text="No characters available" data-i18n="[no_characters_text]No characters available"></div>
</div>
</div>
</div>
@@ -5964,7 +5985,7 @@
<div class="tag_view_color_picker" data-value="color"></div>
<div class="tag_view_color_picker" data-value="color2"></div>
<div class="tag_view_name" contenteditable="true"></div>
<div class="tag_view_counter"><span class="tag_view_counter_value"></span>&nbsp;entries</div>
<div class="tag_view_counter"><span class="tag_view_counter_value"></span>&nbsp;<span data-i18n="tag_entries">entries</span></div>
<div title="Delete tag" class="tag_delete fa-solid fa-trash-can right_menu_button" data-i18n="[title]Delete tag"></div>
</div>
</div>
@@ -6284,6 +6305,54 @@
</label>
</div>
</div>
<div class="inline-drawer wide100p flexFlowColumn">
<div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable">
<strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong>
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
</div>
<div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px">
<small class="flex-container flex1 flexFlowColumn">
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchCharacterDescription" />
<span data-i18n="Character Description">
Character Description
</span>
</label>
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchCharacterPersonality" />
<span data-i18n="Character Personality">
Character Personality
</span>
</label>
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchScenario" />
<span data-i18n="Scenario">
Scenario
</span>
</label>
</small>
<small class="flex-container flex1 flexFlowColumn">
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchPersonaDescription" />
<span data-i18n="Persona Description">
Persona Description
</span>
</label>
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchCharacterDepthPrompt" />
<span data-i18n="Character's Note">
Character's Note
</span>
</label>
<label class="checkbox flex-container alignItemsCenter flexNoGap">
<input type="checkbox" name="matchCreatorNotes" />
<span data-i18n="Creator's Notes">
Creator's Notes
</span>
</label>
</small>
</div>
</div>
</div>
</div>
</form>
@@ -6408,6 +6477,11 @@
</label>
</div>
</div>
<div id="completion_prompt_manager_popup_entry_source_block">
<b data-i18n="Source:">Source:</b>
<span>&nbsp;</span>
<span id="completion_prompt_manager_popup_entry_source"></span>
</div>
<textarea id="completion_prompt_manager_popup_entry_form_prompt" class="text_pole" name="prompt">
</textarea>
</div>
@@ -6651,7 +6725,7 @@
</div>
<div class="flex-container wide100pLess70px character_select_container height100p alignitemscenter">
<div class="wide100p character_name_block">
<span class="ch_name">Go back</span>
<span class="ch_name" data-i18n="Go back">Go back</span>
</div>
</div>
</div>

View File

@@ -411,7 +411,6 @@
"Chat Start": "بداية الدردشة",
"Add Chat Start and Example Separator to a list of stopping strings.": "أضف بداية الدردشة وفاصل الأمثلة إلى قائمة سلاسل التوقف.",
"Use as Stop Strings": "استخدم كسلاسل التوقف",
"context_allow_jailbreak": "يتضمن كسر الحماية في نهاية المطالبة، إذا تم تحديده في بطاقة الشخصية و''Prefer Char. تم تمكين الهروب من السجن.\nلا يُنصح بهذا بالنسبة لنماذج إكمال النص، فقد يؤدي إلى نتائج سيئة.",
"Allow Jailbreak": "السماح بالجيلبريك",
"Context Order": "ترتيب السياق",
"Summary": "ملخص",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Chat-Start",
"Add Chat Start and Example Separator to a list of stopping strings.": "Fügen Sie einer Liste von Stoppzeichenfolgen „Chat-Start“ und „Beispieltrennzeichen“ hinzu.",
"Use as Stop Strings": "Verwende als Stoppzeichenfolgen",
"context_allow_jailbreak": "Schließt Jailbreak am Ende der Eingabeaufforderung ein, wenn dies in der Charakterkarte definiert ist UND „Charakter-Jailbreak bevorzugen“ aktiviert ist.\nDIES WIRD FÜR TEXTVERVOLLSTÄNDIGUNGSMODELLE NICHT EMPFOHLEN, KANN ZU SCHLECHTEN AUSGABEN FÜHREN.",
"Allow Jailbreak": "Jailbreak zulassen",
"Context Order": "Kontextreihenfolge",
"Summary": "Zusammenfassung",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Inicio de chat",
"Add Chat Start and Example Separator to a list of stopping strings.": "Agregue Inicio de chat y Separador de ejemplo a una lista de cadenas de parada.",
"Use as Stop Strings": "Usar como Cadenas de Parada",
"context_allow_jailbreak": "Incluye Jailbreak al final del mensaje, si está definido en la tarjeta de personaje Y está habilitado \"Prefer Char. Jailbreak\".\nESTO NO SE RECOMIENDA PARA MODELOS DE COMPLETO DE TEXTO, PUEDE PRODUCIR UN RESULTADO INCORRECTO.",
"Allow Jailbreak": "Permitir Jailbreak",
"Context Order": "Orden de contexto",
"Summary": "Resumen",

View File

@@ -1448,7 +1448,6 @@
"Add Character and User names to a list of stopping strings.": "Ajouter les noms de personnages et d'utilisateurs à une liste de chaînes d'arrêt.",
"Names as Stop Strings": "Noms comme chaînes d'arrêt",
"context_allow_post_history_instructions": "Inclut les instructions post-historiques à la fin du prompt, si elles sont définies dans la fiche de personnage ET si l'option 'Préférer les instructions de personnage' est activée.\nN'EST PAS RECOMMANDÉ POUR LES MODÈLES DE COMPLÉTION DE TEXTE, CAR IL PEUT ENTRAÎNER DE MAUVAIS RÉSULTATS.",
"Allow Post-History Instructions": "Autoriser les instructions post-histoire",
"Instruct Template": "Modèle d'instruction",
"instruct_derived": "Dériver des métadonnées du modèle, si possible.",
"instruct_enabled": "Activer le mode d'instruction",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Chat Start",
"Add Chat Start and Example Separator to a list of stopping strings.": "Bættu Chat Start og Example Separator við lista yfir stöðvunarstrengi.",
"Use as Stop Strings": "Nota sem Stoppa Strengir",
"context_allow_jailbreak": "Inniheldur Jailbreak í lok hvetjunnar, ef það er skilgreint á stafkortinu OG ''Velst Char. Jailbreak'' er virkt.\nÞETTA ER EKKI MÆLT FYRIR TEXTAÚRSLUNARGERÐ, GETUR leitt til lélegrar úttaks.",
"Allow Jailbreak": "Leyfa jailbreak",
"Context Order": "Samhengisröð",
"Summary": "Samantekt",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Inizio chat",
"Add Chat Start and Example Separator to a list of stopping strings.": "Aggiungi Inizio chat e Separatore di esempio a un elenco di stringhe di arresto.",
"Use as Stop Strings": "Usa come stringhe di arresto",
"context_allow_jailbreak": "Include il jailbreak alla fine del prompt, se definito nella carta personaggio E ''Preferisci Char. Il jailbreak'' è abilitato.\nQUESTO NON È CONSIGLIATO PER I MODELLI DI COMPLETAMENTO DEL TESTO, PUÒ PORTARE A UN RISULTATO CATTIVO.",
"Allow Jailbreak": "Consenti jailbreak",
"Context Order": "Ordine del contesto",
"Summary": "Riepilogo",

View File

@@ -411,7 +411,6 @@
"Chat Start": "チャット開始",
"Add Chat Start and Example Separator to a list of stopping strings.": "停止文字列のリストにチャット開始と例の区切り文字を追加します。",
"Use as Stop Strings": "ストップ文字列として使用",
"context_allow_jailbreak": "文字カードで定義されていて、「文字 Jailbreak を優先」が有効になっている場合は、プロンプトの最後に Jailbreak が含まれます。\nこれはテキスト補完モデルには推奨されません。出力が悪くなる可能性があります。",
"Allow Jailbreak": "脱獄を許可する",
"Context Order": "コンテキスト順序",
"Summary": "まとめ",

View File

@@ -421,7 +421,6 @@
"Chat Start": "채팅 시작",
"Add Chat Start and Example Separator to a list of stopping strings.": "중지 문자열 목록에 채팅 시작 및 예제 구분 기호를 추가합니다.",
"Use as Stop Strings": "중지 문자열로 사용",
"context_allow_jailbreak": "캐릭터 카드에 정의되어 있고 ''Prefer Char. Jailbreak''가 활성화되어 있는 경우 프롬프트 끝에 Jailbreak를 포함합니다.\n이는 텍스트 완성 모델에 권장되지 않으며, 나쁜 출력으로 이어질 수 있습니다.",
"Allow Jailbreak": "탈옥 허용",
"Context Order": "컨텍스트 순서",
"Summary": "요약",
@@ -1520,7 +1519,6 @@
"Always": "항상 추가함",
"Separators as Stop Strings": "구분 기호를 정지 문자열로 사용하기",
"Names as Stop Strings": "캐릭터의 이름들을 정지 문자열로 사용하기",
"Allow Post-History Instructions": "Post-History 지침 허용",
"Image Captioning": "이미지 캡셔닝",
"Automatically caption images": "자동으로 이미지에 대한 설명 문장으로 나타내기",
"Edit captions before saving": "저장하기 전에 이미지에 대한 설명 문장 편집하기",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Chatstart",
"Add Chat Start and Example Separator to a list of stopping strings.": "Voeg Chat Start en Voorbeeldscheidingsteken toe aan een lijst met stoptekenreeksen.",
"Use as Stop Strings": "Gebruik als stopreeksen",
"context_allow_jailbreak": "Inclusief jailbreak aan het einde van de prompt, indien gedefinieerd in de karakterkaart EN ''Prefer Char. Jailbreak'' is ingeschakeld.\nDIT WORDT NIET AANBEVOLEN VOOR MODELLEN VOOR HET INVOEREN VAN TEKST. KAN TOT SLECHTE UITVOER LEIDEN.",
"Allow Jailbreak": "Jailbreak toestaan",
"Context Order": "Contextvolgorde",
"Summary": "Samenvatting",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Início do Chat",
"Add Chat Start and Example Separator to a list of stopping strings.": "Adicione o início do bate-papo e o separador de exemplo a uma lista de strings de parada.",
"Use as Stop Strings": "Usar como Strings de Parada",
"context_allow_jailbreak": "Inclui Jailbreak no final do prompt, se definido no cartão de personagem E ''Prefer Char. Jailbreak'' está habilitado.\nISTO NÃO É RECOMENDADO PARA MODELOS DE COMPLEMENTAÇÃO DE TEXTO, PODE LEVAR A UMA SAÍDA RUIM.",
"Allow Jailbreak": "Permitir jailbreak",
"Context Order": "Ordem de Contexto",
"Summary": "Resumo",

View File

@@ -52,7 +52,7 @@
"Presence Penalty": "Штраф за присутствие",
"Top A": "Top А",
"Tail Free Sampling": "Tail Free Sampling",
"Rep. Pen. Slope": "Rep. Pen. Slope",
"Rep. Pen. Slope": "Рост штрафа за повтор к концу промпта",
"Top K": "Top K",
"Top P": "Top P",
"Do Sample": "Включить сэмплинг",
@@ -162,9 +162,9 @@
"Story String": "Строка истории",
"Example Separator": "Разделитель примеров сообщений",
"Chat Start": "Начало чата",
"Activation Regex": "Regex для активации",
"Activation Regex": "Рег. выражение для активации",
"Instruct Mode": "Режим Instruct",
"Wrap Sequences with Newline": "Отделять строки символом новой строки",
"Wrap Sequences with Newline": "Каждая строка из шаблона на новой строке",
"Include Names": "Добавлять имена",
"Force for Groups and Personas": "Также для групп и персон",
"System Prompt": "Системный промпт",
@@ -299,7 +299,7 @@
"AI Horde": "AI Horde",
"NovelAI": "NovelAI",
"OpenAI API key": "Ключ для API OpenAI",
"Trim spaces": "Обрезать пробелы",
"Trim spaces": "Обрезать пробелы в начале и конце",
"Trim Incomplete Sentences": "Удалять неоконченные предложения",
"Include Newline": "Добавлять новую строку",
"Non-markdown strings": "Строки без разметки",
@@ -510,7 +510,7 @@
"New preset": "Новый пресет",
"Delete preset": "Удалить пресет",
"API Connections": "Соединения с API",
"Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "Может помочь с плохими ответами ставя в очередь только подтвержденных работников. Может замедлить время ответа.",
"Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "Может помочь при плохих ответах, делая запросы только к доверенным рабочим машинам. Может замедлить время ответа.",
"Clear your API key": "Стереть ключ от API",
"Refresh models": "Обновить модели",
"Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "Получите свой OpenRouter API токен используя OAuth. У вас будет открыта вкладка openrouter.ai",
@@ -551,7 +551,7 @@
"Token counts may be inaccurate and provided just for reference.": "Счетчик токенов может быть неточным, используйте как ориентир",
"Click to select a new avatar for this character": "Нажмите чтобы выбрать новый аватар для этого персонажа",
"Example: [{{user}} is a 28-year-old Romanian cat girl.]": "Пример:\n [{{user}} is a 28-year-old Romanian cat girl.]",
"Toggle grid view": "Переключить вид сетки",
"Toggle grid view": "Сменить вид сетки",
"Add to Favorites": "Добавить в Избранное",
"Advanced Definition": "Расширенное описание",
"Character Lore": "Лор персонажа",
@@ -624,7 +624,7 @@
"UI Theme": "Тема UI",
"This message is invisible for the AI": "Это сообщение невидимо для ИИ",
"Sampler Priority": "Приоритет сэмплеров",
"Ooba only. Determines the order of samplers.": "Только oobabooga. Определяет порядок сэмплеров.",
"Ooba only. Determines the order of samplers.": "Только для oobabooga. Определяет порядок сэмплеров.",
"Load default order": "Загрузить стандартный порядок",
"Max Tokens Second": "Макс. кол-во токенов в секунду",
"CFG": "CFG",
@@ -695,7 +695,7 @@
"Medium": "Средний",
"Aggressive": "Агрессивный",
"Very aggressive": "Очень агрессивный",
"Eta_Cutoff_desc": "Eta cutoff - основной параметр специальной техники сэмплинга под названием Eta Sampling.&#13;В единицах 1e-4; разумное значение - 3.&#13;Установите в 0, чтобы отключить.&#13;См. статью Truncation Sampling as Language Model Desmoothing от Хьюитт и др. (2022) для получения подробной информации.",
"Eta_Cutoff_desc": "Eta cutoff - основной параметр специальной техники сэмплинга под названием Eta Sampling.\nВ единицах 1e-4; разумное значение - 3.\nУстановите в 0, чтобы отключить.\nСм. статью Truncation Sampling as Language Model Desmoothing от Хьюитт и др. (2022) для получения подробной информации.",
"Learn how to contribute your idle GPU cycles to the Horde": "Узнайте, как использовать время простоя вашего GPU для помощи Horde",
"Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.": "Используйте соответствующий токенизатор для моделей Google через их API. Медленная обработка подсказок, но предлагает намного более точный подсчет токенов.",
"Load koboldcpp order": "Загрузить порядок из koboldcpp",
@@ -964,7 +964,7 @@
"char_import_3": "Персонаж с JanitorAI (прямая ссылка или UUID)",
"char_import_4": "Персонаж с Pygmalion.chat (прямая ссылка или UUID)",
"char_import_5": "Персонаж с AICharacterCards.com (прямая ссылка или ID)",
"char_import_6": "Прямая ссылка на PNG-файл (чтобы узнать список разрешённых хостов, загляните в",
"char_import_6": "Прямая ссылка на PNG-файл (список разрешённых хостов находится в",
"char_import_7": ")",
"Grammar String": "Грамматика",
"GBNF or EBNF, depends on the backend in use. If you're using this you should know which.": "GBNF или EBNF, зависит от бэкенда. Если вы это используете, то, скорее всего, сами знаете, какой именно.",
@@ -1016,7 +1016,7 @@
"prompt_manager_relative": "Относительная",
"prompt_manager_depth": "Глубина",
"Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Глубина вставки. 0 = после последнего сообщения, 1 = перед последним сообщением, и т.д.",
"The prompt to be sent.": "Отправляемый ИИ промпт.",
"The prompt to be sent.": "Текст промпта.",
"prompt_manager_forbid_overrides": "Запретить перезапись",
"This prompt cannot be overridden by character cards, even if overrides are preferred.": "Карточка персонажа не сможет перезаписать этот промпт, даже если настройки отдают приоритет именно ей.",
"image_inlining_hint_1": "Отправлять картинки как часть промпта, если позволяет модель (такой функционал поддерживают GPT-4V, Claude 3 или Llava 13B). Чтобы добавить в чат изображение, используйте на нужном сообщении действие",
@@ -1232,7 +1232,7 @@
"Top P & Min P": "Top P & Min P",
"llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.": "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.",
"Helps the model to associate messages with characters.": "Помогает модели связывать сообщения с персонажами.",
"character_names_default": "Except for groups and past personas. Otherwise, make sure you provide names in the prompt.",
"character_names_default": "Добавлять префиксы для групповых чатов и предыдущих персон. В остальных случаях указывайте имена в промпте иными способами.",
"Completion": "Completion Object",
"character_names_completion": "Только латинские буквы, цифры и знак подчёркивания. Работает не для всех бэкендов, в частности для Claude, MistralAI, Google.",
"Use AI21 Tokenizer": "Использовать токенайзер AI21",
@@ -1257,7 +1257,6 @@
"Peek a password": "Посмотреть пароль",
"Clear your cookie": "Clear your cookie",
"Add Chat Start and Example Separator to a list of stopping strings.": "Использовать Начало чата и Разделитель примеров сообщений в качестве стоп-строк.",
"context_allow_jailbreak": "Если в карточке есть джейлбрейк И ПРИ ЭТОМ включена опция \"Приоритет джейлбрейку из карточки персонажа\", то этот джейлбрейк добавляется в конец промпта.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.",
"Context Order": "Context Order",
"Summary": "Summary",
"Example Dialogues": "Примеры диалогов",
@@ -1278,7 +1277,7 @@
"Will be inserted as a last prompt line when using system/neutral generation.": "Will be inserted as a last prompt line when using system/neutral generation.",
"If a stop sequence is generated, everything past it will be removed from the output (inclusive).": "Если ИИ генерирует стоп-строку, то всё после неё будет вырезано из ответа (включая и саму стоп-строку).",
"Will be inserted at the start of the chat history if it doesn't start with a User message.": "Вставляется в начале истории чата, если она начинается не с сообщения пользователя.",
"Global World Info/Lorebook activation settings": "Настройки активации глобального лорбука / Информации о мире",
"Global World Info/Lorebook activation settings": "Глобальные настройки активации лорбука / Информации о мире",
"Click to expand": "Щёлкните, чтобы развернуть",
"Insertion Strategy": "Как инжектить",
"Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "Only the entries with the most number of key matches will be selected for Inclusion Group filtering",
@@ -1647,10 +1646,9 @@
"mui_reset": "Сброс",
"Quick 'Impersonate' button": "Быстрое перевоплощение",
"Show a button in the input area to ask the AI to impersonate your character for a single message": "Показать в поле ввода кнопку, по нажатии на которую ИИ сгенерирует одно сообщение от лица вашего персонажа.",
"Separators as Stop Strings": "Разделители как стоп-строки",
"Names as Stop Strings": "Имена как стоп-строки",
"Separators as Stop Strings": "Разделители в качестве стоп-строк",
"Names as Stop Strings": "Имена в качестве стоп-строк",
"Add Character and User names to a list of stopping strings.": "Добавлять имена персонажа и пользователя в список стоп-строк.",
"Allow Post-History Instructions": "Разрешить инструкции после истории",
"context_allow_post_history_instructions": "Добавлять в конец промпта инструкции после истории. Работает только при наличии таких инструкций в карточке И при включенной опции ''Приоритет инструкциям из карточек''.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.",
"First User Prefix": "Первый префикс пользователя",
"Inserted before the first User's message.": "Вставляется перед первым сообщением пользователя.",
@@ -1916,8 +1914,8 @@
"Cannot restore GUI preset": "Пресет для Gui восстановить нельзя",
"Default preset cannot be restored": "Невозможно восстановить пресет по умолчанию",
"Default template cannot be restored": "Невозможно восстановить шаблон по умолчанию",
"Resetting a <b>default preset</b> will restore the default settings": "Сброс <b>стандартного пресета</b> восстановит настройки по умолчанию.",
"Resetting a <b>default template</b> will restore the default settings.": "Сброс <b>стандартного шаблона</b> восстановит настройки по умолчанию.",
"Resetting a <b>default preset</b> will restore the default settings.": "Сброс <b>комплектного пресета</b> восстановит настройки по умолчанию.",
"Resetting a <b>default template</b> will restore the default settings.": "Сброс <b>комплектного шаблона</b> восстановит настройки по умолчанию.",
"Are you sure?": "Вы уверены?",
"Default preset restored": "Стандартный пресет восстановлен",
"Default template restored": "Стандартный шаблон восстановлен",
@@ -2048,11 +2046,11 @@
"prompt_post_processing_merge": "Объединять идущие подряд сообщения с одной ролью",
"prompt_post_processing_semi": "Semi-strict (чередовать роли)",
"prompt_post_processing_strict": "Strict (чередовать роли, сначала пользователь)",
"Select Horde models": "Выбрать модель из Horde",
"Select Horde models": "Выберите модель из Horde",
"Model ID (optional)": "Идентификатор модели (необязательно)",
"Derive context size from backend": "Использовать бэкенд для определения размера контекста",
"Rename current preset": "Переименовать пресет",
"No Worlds active. Click here to select.": "Нет активных миров. Нажмите, чтобы выбрать.",
"No Worlds active. Click here to select.": "Активных миров нет, ЛКМ для выбора.",
"Title/Memo": "Название",
"Strategy": "Статус",
"Position": "Позиция",
@@ -2171,7 +2169,7 @@
"instruct_derived": "Считывать из метаданных модели (по возможности)",
"Confirm token parsing with": "Чтобы убедиться в правильности выделения токенов, используйте",
"Reasoning Effort": "Рассуждения",
"Constrains effort on reasoning for reasoning models.": "Регулирует объём внутренних рассуждений модели (reasoning), для моделей которые поддерживают эту возможность.\nНа данный момент поддерживаются три значения: Подробные, Обычные, Поверхностные.\nПри менее подробном рассуждении ответ получается быстрее, а также экономятся токены, уходящие на рассуждения.",
"Constrains effort on reasoning for reasoning models.": "Регулирует объём внутренних рассуждений модели (reasoning), для моделей, которые поддерживают эту возможность.\nПри менее подробном рассуждении ответ получается быстрее, а также экономятся токены, уходящие на рассуждения.",
"openai_reasoning_effort_low": "Поверхностные",
"openai_reasoning_effort_medium": "Обычные",
"openai_reasoning_effort_high": "Подробные",
@@ -2276,8 +2274,8 @@
"Persona Name Not Set": "У персоны отсутствует имя",
"You must bind a name to this persona before you can set a lorebook.": "Перед привязкой лорбука персоне необходимо присвоить имя.",
"Default Persona Removed": "Персона по умолчанию снята",
"Persona is locked to the current character": "Персона закреплена за этим персонажем",
"Persona is locked to the current chat": "Персона закреплена за этим чатом",
"Persona is locked to the current character": "Персона закреплена за текущим персонажем",
"Persona is locked to the current chat": "Персона закреплена за текущим чатом",
"characters": "перс.",
"character": "персонаж",
"in this group": "в группе",
@@ -2338,5 +2336,88 @@
"Reasoning already exists.": "Рассуждения уже присутствуют.",
"Edit Message": "Редактирование",
"Status check bypassed": "Проверка статуса отключена",
"Valid": "Работает"
"Valid": "Работает",
"Use Group Scoring": "Использовать Group Scoring",
"Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "До групповых фильтров будут допущены только записи с наибольшим кол-вом совпадений",
"Can be used to automatically activate Quick Replies": "Используется для автоматической активации быстрых ответов (Quick Replies)",
"( None )": "(Отсутствует)",
"Tie this entry to specific characters or characters with specific tags": "Привязать запись к опред. персонажам или персонажам с заданными тегами",
"Move Entry to Another Lorebook": "Переместить запись в другой лорбук",
"There are no other lorebooks to move to.": "Некуда перемещать: не найдено других лорбуков.",
"Select Target Lorebook": "Выберите куда переместить",
"Move '${0}' to:": "Переместить '${0}' в:",
"Please select a target lorebook.": "Выберите лорбук, в который будет перемещена запись.",
"Scan depth cannot be negative": "Глубина сканирования не может быть отрицательной",
"Scan depth cannot exceed ${0}": "Глубина сканирования не может превышать ${0}",
"Select your current Reasoning Template": "Выберите текущий Шаблон рассуждений",
"Delete template": "Удалить шаблон",
"Reasoning Template": "Шаблон рассуждений",
"openai_reasoning_effort_auto": "Авто",
"openai_reasoning_effort_minimum": "Минимальные",
"openai_reasoning_effort_maximum": "Максимальные",
"OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level.": "OpenAI принимает следующее: low (Поверхностные), medium (Обычные), high (Подробные). Minimum (Минимальные) - то же самое, что low. Maximum (Максимальные) - то же самое, что high. При выборе Auto (Авто) значение не отсылается вообще.",
"Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent.": "Резервирует часть ответа для рассуждений (Поверхностные: 10% ответа, Обычные: 25%, Подробные: 50%). Остальные значения зависят от конкретной модели.",
"xAI Model": "Модель xAI",
"xAI API Key": "Ключ от API xAI",
"HuggingFace Token": "Токен HuggingFace",
"Endpoint URL": "Адрес эндпоинта",
"Example: https://****.endpoints.huggingface.cloud": "Пример: https://****.endpoints.huggingface.cloud",
"Featherless Model Selection": "Выбор модели из Featherless",
"category": "категория",
"Top": "Топовые",
"All Classes": "Все классы",
"Date Asc": "Дата, возрастание",
"Date Desc": "Дата, убывание",
"Background Image": "Фоновое изображение",
"Delete the background?": "Удалить фон?",
"Tags_as_Folders_desc": "Чтобы тег отображался как папка, его нужно отметить таковым в меню управления тегами. Нажмите сюда, чтобы открыть его.",
"tag_entries": "раз исп.",
"Multiple personas are connected to this character.\nSelect a persona to use for this chat.": "К этому персонажу привязано несколько персон.\nВыберите персону, которую хотите использовать в этом чате.",
"Select Persona": "Выберите персону",
"Completion Object": "Как часть Completion Object",
"Move ${0} to:": "Переместить '${0}' в:",
"Chat Scenario Override": "Перезапись сценария чата",
"Unique to this chat.": "Действует только в рамках текущего чата.",
"All group members will use the following scenario text instead of what is specified in their character cards.": "Все участники группы будут использовать этот сценарий вместо того, который указан в карточке.",
"Checkpoints inherit the scenario override from their parent, and can be changed individually after that.": "Чекпоинты наследуют сценарий родителя, после отделения его можно менять.",
"Delete Tag": "Удалить тег",
"Do you want to delete the tag": "Вы точно хотите удалить тег",
"If you want to merge all references to this tag into another tag, select it below:": "Если хотите заменить ссылки на этот тег на какой-то другой, то выберите из списка:",
"Open Folder (Show all characters even if not selected)": "Открытая папка (показать всех персонажей, включая невыбранных)",
"Closed Folder (Hide all characters unless selected)": "Закрытая папка (скрыть всех персонажей, кроме выбранных)",
"No Folder": "Не папка",
"Show only favorites": "Показать только избранных персонажей",
"Show only groups": "Показать только группы",
"Show only folders": "Показать только папки",
"Manage tags": "Панель управления тегами",
"Show Tag List": "Показать список тегов",
"Clear all filters": "Сбросить все фильтры",
"There are no items to display.": "Отображать абсолютно нечего.",
"Characters and groups hidden by filters or closed folders": "Персонажи и группы скрыты настройками фильтров либо закрытыми папками",
"Otterly empty": "Всё что можно, всё выдрано",
"Here be dragons": "Список настолько очистился, что в него вернулись драконы",
"Kiwibunga": "Настолько пусто, что киви прилетела посидеть",
"Pump-a-Rum": "Пу-пу-пу",
"Croak it": "Только кваканье лягушек и стрёкот сверчков",
"${0} character hidden.": "Персонажей скрыто: ${0}.",
"${0} characters hidden.": "Персонажей скрыто: ${0}.",
"/ page": "/ стр.",
"Context Length": "Размер контекста",
"Added On": "Добавлена",
"Class": "Класс",
"Bulk_edit_characters": "Массовое редактирование персонажей\n\nЛКМ, чтобы выделить либо отменить выделение персонажа\nShift+ЛКМ, чтобы массово выделить либо отменить выделение персонажей\nПКМ, чтобы выбрать действие",
"Bulk select all characters": "Выбрать всех персонажей",
"Duplicate": "Клонировать",
"Next page": "След. страница",
"Previous page": "Пред. страница",
"Group: ${0}": "Группа: ${0}",
"You deleted a character/chat and arrived back here for safety reasons! Pick another character!": "Вы удалили персонажа или чат, и мы из соображений безопасности перенесли вас на эту страницу! Выберите другого персонажа!",
"Group is empty.": "Группа пуста.",
"No characters available": "Персонажей нет",
"Choose what to export": "Выберите, что экспортировать",
"Text Completion Preset": "Пресет для режима Text Completion",
"Update enabled": "Обновить включенные",
"Could not connect to API": "Не удалось подключиться к API",
"Connected to API": "Соединение с API установлено",
"Go back": "Назад"
}

View File

@@ -411,7 +411,6 @@
"Chat Start": "Початок чату",
"Add Chat Start and Example Separator to a list of stopping strings.": "Додайте початок чату та роздільник прикладів до списку рядків зупинки.",
"Use as Stop Strings": "Використовувати як рядки зупинки",
"context_allow_jailbreak": "Включає втечу з в’язниці в кінці підказки, якщо визначено в картці символів ТА «Переважати символ. Втечу з в'язниці'' увімкнено.\nЦЕ НЕ РЕКОМЕНДУЄТЬСЯ ДЛЯ МОДЕЛЕЙ ЗАВЕРШЕННЯ ТЕКСТУ, МОЖЕ ПРИЗВЕСТИ ДО ПОГАНОГО РЕЗУЛЬТАТУ.",
"Allow Jailbreak": "Дозволити втечу з в'язниці",
"Context Order": "Порядок контексту",
"Summary": "Резюме",

View File

@@ -411,7 +411,6 @@
"Chat Start": "Bắt đầu Chat",
"Add Chat Start and Example Separator to a list of stopping strings.": "Thêm Bắt đầu trò chuyện và Dấu phân cách ví dụ vào danh sách các chuỗi dừng.",
"Use as Stop Strings": "Sử dụng như chuỗi dừng",
"context_allow_jailbreak": "Bao gồm Bẻ khóa ở cuối Prompt, nếu được xác định trong thẻ ký tự VÀ ''Thích Char. Bẻ khóa'' được bật.\nĐIỀU NÀY KHÔNG ĐƯỢC KHUYẾN NGHỊ CHO CÁC MÔ HÌNH HOÀN THÀNH VĂN BẢN, CÓ THỂ DẪN ĐẾN ĐẦU RA XẤU.",
"Allow Jailbreak": "Cho phép bẻ khóa",
"Context Order": "Thứ tự bối cảnh",
"Summary": "Bản tóm tắt",

View File

@@ -504,7 +504,6 @@
"Add Character and User names to a list of stopping strings.": "将角色和用户名添加到停止字符串列表中。",
"Names as Stop Strings": "名称作为终止字符串",
"context_allow_post_history_instructions": "如果在角色卡中定义并且启用了“首选角色卡说明”,则在提示末尾包含后历史说明。\n不建议在文本补全模型中使用此功能否则会导致输出错误。",
"Allow Post-History Instructions": "允许后历史说明",
"Instruct Template": "指导模板",
"instruct_derived": "如果可能,从模型元数据中获取",
"instruct_bind_to_context": "如果启用,上下文模板将根据所选的指导模板名称或偏好自动选择。",
@@ -1358,7 +1357,7 @@
"Image Captioning": "图像描述",
"Source": "来源",
"Local": "本地",
"Multimodal (OpenAI / Anthropic / llama / Google)": "多模OpenAI / Anthropic / llama / Google",
"Multimodal (OpenAI / Anthropic / llama / Google)": "多模OpenAI / Anthropic / llama / Google",
"Extras": "更多",
"Horde": "Horde",
"API": "API",
@@ -1588,8 +1587,8 @@
"sd_function_tool_txt": "Use function tool",
"sd_interactive_mode": "发送消息时自动生成图像,例如“给我发一张猫的照片”。",
"sd_interactive_mode_txt": "交互模式",
"sd_multimodal_captioning": "使用多模字幕根据用户和角色的头像生成提示词。",
"sd_multimodal_captioning_txt": "使用多模字幕来描绘肖像",
"sd_multimodal_captioning": "使用多模字幕根据用户和角色的头像生成提示词。",
"sd_multimodal_captioning_txt": "使用多模字幕来描绘肖像",
"sd_free_extend": "使用当前选择的 LLM 自动扩展自由模式主题提示(不是肖像或背景)。",
"sd_free_extend_txt": "延长自由模式提示",
"sd_free_extend_small": "(交互/命令)",
@@ -2109,5 +2108,25 @@
"Title/Memo": "标题(备忘)",
"Strategy": "触发策略",
"Position": "插入位置",
"Trigger %": "触发概率%"
"Trigger %": "触发概率%",
"Generate Caption": "生成图片描述",
"(DEPRECATED)": "(已弃用)",
"[Currently loaded]": "[当前加载]",
"Change Persona Image": "更改角色图片",
"Delete Persona": "删除角色",
"Duplicate Persona": "复制角色",
"Enter a name for this persona:": "输入角色名",
"Enable web search": "启用联网搜索",
"Current Persona": "当前角色",
"Global Settings": "全局设置",
"Select a model": "选择模型",
"Thinking...": "思考中",
"Valid": "有效",
"Rename Persona": "重命名角色",
"Sort By: Name (Z-A)": "排序: 名称Z-A",
"Sort By: Name (A-Z)": "排序: 名称A-Z",
"Sort By: Date (Oldest First)": "排序: 日期(从最远到最新)",
"Sort By: Date (Newest First)": "排序: 日期(从最新到最远)",
"Set the reasoning block of a message. Returns the reasoning block content.": "设置消息的推理块。返回推理块内容。",
"Select providers. No selection = all providers.": "选择服务商。未选择 = 所有服务商。"
}

View File

@@ -399,7 +399,7 @@
"Applies additional processing to the prompt before sending it to the API.": "這個選項會在將提示詞送往 API 之前,對它進行額外的處理。",
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "透過傳送簡短的測試訊息來驗證您的 API 連線。請注意,您將因此獲得榮譽!",
"Test Message": "測試訊息",
"Auto-connect to Last Server": "自動連至上次使用的伺服器",
"Auto-connect to Last Server": "自動連至上次使用的伺服器",
"Missing key": "❌ 鑰匙遺失",
"Key saved": "✔️ 金鑰已儲存",
"View hidden API keys": "檢視隱藏的 API 金鑰",
@@ -412,7 +412,6 @@
"Chat Start": "聊天開始符號",
"Add Chat Start and Example Separator to a list of stopping strings.": "將聊天開始和範例分隔符號加入終止字串中。",
"Use as Stop Strings": "用作停止字串",
"context_allow_jailbreak": "如果在角色卡中定義了越獄,且啟用了「角色卡越獄優先」,則會在提示詞的結尾加入越獄內容。\n這不建議用於文字完成模型因為可能導致不良的輸出結果。",
"Allow Jailbreak": "允許越獄",
"Context Order": "上下文順序",
"Summary": "摘要",
@@ -771,7 +770,7 @@
"Name": "名稱",
"Enter your name": "輸入您的名字",
"Click to set a new User Name": "設定新的使用者名稱",
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "定目前所選的使用者角色至本次聊天。再次點選則可移除定。",
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "定目前所選的使用者角色至本次聊天。再次點選移除定。",
"Click to set user name for all messages": "設定所有訊息的使用者名稱",
"Persona Description": "使用者角色描述",
"Example: [{{user}} is a 28-year-old Romanian cat girl.]": "範例:[{{user}} 是一個 28 歲的羅馬尼亞貓娘。]",
@@ -963,8 +962,8 @@
"Order": "順序",
"Trigger %:": "觸發%:",
"Probability": "機率",
"Duplicate world info entry": "複製世界資訊物件",
"Delete world info entry": "刪除世界資訊物件",
"Duplicate world info entry": "複製世界資訊條目",
"Delete world info entry": "刪除世界資訊條目",
"Comma separated (required)": "逗號分隔(必填)",
"Primary Keywords": "主要關鍵字",
"Keywords or Regexes": "關鍵字或正規表示式",
@@ -1049,7 +1048,7 @@
"welcome_message_part_4": "在聊天輸入框內輸入",
"welcome_message_part_5": "來顯示巨集或命令列表。",
"welcome_message_part_6": "加入",
"Discord server": "不和諧伺服器",
"Discord server": "Discord 伺服器",
"welcome_message_part_7": "取得公告和資訊。",
"SillyTavern is aimed at advanced users.": "SillyTavern 專為進階使用者設計",
"If you're new to this, enable the simplified UI mode below.": "如果您是新手,請啟用下方的簡易 UI 模式",
@@ -1247,7 +1246,7 @@
"ext_regex_replace_string_placeholder": "使用 {{match}} 來包含來自尋找正規表示式的匹配文字或 $1、$2 等捕獲組。",
"Trim Out": "修剪掉",
"ext_regex_trim_placeholder": "在取代之前,全域修剪正規表示式匹配中的任何不需要的部分。每個元素用輸入鍵分隔。",
"ext_regex_affects": "影響物件",
"ext_regex_affects": "影響條目",
"ext_regex_user_input": "使用者輸入",
"ext_regex_ai_output": "AI 輸出",
"Slash Commands": "斜線命令",
@@ -1555,7 +1554,6 @@
"All": "全部",
"Allow fallback models": "允許回退模型",
"Allow fallback providers": "允許回退供應商",
"Allow Post-History Instructions": "允許聊天歷史後指示",
"Allow reverse proxy": "允許反向代理",
"Alternate Greeting #": "備選問候語 #",
"alternate_greetings_hint_1": "點選",
@@ -2270,8 +2268,8 @@
"(Leave empty to auto-generate)": "(留空將自動命名)",
"The currently existing checkpoint will be unlinked and replaced with the new checkpoint, but can still be found in the Chat Management.": "此檢查點將取消連結並替換為新的檢查點,但仍可在「管理聊天檔案」中找到。",
"Enter the Git URL of the extension to install": "輸入欲安裝的擴充功能 Git URL",
"Disclaimer:": "免責宣告",
"Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.": "請注意,使用外部擴充功能可能會導致意想不到的副作用並存在安全風險。匯入前,請務必確保您信任其來源。我們對於第三方擴充功能所引起的任何損害概不負責。",
"Disclaimer:": "免責聲明",
"Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.": "請注意,使用外部擴充功能可能會導致意想不到的副作用並存在安全風險。匯入前,請務必確保您信任其來源。我們對於第三方擴充功能所引起的任何損害概不負責。",
"Prompt Itemization": "提示詞項目化",
"API/Model": "API模型",
"Preset": "預設設定檔",
@@ -2321,11 +2319,11 @@
"Only Show Last Message in Chat (Requires Prome to be enabled).": "僅顯示聊天中的最後一條訊息(需啟用 Prome。",
"Emulates the character card of a character to be a sprite. (Requires Prome to be enabled).": "將角色的角色卡圖片模擬為角色立繪(需啟用 Prome。",
"Shakes the character sprite when the character is speaking (Only works if Streaming is enabled in Preset Settings).": "當角色說話時,震動角色的立繪(僅在預設設定檔中啟用「串流」時有效)。",
"Focuses the current speaking character in chat. (Requires Prome to be enabled).": "聚焦聊天中目前正在說話的角色(啟用 Prome。",
"Focuses the current speaking character in chat. (Requires Prome to be enabled).": "聚焦聊天中目前正在說話的角色(啟用 Prome。",
"Darkens non-speaking (unfocused) characters. (Requires Prome to be enabled).": "使未說話(未聚焦)的角色變暗(需啟用 Prome。",
"Auto-hides characters from the screen that haven't been in the conversation for a while up to X characters. (Requires Prome to be enabled).": "自動隱藏未參與會話一段時間的角色,最多 X 個角色(需啟用 Prome。",
"Enables the ability to use a user sprite for your persona.": "啟用後,將為使用者的角色使用角色立繪功能。",
"Applies the world tint to character sprites (Requires Prome to be enabled. This will override your character tint settings).": "將世界色調應用於角色立繪(需啟用 Prome這將覆蓋角色色調設定)。",
"Applies the world tint to character sprites (Requires Prome to be enabled. This will override your character tint settings).": "將世界色調應用於角色立繪(需啟用 Prome這將覆蓋角色色調設定。",
"Tints the world background.": "為世界背景新增色調。",
"Tints the character sprites.": "為角色立繪新增色調(需啟用 Prome。",
"Auto-Hide Sprites": "自動隱藏立繪",
@@ -2608,7 +2606,7 @@
"Revert all settings to default (not the default profile, just the default that comes with the extension). Your other profiles won't be affected.": "將所有設定恢復為預設值(並非恢復至「預設設定檔」,而是擴充功能隨附的原始預設值)。其他設定檔將不受影響。",
"Limit the number of messages to send in regular prompts to this number (-1 for no limit). Message memories will still be sent.": "限制常規提示中傳送的訊息數量至此數值(-1 表示無限制)。訊息記憶仍將一併傳送。",
"Whether memory is enabled by default for new chats.": "是否在新對話中預設啟用記憶。",
"Summarize Chat": "摘要對話",
"Summarize Chat": "聊天摘要",
"Choose settings for the chat summarization. All message inclusion/exclusion settings from the main config profile are used, in addition to the following options.": "選擇聊天摘要的設定。摘要時將使用主要設定檔中的所有訊息包含/排除規則,並可額外設定以下選項。",
"Currently preparing to summarize:": "目前正在準備摘要:",
"Summarize messages with no existing summary": "摘要尚無摘要的訊息",
@@ -2619,9 +2617,130 @@
"Type the folder name of the theme you want to apply.": "輸入您想套用的主題資料夾名稱。",
"Place your theme data in a folder.": "請將主題資料存於該資料夾內。",
"Unsure where to start? Type ": "不確定如何開始?輸入:",
" to apply the default Google Messages theme or click ": " 即可使用預設主題 Google Messages或點",
" to apply the default Google Messages theme or click ": " 即可使用預設主題 Google Messages或點",
"here": "這裡",
" to learn how to create your own theme.": " 以學習如何創建個人化主題。",
" to learn how to create your own theme.": " 以了解如何創建個人化主題。",
"Guinevere (UI Theme Extension)": "Guinevere進階自定義 UI 主題)",
"and Guinaifen.": "和 Guinaifen桂乃芬呈獻。"
"and Guinaifen.": "和 Guinaifen桂乃芬呈獻。",
"(Requires Prome to be enabled)": "(需啟用 Prome",
"[ None ]": "[無]",
"Group is empty.": "群組為空。",
"No characters available": "無可用角色",
"Adds a shadow to the character sprite.": "為角色立繪新增陰影。",
"Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent.": "分配部分回應長度用於推理功能10%、中25%、高50%)。其他選項依模型而異。",
"Attach a file or image to a current chat.": "附加檔案或圖片至目前的聊天。",
"Change Persona Image": "變更使用者角色頭像",
"Click to lock your selected persona to the current character. Click again to remove the lock.": "點選以將所選使用者角色鎖定目前聊天的角色。再次點選以解除鎖定。",
"Click to select this as default persona for the new chats. Click again to remove it.": "點選以將此設為新聊天的預設使用者角色,再次點選可取消設定。",
"Connected Personas": "已連結的使用者角色",
"Create a new prompt": "新增新提示詞",
"Delete a prompt": "刪除提示詞",
"Delete Persona": "刪除使用者角色",
"Duplicate Persona": "複製使用者角色",
"Expand and zoom": "展開並縮放",
"Move Entry to Another Lorebook": "將條目移動到其他知識書",
"Persona is locked to the current character": "使用者角色已鎖定至目前角色",
"Persona is locked to the current chat": "使用者角色已鎖定至目前聊天",
"Rename a prompt": "重新命名提示詞",
"Rename Persona": "重新命名使用者角色",
"Select your current Reasoning Template": "選擇你目前使用的推理範本",
"Toggles sprite scaling for character sprites.": "切換角色立繪的縮放比例",
"When multiple personas are connected to a character, a popup will appear to select which one to use.": "當多個使用者角色連接至一個角色時,將顯示選擇彈窗。",
"When using LLM or WebLLM classifier, only show and use expressions that have sprites assigned to them.": "使用 LLM 或 WebLLM 分類器時,僅顯示並使用已指派的表情立繪。",
"Whenever a persona is selected, it will be locked and automatically selected when the chat is opened.": "若已選擇使用者角色,將在開啟聊天時自動進行鎖定。",
"Additional Matching Sources": "額外匹配來源",
"All Classes": "所有類別",
"Allow multiple persona connections per character": "允許每個角色連接多個使用者角色",
"Allows the model to return image attachments.": "允許模型返回圖片附件。",
"Auto-Hide Sprite Settings": "自動隱藏立繪設定",
"Auto-lock a chosen persona to the chat": "自動鎖定使用者角色至聊天中",
"Character": "角色",
"Character Personality": "角色個性",
"Character Tint/Share World Tint With Characters requires Prome to be enabled.": "角色著色/與角色共享世界著色功能需啟用 Prome。",
"Chat": "聊天",
"Click_space": "點選",
"Connections": "連接",
"Context": "上下文",
"Current Persona": "目前使用者角色",
"Date Asc": "日期升序",
"Date Desc": "日期降序",
"Enable Sprite Scale": "啟用立繪縮放",
"Enable web search": "啟用網路搜尋",
"Filter expressions for available sprites": "篩選可用的立繪表情",
"Focus Settings": "焦點設定",
"General Sprite Settings": "通用立繪設定",
"Global Settings": "全域設定",
"Go back": "返回",
"Hide Sheld": "隱藏聊天欄位(#Sheld",
"in this group": "在此群組中",
"Letterbox Configuration (Requires Prome to be enabled)": "信箱設定(需啟用 Prome",
"openai_reasoning_effort_auto": "自動",
"openai_reasoning_effort_maximum": "最大",
"openai_reasoning_effort_minimum": "最小",
"openrouter_web_search_fee": "需付費。每次提示詞將額外收取 0.02 美元費用。",
"Pooled order": "合併順序",
"Request inline images": "請求內嵌圖片",
"Request inline images_desc_2": "與以下功能不相容:函數調用、網路搜尋、系統提示詞。",
"Response": "回應",
"Secondary Embedding endpoint URL": "次要嵌入端點 URL",
"Set the size scale of the character sprites.": "設定角色立繪的大小比例。",
"Sprite Scale": "立繪縮放",
"Sprite Shadow Settings": "立繪陰影設定",
"tag_entries": "條目",
"Use search capabilities provided by the backend.": "使用後端提供的搜尋功能。",
"Use secondary URL": "使用次要 URL",
"User Sprite Settings": "[測試版] 使用者立繪設定",
"xAI API Key": "xAI API 密鑰",
"xAI Model": "xAI 模型",
"關閉": "關閉",
"Reset custom sampler selection": "重設自定取樣器選擇",
"Here you can toggle the display of individual samplers. (WIP)": "可在此切換各取樣器的顯示狀態(開發中)",
"Tie this entry to specific characters or characters with specific tags": "將此項綁定至特定角色或標籤",
"There are no other lorebooks to move to.": "暫無其他知識書可供移動。",
"Select Target Lorebook": "選擇目標知識書",
"Move '${0}' to:": "將「${0}」移動至:",
"Please select a target lorebook.": "請選擇目標知識書。",
"Scan depth cannot be negative": "掃描深度不能為負值",
"Scan depth cannot exceed ${0}": "掃描深度不能超過 ${0}",
"Reasoning Template": "推理範本",
"OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level.": "OpenAI 支援程度低、中、高。Minimum 與 Maximum 分別等同於低與高。選擇 Auto自動不會傳送努力等級。",
"Branch or tag name (optional)": "分支/標籤名稱(可留空)",
"Update enabled": "僅更新啟用項目",
"Sort: Loading Order": "排序:載入順序",
"Sort: Display Name": "排序:顯示名稱",
"Multiple personas are connected to this character.\nSelect a persona to use for this chat.": "此角色已綁定多個使用者角色,請選擇用於本次對話的角色。",
"Select Persona": "選擇使用者角色",
"Move ${0} to:": "將 ${0} 移至:",
"Delete Tag": "刪除標籤",
"Do you want to delete the tag": "確定要刪除此標籤嗎?",
"If you want to merge all references to this tag into another tag, select it below:": "若想將所有引用合併至其他標籤,請於下方選擇目標標籤:",
"Open Folder (Show all characters even if not selected)": "開啟資料夾(顯示所有角色,即使未被選取)",
"Closed Folder (Hide all characters unless selected)": "關閉資料夾(僅顯示選取的角色)",
"No Folder": "無資料夾",
"Show only favorites": "僅顯示最愛角色",
"Show only groups": "僅顯示群組",
"Show only folders": "僅顯示資料夾",
"Manage tags": "標籤管理",
"Show Tag List": "顯示標籤列表",
"Clear all filters": "清除所有篩選器",
"There are no items to display.": "暫無可顯示的項目。",
"Characters and groups hidden by filters or closed folders": "部分角色與群組因篩選或關閉資料夾而未顯示",
"Otterly empty": "萬獺俱寂",
"Here be dragons": "此處有龍",
"Kiwibunga": "這是鴿子嗎?",
"Pump-a-Rum": "啪,沒了。",
"Croak it": "PLAY 蝦咪 GAME",
"${0} character hidden.": "隱藏了 ${0} 名角色。",
"${0} characters hidden.": "隱藏了 ${0} 名角色。",
"/ page": "/頁",
"Context Length": "上下文長度",
"Added On": "新增日期",
"Class": "分類",
"Next page": "下一頁",
"Previous page": "上一頁",
"Group: ${0}": "群組:${0}",
"You deleted a character/chat and arrived back here for safety reasons! Pick another character!": "角色或對話已被刪除。系統為安全考量導回此頁,請重新選擇角色。",
"Could not connect to API": "無法連線至 API",
"Connected to API": "已成功連線至 API",
"help_macros_charDepthPrompt": "角色的 @ 深度註記"
}

View File

@@ -50,6 +50,7 @@ import {
importWorldInfo,
wi_anchor_position,
world_info_include_names,
initWorldInfo,
} from './scripts/world-info.js';
import {
@@ -96,6 +97,7 @@ import {
forceCharacterEditorTokenize,
applyPowerUserSettings,
generatedTextFiltered,
applyStylePins,
} from './scripts/power-user.js';
import {
@@ -142,6 +144,7 @@ import {
getHordeModels,
adjustHordeGenerationParams,
MIN_LENGTH,
initHorde,
} from './scripts/horde.js';
import {
@@ -174,6 +177,9 @@ import {
saveBase64AsFile,
uuidv4,
equalsIgnoreCaseAndAccents,
localizePagination,
renderPaginationDropdown,
paginationDropdownChangeHandler,
} from './scripts/utils.js';
import { debounce_timeout, IGNORE_SYMBOL } from './scripts/constants.js';
@@ -992,6 +998,8 @@ async function firstLoadInit() {
initBackgrounds();
initAuthorsNote();
await initPersonas();
initWorldInfo();
initHorde();
initRossMods();
initStats();
initCfg();
@@ -1002,6 +1010,8 @@ async function firstLoadInit() {
initBulkEdit();
initReasoning();
await initScrapers();
initCustomSelectedSamplers();
addDebugFunctions();
doDailyExtensionUpdatesCheck();
await hideLoader();
await fixViewport();
@@ -1421,30 +1431,26 @@ function getBackBlock() {
return template;
}
function getEmptyBlock() {
async function getEmptyBlock() {
const icons = ['fa-dragon', 'fa-otter', 'fa-kiwi-bird', 'fa-crow', 'fa-frog'];
const texts = ['Here be dragons', 'Otterly empty', 'Kiwibunga', 'Pump-a-Rum', 'Croak it'];
const texts = [t`Here be dragons`, t`Otterly empty`, t`Kiwibunga`, t`Pump-a-Rum`, t`Croak it`];
const roll = new Date().getMinutes() % icons.length;
const emptyBlock = `
<div class="text_block empty_block">
<i class="fa-solid ${icons[roll]} fa-4x"></i>
<h1>${texts[roll]}</h1>
<p>There are no items to display.</p>
</div>`;
const params = {
text: texts[roll],
icon: icons[roll],
};
const emptyBlock = await renderTemplateAsync('emptyBlock', params);
return $(emptyBlock);
}
/**
* @param {number} hidden Number of hidden characters
*/
function getHiddenBlock(hidden) {
const hiddenBlock = `
<div class="text_block hidden_block">
<small>
<p>${hidden} ${hidden > 1 ? 'characters' : 'character'} hidden.</p>
<div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Characters and groups hidden by filters or closed folders" title="Characters and groups hidden by filters or closed folders"></div>
</small>
</div>`;
async function getHiddenBlock(hidden) {
const params = {
text: (hidden > 1 ? t`${hidden} characters hidden.` : t`${hidden} character hidden.`),
};
const hiddenBlock = await renderTemplateAsync('hiddenBlock', params);
return $(hiddenBlock);
}
@@ -1524,10 +1530,11 @@ export async function printCharacters(fullRefresh = false) {
const entities = getEntitiesList({ doFilter: true });
const pageSize = Number(accountStorage.getItem(storageKey)) || per_page_default;
const sizeChangerOptions = [10, 25, 50, 100, 250, 500, 1000];
$('#rm_print_characters_pagination').pagination({
dataSource: entities,
pageSize: Number(accountStorage.getItem(storageKey)) || per_page_default,
sizeChangerOptions: [10, 25, 50, 100, 250, 500, 1000],
pageSize,
pageRange: 1,
pageNumber: saveCharactersPage || 1,
position: 'top',
@@ -1536,14 +1543,16 @@ export async function printCharacters(fullRefresh = false) {
prevText: '<',
nextText: '>',
formatNavigator: PAGINATION_TEMPLATE,
formatSizeChanger: renderPaginationDropdown(pageSize, sizeChangerOptions),
showNavigator: true,
callback: function (/** @type {Entity[]} */ data) {
callback: async function (/** @type {Entity[]} */ data) {
$(listId).empty();
if (power_user.bogus_folders && isBogusFolderOpen()) {
$(listId).append(getBackBlock());
}
if (!data.length) {
$(listId).append(getEmptyBlock());
const emptyBlock = await getEmptyBlock();
$(listId).append(emptyBlock);
}
let displayCount = 0;
for (const i of data) {
@@ -1564,13 +1573,16 @@ export async function printCharacters(fullRefresh = false) {
const hidden = (characters.length + groups.length) - displayCount;
if (hidden > 0 && entitiesFilter.hasAnyFilter()) {
$(listId).append(getHiddenBlock(hidden));
const hiddenBlock = await getHiddenBlock(hidden);
$(listId).append(hiddenBlock);
}
localizePagination($('#rm_print_characters_pagination'));
eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
},
afterSizeSelectorChange: function (e) {
afterSizeSelectorChange: function (e, size) {
accountStorage.setItem(storageKey, e.target.value);
paginationDropdownChangeHandler(e, size);
},
afterPaging: function (e) {
saveCharactersPage = e;
@@ -1911,6 +1923,7 @@ export async function showMoreMessages(messagesToLoad = null) {
$('#chat').scrollTop(newHeight - prevHeight);
}
applyStylePins();
await eventSource.emit(event_types.MORE_MESSAGES_LOADED);
}
@@ -1948,6 +1961,7 @@ export async function printMessages() {
hideSwipeButtons();
showSwipeButtons();
scrollChatToBottom();
applyStylePins();
function incrementAndCheck() {
imagesLoaded++;
@@ -2751,6 +2765,7 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re
environment.charVersion = fields.version || '';
environment.char_version = fields.version || '';
environment.charDepthPrompt = fields.charDepthPrompt || '';
environment.creatorNotes = fields.creatorNotes || '';
}
// Must be substituted last so that they're replaced inside {{description}}
@@ -3129,6 +3144,7 @@ export function baseChatReplace(value, name1, name2) {
* @property {string} jailbreak Jailbreak instructions
* @property {string} version Character version
* @property {string} charDepthPrompt Character depth note
* @property {string} creatorNotes Character creator notes
* @returns {CharacterCardFields} Character card fields
*/
export function getCharacterCardFields({ chid = null } = {}) {
@@ -3144,6 +3160,7 @@ export function getCharacterCardFields({ chid = null } = {}) {
jailbreak: '',
version: '',
charDepthPrompt: '',
creatorNotes: '',
};
result.persona = baseChatReplace(power_user.persona_description?.trim(), name1, name2);
@@ -3162,6 +3179,7 @@ export function getCharacterCardFields({ chid = null } = {}) {
result.jailbreak = power_user.prefer_character_jailbreak ? baseChatReplace(character.data?.post_history_instructions?.trim(), name1, name2) : '';
result.version = character.data?.character_version ?? '';
result.charDepthPrompt = baseChatReplace(character.data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2);
result.creatorNotes = baseChatReplace(character.data?.creator_notes?.trim(), name1, name2);
if (selected_group) {
const groupCards = getGroupCharacterCards(selected_group, Number(currentChid));
@@ -3989,11 +4007,14 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
system,
jailbreak,
charDepthPrompt,
creatorNotes,
} = getCharacterCardFields();
if (main_api !== 'openai') {
if (power_user.sysprompt.enabled) {
system = power_user.prefer_character_prompt && system ? system : baseChatReplace(power_user.sysprompt.content, name1, name2);
system = power_user.prefer_character_prompt && system
? substituteParams(system, name1, name2, (power_user.sysprompt.content ?? ''))
: baseChatReplace(power_user.sysprompt.content, name1, name2);
system = isInstruct ? formatInstructModeSystemPrompt(substituteParams(system, name1, name2, power_user.sysprompt.content)) : system;
} else {
// Nullify if it's not enabled
@@ -4143,7 +4164,15 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
// Make quiet prompt available for WIAN
setExtensionPrompt('QUIET_PROMPT', quiet_prompt || '', extension_prompt_types.IN_PROMPT, 0, true);
const chatForWI = coreChat.map(x => world_info_include_names ? `${x.name}: ${x.mes}` : x.mes).reverse();
const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(chatForWI, this_max_context, dryRun);
const globalScanData = {
personaDescription: persona,
characterDescription: description,
characterPersonality: personality,
characterDepthPrompt: charDepthPrompt,
scenario: scenario,
creatorNotes: creatorNotes,
};
const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(chatForWI, this_max_context, dryRun, globalScanData);
setExtensionPrompt('QUIET_PROMPT', '', extension_prompt_types.IN_PROMPT, 0, true);
// Add message example WI
@@ -4192,17 +4221,20 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
injectedIndices = await doChatInject(coreChat, isContinue);
}
// Insert character jailbreak as the last user message (if exists, allowed, preferred, and not using Chat Completion)
if (power_user.context.allow_jailbreak && power_user.prefer_character_jailbreak && main_api !== 'openai' && jailbreak) {
// Set "original" explicity to empty string since there's no original
jailbreak = substituteParams(jailbreak, name1, name2, '');
if (main_api !== 'openai' && power_user.sysprompt.enabled) {
jailbreak = power_user.prefer_character_jailbreak && jailbreak
? substituteParams(jailbreak, name1, name2, (power_user.sysprompt.post_history ?? ''))
: baseChatReplace(power_user.sysprompt.post_history, name1, name2);
// When continuing generation of previous output, last user message precedes the message to continue
if (isContinue) {
coreChat.splice(coreChat.length - 1, 0, { mes: jailbreak, is_user: true });
}
else {
coreChat.push({ mes: jailbreak, is_user: true });
// Only inject the jb if there is one
if (jailbreak) {
// When continuing generation of previous output, last user message precedes the message to continue
if (isContinue) {
coreChat.splice(coreChat.length - 1, 0, { mes: jailbreak, is_user: true });
}
else {
coreChat.push({ mes: jailbreak, is_user: true });
}
}
}
@@ -4235,12 +4267,20 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
// Do not suffix the message for continuation
if (i === 0 && isContinue) {
// Pick something that's very unlikely to be in a message
const FORMAT_TOKEN = '\u0000\ufffc\u0000\ufffd';
if (isInstruct) {
const originalMessage = String(coreChat[j].mes ?? '');
coreChat[j].mes = originalMessage.replaceAll(FORMAT_TOKEN, '') + FORMAT_TOKEN;
// Reformat with the last output sequence (if any)
chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.LAST);
coreChat[j].mes = originalMessage;
}
chat2[i] = chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length);
chat2[i] = chat2[i].includes(FORMAT_TOKEN)
? chat2[i].slice(0, chat2[i].lastIndexOf(FORMAT_TOKEN))
: chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length);
continue_mag = coreChat[j].mes;
}
@@ -4854,6 +4894,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''),
tokenizer: getFriendlyTokenizerName(main_api).tokenizerName || '',
presetName: getPresetManager()?.getSelectedPresetName() || '',
messagesCount: main_api !== 'openai' ? mesSend.length : oaiMessages.length,
examplesCount: main_api !== 'openai' ? (pinExmString ? mesExamplesArray.length : count_exm_add) : oaiMessageExamples.length,
};
//console.log(additionalPromptStuff);
@@ -5537,6 +5579,8 @@ export async function itemizedParams(itemizedPrompts, thisPromptSet, incomingMes
modelUsed: chat[incomingMesId]?.extra?.model,
apiUsed: chat[incomingMesId]?.extra?.api,
presetName: itemizedPrompts[thisPromptSet].presetName || t`(Unknown)`,
messagesCount: String(itemizedPrompts[thisPromptSet].messagesCount ?? ''),
examplesCount: String(itemizedPrompts[thisPromptSet].examplesCount ?? ''),
};
const getFriendlyName = (value) => $(`#rm_api_block select option[value="${value}"]`).first().text() || value;
@@ -6955,15 +6999,23 @@ export async function saveChat({ chatName, withMetadata, mesId, force = false }
throw new Error(result.statusText);
}
const forceSaveConfirmed = await Popup.show.confirm(
t`ERROR: Chat integrity check failed.`,
t`Continuing the operation may result in data loss. Would you like to overwrite the chat file anyway? Pressing "NO" will cancel the save operation.`,
{ okButton: t`Yes, overwrite`, cancelButton: t`No, cancel` },
) === POPUP_RESULT.AFFIRMATIVE;
const popupResult = await Popup.show.input(
t`ERROR: Chat integrity check failed while saving the file.`,
t`<p>After you click OK, the page will be reloaded to prevent data corruption.</p>
<p>To confirm an overwrite (and potentially <b>LOSE YOUR DATA</b>), enter <code>OVERWRITE</code> (in all caps) in the box below before clicking OK.</p>`,
'',
{ okButton: 'OK', cancelButton: false },
);
if (forceSaveConfirmed) {
await saveChat({ chatName, withMetadata, mesId, force: true });
const forceSaveConfirmed = popupResult === 'OVERWRITE';
if (!forceSaveConfirmed) {
console.warn('Chat integrity check failed, and user did not confirm the overwrite. Reloading the page.');
window.location.reload();
return;
}
await saveChat({ chatName, withMetadata, mesId, force: true });
} catch (error) {
console.error(error);
toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Chat could not be saved`);
@@ -8390,15 +8442,15 @@ export function callPopup(text, type, inputValue = '', { okButton, rows, wide, w
function getOkButtonText() {
if (['text', 'char_not_selected'].includes(popup_type)) {
$dialoguePopupCancel.css('display', 'none');
return okButton ?? 'Ok';
return okButton ?? t`Ok`;
} else if (['delete_extension'].includes(popup_type)) {
return okButton ?? 'Ok';
return okButton ?? t`Ok`;
} else if (['new_chat', 'confirm'].includes(popup_type)) {
return okButton ?? 'Yes';
return okButton ?? t`Yes`;
} else if (['input'].includes(popup_type)) {
return okButton ?? t`Save`;
}
return okButton ?? 'Delete';
return okButton ?? t`Delete`;
}
dialogueCloseStop = true;
@@ -9104,7 +9156,7 @@ function formatSwipeCounter(current, total) {
* @param {string} [params.source] The source of the swipe event.
* @param {boolean} [params.repeated] Is the swipe event repeated.
*/
function swipe_left(_event, { source, repeated } = {}) {
export function swipe_left(_event, { source, repeated } = {}) {
if (chat.length - 1 === Number(this_edit_mes_id)) {
closeMessageEditor();
}
@@ -9252,7 +9304,7 @@ function swipe_left(_event, { source, repeated } = {}) {
* @param {string} [params.source] The source of the swipe event.
* @param {boolean} [params.repeated] Is the swipe event repeated.
*/
function swipe_right(_event, { source, repeated } = {}) {
export function swipe_right(_event, { source, repeated } = {}) {
if (chat.length - 1 === Number(this_edit_mes_id)) {
closeMessageEditor();
}
@@ -11847,8 +11899,8 @@ jQuery(async function () {
return;
}
const drawer = $(this).closest('.inline-drawer');
const icon = drawer.find('.inline-drawer-icon');
const drawerContent = drawer.find('.inline-drawer-content');
const icon = drawer.find('>.inline-drawer-header .inline-drawer-icon');
const drawerContent = drawer.find('>.inline-drawer-content');
icon.toggleClass('down up');
icon.toggleClass('fa-circle-chevron-down fa-circle-chevron-up');
drawerContent.stop().slideToggle({
@@ -12224,8 +12276,6 @@ jQuery(async function () {
// Added here to prevent execution before script.js is loaded and get rid of quirky timeouts
await firstLoadInit();
addDebugFunctions();
eventSource.on(event_types.CHAT_DELETED, async (name) => {
await deleteItemizedPrompts(name);
});
@@ -12233,8 +12283,6 @@ jQuery(async function () {
await deleteItemizedPrompts(name);
});
initCustomSelectedSamplers();
window.addEventListener('beforeunload', (e) => {
if (isChatSaving) {
e.preventDefault();

View File

@@ -196,6 +196,17 @@ export class PromptCollection {
}
class PromptManager {
get promptSources() {
return {
charDescription: t`Character Description`,
charPersonality: t`Character Personality`,
scenario: t`Character Scenario`,
personaDescription: t`Persona Description`,
worldInfoBefore: t`World Info (↑Char)`,
worldInfoAfter: t`World Info (↓Char)`,
};
}
constructor() {
this.systemPrompts = [
'main',
@@ -408,6 +419,7 @@ class PromptManager {
this.handleResetPrompt = (event) => {
const promptId = event.target.dataset.pmPrompt;
const prompt = this.getPromptById(promptId);
const isPulledPrompt = Object.keys(this.promptSources).includes(promptId);
switch (promptId) {
case 'main':
@@ -439,6 +451,12 @@ class PromptManager {
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides').checked = prompt.forbid_overrides ?? false;
document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block').style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden';
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').disabled = prompt.marker ?? false;
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block').style.display = isPulledPrompt ? '' : 'none';
if (isPulledPrompt) {
const sourceName = this.promptSources[promptId];
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source').textContent = sourceName;
}
if (!this.systemPrompts.includes(promptId)) {
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').removeAttribute('disabled');
@@ -1207,6 +1225,9 @@ class PromptManager {
const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block');
const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides');
const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block');
const entrySourceBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block');
const entrySource = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source');
const isPulledPrompt = Object.keys(this.promptSources).includes(prompt.identifier);
nameField.value = prompt.name ?? '';
roleField.value = prompt.role || 'system';
@@ -1218,6 +1239,12 @@ class PromptManager {
injectionPositionField.removeAttribute('disabled');
forbidOverridesField.checked = prompt.forbid_overrides ?? false;
forbidOverridesBlock.style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden';
entrySourceBlock.style.display = isPulledPrompt ? '' : 'none';
if (isPulledPrompt) {
const sourceName = this.promptSources[prompt.identifier];
entrySource.textContent = sourceName;
}
if (this.systemPrompts.includes(prompt.identifier)) {
injectionPositionField.setAttribute('disabled', 'disabled');
@@ -1303,6 +1330,8 @@ class PromptManager {
const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block');
const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides');
const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block');
const entrySourceBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block');
const entrySource = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source');
nameField.value = '';
roleField.selectedIndex = 0;
@@ -1314,6 +1343,8 @@ class PromptManager {
injectionDepthBlock.style.visibility = 'unset';
forbidOverridesBlock.style.visibility = 'unset';
forbidOverridesField.checked = false;
entrySourceBlock.style.display = 'none';
entrySource.textContent = '';
roleField.disabled = false;
}

View File

@@ -1048,7 +1048,7 @@ export function initRossMods() {
//Enter to send when send_textarea in focus
if (document.activeElement == hotkeyTargets['send_textarea']) {
const sendOnEnter = shouldSendOnEnter();
if (!event.shiftKey && !event.ctrlKey && !event.altKey && event.key == 'Enter' && sendOnEnter) {
if (!event.isComposing && !event.shiftKey && !event.ctrlKey && !event.altKey && event.key == 'Enter' && sendOnEnter) {
event.preventDefault();
sendTextareaMessage();
return;
@@ -1120,7 +1120,7 @@ export function initRossMods() {
const result = await Popup.show.confirm('Regenerate Message', 'Are you sure you want to regenerate the latest message?', {
customInputs: [{ id: 'regenerateWithCtrlEnter', label: 'Don\'t ask again' }],
onClose: (popup) => {
regenerateWithCtrlEnter = popup.inputResults.get('regenerateWithCtrlEnter') ?? false;
regenerateWithCtrlEnter = Boolean(popup.inputResults.get('regenerateWithCtrlEnter') ?? false);
},
});
if (!result) {

View File

@@ -1,11 +1,12 @@
import { Fuse } from '../lib.js';
import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl, saveSettingsDebounced } from '../script.js';
import { saveMetadataDebounced } from './extensions.js';
import { openThirdPartyExtensionMenu, saveMetadataDebounced } from './extensions.js';
import { SlashCommand } from './slash-commands/SlashCommand.js';
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
import { flashHighlight, stringFormat } from './utils.js';
import { t } from './i18n.js';
import { Popup } from './popup.js';
const BG_METADATA_KEY = 'custom_background';
const LIST_METADATA_KEY = 'chat_backgrounds';
@@ -77,7 +78,7 @@ function getChatBackgroundsList() {
}
function getBackgroundPath(fileUrl) {
return `backgrounds/${fileUrl}`;
return `backgrounds/${encodeURIComponent(fileUrl)}`;
}
function highlightLockedBackground() {
@@ -217,7 +218,7 @@ async function onCopyToSystemBackgroundClick(e) {
const formData = new FormData();
formData.set('avatar', file);
uploadBackground(formData);
await uploadBackground(formData);
const list = chat_metadata[LIST_METADATA_KEY] || [];
const index = list.indexOf(bgNames.oldBg);
@@ -291,7 +292,7 @@ async function onDeleteBackgroundClick(e) {
const bgToDelete = $(this).closest('.bg_example');
const url = bgToDelete.data('url');
const isCustom = bgToDelete.attr('custom') === 'true';
const confirm = await callPopup('<h3>Delete the background?</h3>', 'confirm');
const confirm = await Popup.show.confirm(t`Delete the background?`, null);
const bg = bgToDelete.attr('bgfile');
if (confirm) {
@@ -438,7 +439,7 @@ async function delBackground(bg) {
});
}
function onBackgroundUploadSelected() {
async function onBackgroundUploadSelected() {
const form = $('#form_bg_download').get(0);
if (!(form instanceof HTMLFormElement)) {
@@ -447,34 +448,82 @@ function onBackgroundUploadSelected() {
}
const formData = new FormData(form);
uploadBackground(formData);
await convertFileIfVideo(formData);
await uploadBackground(formData);
form.reset();
}
/**
* Converts a video file to an animated webp format if the file is a video.
* @param {FormData} formData
* @returns {Promise<void>}
*/
async function convertFileIfVideo(formData) {
const file = formData.get('avatar');
if (!(file instanceof File)) {
return;
}
if (!file.type.startsWith('video/')) {
return;
}
if (typeof globalThis.convertVideoToAnimatedWebp !== 'function') {
toastr.warning(t`Click here to install the Video Background Loader extension`, t`Video background uploads require a downloadable add-on`, {
timeOut: 0,
extendedTimeOut: 0,
onclick: () => openThirdPartyExtensionMenu('https://github.com/SillyTavern/Extension-VideoBackgroundLoader'),
});
return;
}
let toastMessage = jQuery();
try {
toastMessage = toastr.info(t`Preparing video for upload. This may take several minutes.`, t`Please wait`, { timeOut: 0, extendedTimeOut: 0 });
const sourceBuffer = await file.arrayBuffer();
const convertedBuffer = await globalThis.convertVideoToAnimatedWebp({ buffer: new Uint8Array(sourceBuffer), name: file.name });
const convertedFileName = file.name.replace(/\.[^/.]+$/, '.webp');
const convertedFile = new File([convertedBuffer], convertedFileName, { type: 'image/webp' });
formData.set('avatar', convertedFile);
toastMessage.remove();
} catch (error) {
formData.delete('avatar');
toastMessage.remove();
console.error('Error converting video to animated webp:', error);
toastr.error(t`Error converting video to animated webp`);
}
}
/**
* Uploads a background to the server
* @param {FormData} formData
*/
function uploadBackground(formData) {
jQuery.ajax({
type: 'POST',
url: '/api/backgrounds/upload',
data: formData,
beforeSend: function () {
},
cache: false,
contentType: false,
processData: false,
success: async function (bg) {
setBackground(bg, generateUrlParameter(bg, false));
await getBackgrounds();
highlightNewBackground(bg);
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
async function uploadBackground(formData) {
try {
if (!formData.has('avatar')) {
console.log('No file provided. Background upload cancelled.');
return;
}
const headers = getRequestHeaders();
delete headers['Content-Type'];
const response = await fetch('/api/backgrounds/upload', {
method: 'POST',
headers: headers,
body: formData,
cache: 'no-cache',
});
if (!response.ok) {
throw new Error('Failed to upload background');
}
const bg = await response.text();
setBackground(bg, generateUrlParameter(bg, false));
await getBackgrounds();
highlightNewBackground(bg);
} catch (error) {
console.error('Error uploading background:', error);
}
}
/**

View File

@@ -33,6 +33,12 @@
* @property {number} role - The specific function or purpose of the extension.
* @property {boolean} vectorized - Indicates if the extension is optimized for vectorized processing.
* @property {number} display_index - The order in which the extension should be displayed for user interfaces.
* @property {boolean} match_persona_description - Wether to match against the persona description.
* @property {boolean} match_character_description - Wether to match against the persona description.
* @property {boolean} match_character_personality - Wether to match against the character personality.
* @property {boolean} match_character_depth_prompt - Wether to match against the character depth prompt.
* @property {boolean} match_scenario - Wether to match against the character scenario.
* @property {boolean} match_creator_notes - Wether to match against the character creator notes.
*/
/**

View File

@@ -74,6 +74,11 @@ const hash_derivations = {
'b6835114b7303ddd78919a82e4d9f7d8c26ed0d7dfc36beeb12d524f6144eab1':
'DeepSeek-V2.5'
,
// THUDM-GLM 4
'854b703e44ca06bdb196cc471c728d15dbab61e744fe6cdce980086b61646ed1':
'GLM-4'
,
};
const substr_derivations = {

View File

@@ -1576,7 +1576,8 @@ jQuery(function () {
await callGenericPopup(wrapper, POPUP_TYPE.TEXT, '', { wide: true, large: true });
});
$(document).on('click', 'body.documentstyle .mes .mes_text', function () {
$(document).on('click', 'body .mes .mes_text', function () {
if (!power_user.click_to_edit) return;
if (window.getSelection().toString()) return;
if ($('.edit_textarea').length) return;
$(this).closest('.mes').find('.mes_edit').trigger('click');

View File

@@ -661,6 +661,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
let deleteButton = isExternal ? `<button class="btn_delete menu_button" data-name="${externalId}" data-i18n="[title]Delete" title="Delete"><i class="fa-fw fa-solid fa-trash-can"></i></button>` : '';
let updateButton = isExternal ? `<button class="btn_update menu_button displayNone" data-name="${externalId}" title="Update available"><i class="fa-solid fa-download fa-fw"></i></button>` : '';
let moveButton = isExternal && isUserAdmin ? `<button class="btn_move menu_button" data-name="${externalId}" data-i18n="[title]Move" title="Move"><i class="fa-solid fa-folder-tree fa-fw"></i></button>` : '';
let branchButton = isExternal && isUserAdmin ? `<button class="btn_branch menu_button" data-name="${externalId}" data-i18n="[title]Switch branch" title="Switch branch"><i class="fa-solid fa-code-branch fa-fw"></i></button>` : '';
let modulesInfo = '';
if (isActive && Array.isArray(manifest.optional)) {
@@ -701,6 +702,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal,
<div class="extension_actions flex-container alignItemsCenter">
${updateButton}
${branchButton}
${moveButton}
${deleteButton}
</div>
@@ -944,6 +946,44 @@ async function onDeleteClick() {
}
}
async function onBranchClick() {
const extensionName = $(this).data('name');
const isCurrentUserAdmin = isAdmin();
const isGlobal = getExtensionType(extensionName) === 'global';
if (isGlobal && !isCurrentUserAdmin) {
toastr.error(t`You don't have permission to switch branch.`);
return;
}
let newBranch = '';
const branches = await getExtensionBranches(extensionName, isGlobal);
const selectElement = document.createElement('select');
selectElement.classList.add('text_pole', 'wide100p');
selectElement.addEventListener('change', function () {
newBranch = this.value;
});
for (const branch of branches) {
const option = document.createElement('option');
option.value = branch.name;
option.textContent = `${branch.name} (${branch.commit}) [${branch.label}]`;
option.selected = branch.current;
selectElement.appendChild(option);
}
const popup = new Popup(selectElement, POPUP_TYPE.CONFIRM, '', {
okButton: t`Switch`,
cancelButton: t`Cancel`,
});
const popupResult = await popup.show();
if (!popupResult || !newBranch) {
return;
}
await switchExtensionBranch(extensionName, isGlobal, newBranch);
}
async function onMoveClick() {
const extensionName = $(this).data('name');
const isCurrentUserAdmin = isAdmin();
@@ -1055,13 +1095,83 @@ async function getExtensionVersion(extensionName, abortSignal) {
}
}
/**
* Gets the list of branches for a specific extension.
* @param {string} extensionName The name of the extension
* @param {boolean} isGlobal Whether the extension is global or not
* @returns {Promise<ExtensionBranch[]>} List of branches for the extension
* @typedef {object} ExtensionBranch
* @property {string} name The name of the branch
* @property {string} commit The commit hash of the branch
* @property {boolean} current Whether this branch is the current one
* @property {string} label The commit label of the branch
*/
async function getExtensionBranches(extensionName, isGlobal) {
try {
const response = await fetch('/api/extensions/branches', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
extensionName,
global: isGlobal,
}),
});
if (!response.ok) {
const text = await response.text();
toastr.error(text || response.statusText, t`Extension branches fetch failed`);
console.error('Extension branches fetch failed', response.status, response.statusText, text);
return [];
}
return await response.json();
} catch (error) {
console.error('Error:', error);
return [];
}
}
/**
* Switches the branch of an extension.
* @param {string} extensionName The name of the extension
* @param {boolean} isGlobal If the extension is global
* @param {string} branch Branch name to switch to
* @returns {Promise<void>}
*/
async function switchExtensionBranch(extensionName, isGlobal, branch) {
try {
const response = await fetch('/api/extensions/switch', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
extensionName,
branch,
global: isGlobal,
}),
});
if (!response.ok) {
const text = await response.text();
toastr.error(text || response.statusText, t`Extension branch switch failed`);
console.error('Extension branch switch failed', response.status, response.statusText, text);
return;
}
toastr.success(t`Extension ${extensionName} switched to ${branch}`);
await loadExtensionSettings({}, false, false);
void showExtensionsDetails();
} catch (error) {
console.error('Error:', error);
}
}
/**
* Installs a third-party extension via the API.
* @param {string} url Extension repository URL
* @param {boolean} global Is the extension global?
* @returns {Promise<void>}
*/
export async function installExtension(url, global) {
export async function installExtension(url, global, branch = '') {
console.debug('Extension installation started', url);
toastr.info(t`Please wait...`, t`Installing extension`);
@@ -1072,6 +1182,7 @@ export async function installExtension(url, global) {
body: JSON.stringify({
url,
global,
branch,
}),
});
@@ -1406,9 +1517,17 @@ export async function openThirdPartyExtensionMenu(suggestUrl = '') {
await popup.complete(POPUP_RESULT.AFFIRMATIVE);
},
};
/** @type {import('./popup.js').CustomPopupInput} */
const branchNameInput = {
id: 'extension_branch_name',
label: t`Branch or tag name (optional)`,
type: 'text',
tooltip: 'e.g. main, dev, v1.0.0',
};
const customButtons = isCurrentUserAdmin ? [installForAllButton] : [];
const popup = new Popup(html, POPUP_TYPE.INPUT, suggestUrl ?? '', { okButton, customButtons });
const customInputs = [branchNameInput];
const popup = new Popup(html, POPUP_TYPE.INPUT, suggestUrl ?? '', { okButton, customButtons, customInputs });
const input = await popup.show();
if (!input) {
@@ -1417,7 +1536,8 @@ export async function openThirdPartyExtensionMenu(suggestUrl = '') {
}
const url = String(input).trim();
await installExtension(url, global);
const branchName = String(popup.inputResults.get('extension_branch_name') ?? '').trim();
await installExtension(url, global, branchName);
}
export async function initExtensions() {
@@ -1433,6 +1553,7 @@ export async function initExtensions() {
$(document).on('click', '.extensions_info .extension_block .btn_update', onUpdateClick);
$(document).on('click', '.extensions_info .extension_block .btn_delete', onDeleteClick);
$(document).on('click', '.extensions_info .extension_block .btn_move', onMoveClick);
$(document).on('click', '.extensions_info .extension_block .btn_branch', onBranchClick);
/**
* Handles the click event for the third-party extension import button.

View File

@@ -291,7 +291,7 @@ async function installAsset(url, assetType, filename) {
try {
if (category === 'extension') {
console.debug(DEBUG_PREFIX, 'Installing extension ', url);
await installExtension(url);
await installExtension(url, false);
console.debug(DEBUG_PREFIX, 'Extension installed.');
return;
}
@@ -309,7 +309,7 @@ async function installAsset(url, assetType, filename) {
console.debug(DEBUG_PREFIX, 'Importing character ', filename);
const blob = await result.blob();
const file = new File([blob], filename, { type: blob.type });
await processDroppedFiles([file], true);
await processDroppedFiles([file]);
console.debug(DEBUG_PREFIX, 'Character downloaded.');
}
}

View File

@@ -39,7 +39,7 @@ To install a single 3rd party extension, use the &quot;Install Extensions&quot;
<span data-i18n="Characters">Characters</span>
</div>
</div>
<div class="inline-drawer-content" id="assets_menu">
<div id="assets_menu">
</div>
</div>
</div>

View File

@@ -46,6 +46,8 @@
<option data-type="mistral" value="mistral-large-pixtral-2411">mistral-large-pixtral-2411</option>
<option data-type="mistral" value="mistral-small-2503">mistral-small-2503</option>
<option data-type="mistral" value="mistral-small-latest">mistral-small-latest</option>
<option data-type="mistral" value="mistral-medium-latest">mistral-medium-latest</option>
<option data-type="mistral" value="mistral-medium-2505">mistral-medium-2505</option>
<option data-type="zerooneai" value="yi-vision">yi-vision</option>
<option data-type="openai" value="gpt-4.1">gpt-4.1</option>
<option data-type="openai" value="gpt-4.1-2025-04-14">gpt-4.1-2025-04-14</option>
@@ -57,9 +59,14 @@
<option data-type="openai" value="gpt-4-turbo">gpt-4-turbo</option>
<option data-type="openai" value="gpt-4o">gpt-4o</option>
<option data-type="openai" value="gpt-4o-mini">gpt-4o-mini</option>
<option data-type="openai" value="gpt-4o-mini-2024-07-18">gpt-4o-mini-2024-07-18</option>
<option data-type="openai" value="chatgpt-4o-latest">chatgpt-4o-latest</option>
<option data-type="openai" value="o1">o1</option>
<option data-type="openai" value="o1-2024-12-17">o1-2024-12-17</option>
<option data-type="openai" value="o3">o3</option>
<option data-type="openai" value="o3-2025-04-16">o3-2025-04-16</option>
<option data-type="openai" value="o4-mini">o4-mini</option>
<option data-type="openai" value="o4-mini-2025-04-16">o4-mini-2025-04-16</option>
<option data-type="openai" value="gpt-4.5-preview">gpt-4.5-preview</option>
<option data-type="openai" value="gpt-4.5-preview-2025-02-27">gpt-4.5-preview-2025-02-27</option>
<option data-type="anthropic" value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option>
@@ -72,35 +79,36 @@
<option data-type="anthropic" value="claude-3-opus-20240229">claude-3-opus-20240229</option>
<option data-type="anthropic" value="claude-3-sonnet-20240229">claude-3-sonnet-20240229</option>
<option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option>
<option data-type="google" value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option>
<option data-type="google" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option>
<option data-type="google" value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-2.0-pro-exp">gemini-2.0-pro-exp</option>
<option data-type="google" value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05</option>
<option data-type="google" value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option>
<option data-type="google" value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option>
<option data-type="google" value="gemini-2.0-flash">gemini-2.0-flash</option>
<option data-type="google" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option>
<option data-type="google" value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-exp-1206">gemini-exp-1206 → 2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-2.0-flash-001">gemini-2.0-flash-001</option>
<option data-type="google" value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option>
<option data-type="google" value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219</option>
<option data-type="google" value="gemini-1.5-flash">gemini-1.5-flash</option>
<option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option>
<option data-type="google" value="gemini-1.5-flash-001">gemini-1.5-flash-001</option>
<option data-type="google" value="gemini-1.5-flash-002">gemini-1.5-flash-002</option>
<option data-type="google" value="gemini-1.5-flash-exp-0827">gemini-1.5-flash-exp-0827</option>
<option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option>
<option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option>
<option data-type="google" value="gemini-exp-1114">gemini-exp-1114</option>
<option data-type="google" value="gemini-exp-1121">gemini-exp-1121</option>
<option data-type="google" value="gemini-exp-1206">gemini-exp-1206</option>
<option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option>
<option data-type="google" value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option>
<option data-type="google" value="gemini-2.0-flash">gemini-2.0-flash</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21 → 2.5-flash-preview-04-17</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219 → 2.5-flash-preview-04-17</option>
<option data-type="google" value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp → 2.5-flash-preview-04-17</option>
<option data-type="google" value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option>
<option data-type="google" value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option>
<option data-type="google" value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option>
<option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option>
<option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option>
<option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option>
<option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option>
<option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option>
<option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option>
<option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option>
<option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option>
<option data-type="google" value="gemini-1.5-flash-002">gemini-1.5-flash-002</option>
<option data-type="google" value="gemini-1.5-flash-001">gemini-1.5-flash-001</option>
<option data-type="google" value="gemini-1.5-flash">gemini-1.5-flash</option>
<option data-type="google" value="gemini-1.5-flash-8b-001">gemini-1.5-flash-8b-001</option>
<option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option>
<option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option>
<option data-type="google" value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option>
<option data-type="google" value="learnlm-1.5-pro-experimental">learnlm-1.5-pro-experimental</option>
<option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option>
<option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option>
<option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option>

View File

@@ -22,7 +22,7 @@ export async function getMultimodalCaption(base64Img, prompt) {
throwIfInvalidModel(useReverseProxy);
const noPrefix = ['ollama', 'llamacpp'].includes(extension_settings.caption.multimodal_api);
const noPrefix = ['ollama'].includes(extension_settings.caption.multimodal_api);
if (noPrefix && base64Img.startsWith('data:image/')) {
base64Img = base64Img.split(',')[1];
@@ -97,8 +97,6 @@ export async function getMultimodalCaption(base64Img, prompt) {
return '/api/google/caption-image';
case 'anthropic':
return '/api/anthropic/caption-image';
case 'llamacpp':
return '/api/backends/text-completions/llamacpp/caption-image';
case 'ollama':
return '/api/backends/text-completions/ollama/caption-image';
default:

View File

@@ -76,7 +76,7 @@
<div id="tts_voicemap_block">
</div>
<hr>
<form id="tts_provider_settings" class="inline-drawer-content">
<form id="tts_provider_settings">
</form>
<div class="tts_buttons">
<input id="tts_voices" class="menu_button" type="submit" value="Available voices" />

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