mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' of https://github.com/BlipRanger/SillyTavern into feature/stats
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,5 +23,6 @@ secrets.json
|
||||
/dist
|
||||
poe_device.json
|
||||
/backups/
|
||||
public/movingUI/
|
||||
poe-error.log
|
||||
poe-success.log
|
54
package-lock.json
generated
54
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "sillytavern",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "sillytavern",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@dqbd/tiktoken": "^1.0.2",
|
||||
@@ -71,18 +71,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz",
|
||||
"integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
|
||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
|
||||
"integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -647,9 +647,9 @@
|
||||
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.7.11",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.11.tgz",
|
||||
"integrity": "sha512-UDi3g6Jss/W5FnSzO9jCtQwEpfymt0M+sPPlmLhDH6h2TJ8j4ESE/LpmNPBij15J5NKkk4/cg/qoVMdWI3vnlQ==",
|
||||
"version": "0.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.9.tgz",
|
||||
"integrity": "sha512-4VSbbcMoxc4KLjb1gs96SRmi7w4h1SF+fCoiK0XaQX62buCc1G5d0DC5bJ9xJBNPDSVCmIrcl8BiYxzjrqaaJA==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
@@ -1310,12 +1310,12 @@
|
||||
"integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="
|
||||
},
|
||||
"node_modules/exifreader": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/exifreader/-/exifreader-4.12.0.tgz",
|
||||
"integrity": "sha512-aRSmNyw2c6f6qPK4jmC56W/5XePDN7LVwt8tQjgMchxoY3MCxqEToegirKdS7A3CYCWAOPehfypMZWGWxtLhzw==",
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/exifreader/-/exifreader-4.13.0.tgz",
|
||||
"integrity": "sha512-IhJBpyXDLbCdgzVHkthadOvrMiZOR2XS7POVp0b5JoVfScRoCJ6YazZ+stTkbDTE5TRTP44bE5RKsujckAs45Q==",
|
||||
"hasInstallScript": true,
|
||||
"optionalDependencies": {
|
||||
"@xmldom/xmldom": "^0.7.8"
|
||||
"@xmldom/xmldom": "^0.8.8"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-template": {
|
||||
@@ -1396,9 +1396,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
|
||||
"integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
@@ -2226,9 +2226,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.43.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.43.0.tgz",
|
||||
"integrity": "sha512-QB0MMv+tn9Ur2DtJrc8y09n0n6sw88CyDniWSX2cHW10goQXYPK9ZpFJOktDS4ron501edPX6h9i7Pg+RnH5nQ==",
|
||||
"version": "3.45.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz",
|
||||
"integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
@@ -2238,9 +2238,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.11",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
|
||||
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
|
||||
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
@@ -2991,9 +2991,9 @@
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
|
@@ -49,7 +49,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||
},
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.0",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"pkg": "pkg --compress Gzip --no-bytecode --public ."
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 200,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": true
|
||||
"early_stopping": true,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": false,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": false,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 200,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
22
public/TextGen Settings/Mirostat.settings
Normal file
22
public/TextGen Settings/Mirostat.settings
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"temp": 1,
|
||||
"top_p": 1,
|
||||
"top_k": 0,
|
||||
"typical_p": 1,
|
||||
"top_a": 0,
|
||||
"tfs": 1,
|
||||
"epsilon_cutoff": 0,
|
||||
"eta_cutoff": 0,
|
||||
"rep_pen": 1,
|
||||
"no_repeat_ngram_size": 0,
|
||||
"penalty_alpha": 0,
|
||||
"num_beams": 1,
|
||||
"length_penalty": 1,
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 2,
|
||||
"mirostat_tau": 8,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -13,5 +13,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1.07,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
@@ -15,5 +15,8 @@
|
||||
"min_length": 0,
|
||||
"encoder_rep_pen": 1,
|
||||
"do_sample": true,
|
||||
"early_stopping": false
|
||||
"early_stopping": false,
|
||||
"mirostat_mode": 0,
|
||||
"mirostat_tau": 5,
|
||||
"mirostat_eta": 0.1
|
||||
}
|
||||
|
579
public/i18n.json
579
public/i18n.json
@@ -292,7 +292,293 @@
|
||||
"WEBP": "WEBP",
|
||||
"presets": "预设",
|
||||
"Message Sound": "消息音效",
|
||||
"Author's Note": "作者的注释"
|
||||
"Author's Note": "作者的注释",
|
||||
"Send Jailbreak": "NEEDS TRANSLATION",
|
||||
"Replace empty message": "NEEDS TRANSLATION",
|
||||
"Send this text instead of nothing when the text box is empty.": "NEEDS TRANSLATION",
|
||||
"NSFW avoidance prompt": "NEEDS TRANSLATION",
|
||||
"Prompt that is used when the NSFW toggle is off": "NEEDS TRANSLATION",
|
||||
"Advanced prompt bits": "NEEDS TRANSLATION",
|
||||
"World Info format template": "NEEDS TRANSLATION",
|
||||
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "NEEDS TRANSLATION",
|
||||
"Unrestricted maximum value for the context slider": "NEEDS TRANSLATION",
|
||||
"Chat Completion Source": "NEEDS TRANSLATION",
|
||||
"Avoid sending sensitive information to the Horde.": "NEEDS TRANSLATION",
|
||||
"Review the Privacy statement": "NEEDS TRANSLATION",
|
||||
"Learn how to contribute your idel GPU cycles to the Horde": "NEEDS TRANSLATION",
|
||||
"Trusted workers only": "NEEDS TRANSLATION",
|
||||
"For privacy reasons, your API key will be hidden after you reload the page.": "NEEDS TRANSLATION",
|
||||
"-- Horde models not loaded --": "NEEDS TRANSLATION",
|
||||
"Example: http://127.0.0.1:5000/api ": "NEEDS TRANSLATION",
|
||||
"No connection...": "NEEDS TRANSLATION",
|
||||
"Get your NovelAI API Key": "NEEDS TRANSLATION",
|
||||
"KoboldAI Horde": "NEEDS TRANSLATION",
|
||||
"Text Gen WebUI (ooba)": "NEEDS TRANSLATION",
|
||||
"NovelAI": "NEEDS TRANSLATION",
|
||||
"Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale)": "NEEDS TRANSLATION",
|
||||
"OpenAI API key": "NEEDS TRANSLATION",
|
||||
"Trim spaces": "NEEDS TRANSLATION",
|
||||
"Trim Incomplete Sentences": "NEEDS TRANSLATION",
|
||||
"Include Newline": "NEEDS TRANSLATION",
|
||||
"Non-markdown strings": "NEEDS TRANSLATION",
|
||||
"Replace Macro in Sequences": "NEEDS TRANSLATION",
|
||||
"Presets": "NEEDS TRANSLATION",
|
||||
"Separator": "NEEDS TRANSLATION",
|
||||
"Start Reply With": "NEEDS TRANSLATION",
|
||||
"Show reply prefix in chat": "NEEDS TRANSLATION",
|
||||
"Worlds/Lorebooks": "NEEDS TRANSLATION",
|
||||
"Active World(s)": "NEEDS TRANSLATION",
|
||||
"Character Lore Insertion Strategy": "NEEDS TRANSLATION",
|
||||
"Sorted Evenly": "NEEDS TRANSLATION",
|
||||
"Character Lore First": "NEEDS TRANSLATION",
|
||||
"Global Lore First": "NEEDS TRANSLATION",
|
||||
"-- World Info not found --": "NEEDS TRANSLATION",
|
||||
"Recursive Scan": "NEEDS TRANSLATION",
|
||||
"Case Sensitive": "NEEDS TRANSLATION",
|
||||
"Match whole words": "NEEDS TRANSLATION",
|
||||
"World/Lore Editor": "NEEDS TRANSLATION",
|
||||
"--- None ---": "NEEDS TRANSLATION",
|
||||
"Comma seperated (ignored if empty)": "NEEDS TRANSLATION",
|
||||
"Use Probability": "NEEDS TRANSLATION",
|
||||
"Exclude from recursion": "NEEDS TRANSLATION",
|
||||
"Position:": "NEEDS TRANSLATION",
|
||||
"Before Char Defs": "NEEDS TRANSLATION",
|
||||
"After Char Defs": "NEEDS TRANSLATION",
|
||||
"Before AN": "NEEDS TRANSLATION",
|
||||
"After AN": "NEEDS TRANSLATION",
|
||||
"Order:": "NEEDS TRANSLATION",
|
||||
"Probability:": "NEEDS TRANSLATION",
|
||||
"Delete Entry": "NEEDS TRANSLATION",
|
||||
"User Message Blur Tint": "NEEDS TRANSLATION",
|
||||
"AI Message Blur Tint": "NEEDS TRANSLATION",
|
||||
"Chat Style:": "NEEDS TRANSLATION",
|
||||
"Chat Width (PC):": "NEEDS TRANSLATION",
|
||||
"Chat Timestamps": "NEEDS TRANSLATION",
|
||||
"Message IDs": "NEEDS TRANSLATION",
|
||||
"Prefer Character Card Prompt": "NEEDS TRANSLATION",
|
||||
"Prefer Character Card Jailbreak": "NEEDS TRANSLATION",
|
||||
"Press Send to continue": "NEEDS TRANSLATION",
|
||||
"Log prompts to console": "NEEDS TRANSLATION",
|
||||
"Never resize avatars": "NEEDS TRANSLATION",
|
||||
"Show avatar filenames": "NEEDS TRANSLATION",
|
||||
"Import Card Tags": "NEEDS TRANSLATION",
|
||||
"Confirm message deletion": "NEEDS TRANSLATION",
|
||||
"Spoiler Free Mode": "NEEDS TRANSLATION",
|
||||
"Auto-swipe": "NEEDS TRANSLATION",
|
||||
"Minimum generated message length": "NEEDS TRANSLATION",
|
||||
"Blacklisted words": "NEEDS TRANSLATION",
|
||||
"Blacklisted word count to swipe": "NEEDS TRANSLATION",
|
||||
"Reload Chat": "NEEDS TRANSLATION",
|
||||
"Not Connected": "NEEDS TRANSLATION",
|
||||
"Persona Management": "NEEDS TRANSLATION",
|
||||
"Persona Description": "NEEDS TRANSLATION",
|
||||
"Before Character Card": "NEEDS TRANSLATION",
|
||||
"After Character Card": "NEEDS TRANSLATION",
|
||||
"Top of Author's Note": "NEEDS TRANSLATION",
|
||||
"Bottom of Author's Note": "NEEDS TRANSLATION",
|
||||
"How do I use this?": "NEEDS TRANSLATION",
|
||||
"More...": "NEEDS TRANSLATION",
|
||||
"Link to World Info": "NEEDS TRANSLATION",
|
||||
"Import Card Lore": "NEEDS TRANSLATION",
|
||||
"Scenario Override": "NEEDS TRANSLATION",
|
||||
"Rename": "NEEDS TRANSLATION",
|
||||
"Character Description": "NEEDS TRANSLATION",
|
||||
"Creator's Notes": "NEEDS TRANSLATION",
|
||||
"A-Z": "NEEDS TRANSLATION",
|
||||
"Z-A": "NEEDS TRANSLATION",
|
||||
"Newest": "NEEDS TRANSLATION",
|
||||
"Oldest": "NEEDS TRANSLATION",
|
||||
"Favorites": "NEEDS TRANSLATION",
|
||||
"Recent": "NEEDS TRANSLATION",
|
||||
"Most chats": "NEEDS TRANSLATION",
|
||||
"Least chats": "NEEDS TRANSLATION",
|
||||
"Back": "NEEDS TRANSLATION",
|
||||
"Prompt Overrides (For OpenAI/Claude/Scale APIs, Window/OpenRouter, Poe, and Instruct mode)": "NEEDS TRANSLATION",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "NEEDS TRANSLATION",
|
||||
"Main Prompt": "NEEDS TRANSLATION",
|
||||
"Jailbreak": "NEEDS TRANSLATION",
|
||||
"Creator's Metadata (Not sent with the AI prompt)": "NEEDS TRANSLATION",
|
||||
"Everything here is optional": "NEEDS TRANSLATION",
|
||||
"Created by": "NEEDS TRANSLATION",
|
||||
"Character Version": "NEEDS TRANSLATION",
|
||||
"Tags to Embed": "NEEDS TRANSLATION",
|
||||
"How often the character speaks in group chats!": "NEEDS TRANSLATION",
|
||||
"Important to set the character's writing style.": "NEEDS TRANSLATION",
|
||||
"ATTENTION!": "NEEDS TRANSLATION",
|
||||
"Samplers Order": "NEEDS TRANSLATION",
|
||||
"Samplers will be applied in a top-down order. Use with caution.": "NEEDS TRANSLATION",
|
||||
"Repetition Penalty": "NEEDS TRANSLATION",
|
||||
"Epsilon Cutoff": "NEEDS TRANSLATION",
|
||||
"Eta Cutoff": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Range.": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Freq.": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Presence": "NEEDS TRANSLATION",
|
||||
"Follow_poe": "NEEDS TRANSLATION",
|
||||
"Enter it in the box below:": "NEEDS TRANSLATION",
|
||||
"separate with commas w/o space between": "NEEDS TRANSLATION",
|
||||
"Document": "NEEDS TRANSLATION",
|
||||
"Suggest replies": "NEEDS TRANSLATION",
|
||||
"Show suggested replies. Not all bots support this.": "NEEDS TRANSLATION",
|
||||
"Use 'Unlocked Context' to enable chunked generation.": "NEEDS TRANSLATION",
|
||||
"It extends the context window in exchange for reply generation speed.": "NEEDS TRANSLATION",
|
||||
"Safe Context Size values for Poe bots:": "NEEDS TRANSLATION",
|
||||
"ChatGPT / Sage = 3600-4000 tokens": "NEEDS TRANSLATION",
|
||||
"Claude-instant / Claude+ = 5000-5500 tokens": "NEEDS TRANSLATION",
|
||||
"GPT-4 = 7600-8000": "NEEDS TRANSLATION",
|
||||
"Purge Poe Chat": "NEEDS TRANSLATION",
|
||||
"Continue": "NEEDS TRANSLATION",
|
||||
"Editing:": "NEEDS TRANSLATION",
|
||||
"AI reply prefix": "NEEDS TRANSLATION",
|
||||
"Custom Stopping Strings": "NEEDS TRANSLATION",
|
||||
"JSON serialized array of strings": "NEEDS TRANSLATION",
|
||||
"words you dont want generated separated by comma ','": "NEEDS TRANSLATION",
|
||||
"Extensions URL": "NEEDS TRANSLATION",
|
||||
"API Key": "NEEDS TRANSLATION",
|
||||
"Enter your name": "NEEDS TRANSLATION",
|
||||
"Name this character": "NEEDS TRANSLATION",
|
||||
"Search / Create Tags": "NEEDS TRANSLATION",
|
||||
"Describe your character's physical and mental traits here.": "NEEDS TRANSLATION",
|
||||
"This will be the first message from the character that starts every chat.": "NEEDS TRANSLATION",
|
||||
"Chat Name (Optional)": "NEEDS TRANSLATION",
|
||||
"Filter...": "NEEDS TRANSLATION",
|
||||
"Search...": "NEEDS TRANSLATION",
|
||||
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "NEEDS TRANSLATION",
|
||||
"Any contents here will replace the default Jailbreak Prompt (Character Note for Poe) used for this character. (v2 spec: post_history_instructions)": "NEEDS TRANSLATION",
|
||||
"(Botmaker's name / Contact Info)": "NEEDS TRANSLATION",
|
||||
"(If you want to track character versions)": "NEEDS TRANSLATION",
|
||||
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "NEEDS TRANSLATION",
|
||||
"(Write a comma-separated list of tags)": "NEEDS TRANSLATION",
|
||||
"(A brief description of the personality)": "NEEDS TRANSLATION",
|
||||
"(Circumstances and context of the interaction)": "NEEDS TRANSLATION",
|
||||
"(Examples of chat dialog. Begin each example with START on a new line.)": "NEEDS TRANSLATION",
|
||||
"Injection text (supports parameters)": "NEEDS TRANSLATION",
|
||||
"Injection depth": "NEEDS TRANSLATION",
|
||||
"Type here...": "NEEDS TRANSLATION",
|
||||
"Comma separated (required)": "NEEDS TRANSLATION",
|
||||
"Comma separated (ignored if empty)": "NEEDS TRANSLATION",
|
||||
"What this keyword should mean to the AI, sent verbatim": "NEEDS TRANSLATION",
|
||||
"Not sent to the AI": "NEEDS TRANSLATION",
|
||||
"(This will be the first message from the character that starts every chat)": "NEEDS TRANSLATION",
|
||||
"Not connected to API!": "NEEDS TRANSLATION",
|
||||
"AI Response Configuration": "NEEDS TRANSLATION",
|
||||
"AI Configuration panel will stay open": "NEEDS TRANSLATION",
|
||||
"Update current preset": "NEEDS TRANSLATION",
|
||||
"Create new preset": "NEEDS TRANSLATION",
|
||||
"Import preset": "NEEDS TRANSLATION",
|
||||
"Export preset": "NEEDS TRANSLATION",
|
||||
"Delete the preset": "NEEDS TRANSLATION",
|
||||
"Attempts to automatically jailbreak the bot": "NEEDS TRANSLATION",
|
||||
"Purges the chat history on Poe site": "NEEDS TRANSLATION",
|
||||
"Inserts jailbreak as a last system message": "NEEDS TRANSLATION",
|
||||
"NSFW block goes first in the resulting prompt": "NEEDS TRANSLATION",
|
||||
"Enables OpenAI completion streaming": "NEEDS TRANSLATION",
|
||||
"Wrap user messages in quotes before sending": "NEEDS TRANSLATION",
|
||||
"Restore default prompt": "NEEDS TRANSLATION",
|
||||
"New preset": "NEEDS TRANSLATION",
|
||||
"Delete preset": "NEEDS TRANSLATION",
|
||||
"Restore default jailbreak": "NEEDS TRANSLATION",
|
||||
"Restore default reply": "NEEDS TRANSLATION",
|
||||
"Restore defaul note": "NEEDS TRANSLATION",
|
||||
"API Connections": "NEEDS TRANSLATION",
|
||||
"Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "NEEDS TRANSLATION",
|
||||
"Clear your API key": "NEEDS TRANSLATION",
|
||||
"Refresh models": "NEEDS TRANSLATION",
|
||||
"Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "NEEDS TRANSLATION",
|
||||
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "NEEDS TRANSLATION",
|
||||
"Create New": "NEEDS TRANSLATION",
|
||||
"Edit": "NEEDS TRANSLATION",
|
||||
"World Info & Soft Prompts": "NEEDS TRANSLATION",
|
||||
"Locked = World Editor will stay open": "NEEDS TRANSLATION",
|
||||
"Entries can activate other entries by mentioning their keywords": "NEEDS TRANSLATION",
|
||||
"Lookup for the entry keys in the context will respect the case": "NEEDS TRANSLATION",
|
||||
"If the entry key consists of only one word, it would not be matched as part of other words": "NEEDS TRANSLATION",
|
||||
"Open all Entries": "NEEDS TRANSLATION",
|
||||
"Close all Entries": "NEEDS TRANSLATION",
|
||||
"Create": "NEEDS TRANSLATION",
|
||||
"Import World Info": "NEEDS TRANSLATION",
|
||||
"Export World Info": "NEEDS TRANSLATION",
|
||||
"Delete World Info": "NEEDS TRANSLATION",
|
||||
"Rename World Info": "NEEDS TRANSLATION",
|
||||
"Save changes to a new theme file": "NEEDS TRANSLATION",
|
||||
"removes blur and uses alternative background color for divs": "NEEDS TRANSLATION",
|
||||
"If checked and the character card contains a prompt override (System Prompt), use that instead.": "NEEDS TRANSLATION",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead.": "NEEDS TRANSLATION",
|
||||
"AI Response Formatting": "NEEDS TRANSLATION",
|
||||
"Change Background Image": "NEEDS TRANSLATION",
|
||||
"Extensions": "NEEDS TRANSLATION",
|
||||
"Click to set a new User Name": "NEEDS TRANSLATION",
|
||||
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "NEEDS TRANSLATION",
|
||||
"Click to set user name for all messages": "NEEDS TRANSLATION",
|
||||
"Create a dummy persona": "NEEDS TRANSLATION",
|
||||
"Character Management": "NEEDS TRANSLATION",
|
||||
"Locked = Character Management panel will stay open": "NEEDS TRANSLATION",
|
||||
"Select/Create Characters": "NEEDS TRANSLATION",
|
||||
"Token counts may be inaccurate and provided just for reference.": "NEEDS TRANSLATION",
|
||||
"Click to select a new avatar for this character": "NEEDS TRANSLATION",
|
||||
"Add to Favorites": "NEEDS TRANSLATION",
|
||||
"Advanced Definition": "NEEDS TRANSLATION",
|
||||
"Character Lore": "NEEDS TRANSLATION",
|
||||
"Export and Download": "NEEDS TRANSLATION",
|
||||
"Duplicate Character": "NEEDS TRANSLATION",
|
||||
"Create Character": "NEEDS TRANSLATION",
|
||||
"Delete Character": "NEEDS TRANSLATION",
|
||||
"View all tags": "NEEDS TRANSLATION",
|
||||
"Click to set additional greeting messages": "NEEDS TRANSLATION",
|
||||
"Show / Hide Description and First Message": "NEEDS TRANSLATION",
|
||||
"Click to select a new avatar for this group": "NEEDS TRANSLATION",
|
||||
"Set a group chat scenario": "NEEDS TRANSLATION",
|
||||
"Restore collage avatar": "NEEDS TRANSLATION",
|
||||
"Create New Character": "NEEDS TRANSLATION",
|
||||
"Import Character from File": "NEEDS TRANSLATION",
|
||||
"Import content from external URL": "NEEDS TRANSLATION",
|
||||
"Create New Chat Group": "NEEDS TRANSLATION",
|
||||
"Characters sorting order": "NEEDS TRANSLATION",
|
||||
"Add chat injection": "NEEDS TRANSLATION",
|
||||
"Remove injection": "NEEDS TRANSLATION",
|
||||
"Remove": "NEEDS TRANSLATION",
|
||||
"Select a World Info file for": "NEEDS TRANSLATION",
|
||||
"Primary Lorebook": "NEEDS TRANSLATION",
|
||||
"A selected World Info will be bound to this character as its own Lorebook.": "NEEDS TRANSLATION",
|
||||
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "NEEDS TRANSLATION",
|
||||
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "NEEDS TRANSLATION",
|
||||
"Additional Lorebooks": "NEEDS TRANSLATION",
|
||||
"Associate one or more auxillary Lorebooks with this character.": "NEEDS TRANSLATION",
|
||||
"NOTE: These choices are optional and won't be preserved on character export!": "NEEDS TRANSLATION",
|
||||
"Rename chat file": "NEEDS TRANSLATION",
|
||||
"Export JSONL chat file": "NEEDS TRANSLATION",
|
||||
"Download chat as plain text document": "NEEDS TRANSLATION",
|
||||
"Delete chat file": "NEEDS TRANSLATION",
|
||||
"Delete tag": "NEEDS TRANSLATION",
|
||||
"Translate message": "NEEDS TRANSLATION",
|
||||
"Generate Image": "NEEDS TRANSLATION",
|
||||
"Narrate": "NEEDS TRANSLATION",
|
||||
"Prompt": "NEEDS TRANSLATION",
|
||||
"Create Bookmark": "NEEDS TRANSLATION",
|
||||
"Copy": "NEEDS TRANSLATION",
|
||||
"Open bookmark chat": "NEEDS TRANSLATION",
|
||||
"Confirm": "NEEDS TRANSLATION",
|
||||
"Copy this message": "NEEDS TRANSLATION",
|
||||
"Delete this message": "NEEDS TRANSLATION",
|
||||
"Move message up": "NEEDS TRANSLATION",
|
||||
"Move message down": "NEEDS TRANSLATION",
|
||||
"Enlarge": "NEEDS TRANSLATION",
|
||||
"Temporarily disable automatic replies from this character": "NEEDS TRANSLATION",
|
||||
"Enable automatic replies from this character": "NEEDS TRANSLATION",
|
||||
"Trigger a message from this character": "NEEDS TRANSLATION",
|
||||
"Move up": "NEEDS TRANSLATION",
|
||||
"Move down": "NEEDS TRANSLATION",
|
||||
"View character card": "NEEDS TRANSLATION",
|
||||
"Remove from group": "NEEDS TRANSLATION",
|
||||
"Add to group": "NEEDS TRANSLATION",
|
||||
"Add": "NEEDS TRANSLATION",
|
||||
"Abort request": "NEEDS TRANSLATION",
|
||||
"Send a message": "NEEDS TRANSLATION",
|
||||
"Ask AI to write your message for you": "NEEDS TRANSLATION",
|
||||
"Continue the last message": "NEEDS TRANSLATION",
|
||||
"Bind user name to that avatar": "NEEDS TRANSLATION",
|
||||
"Select this as default persona for the new chats.": "NEEDS TRANSLATION",
|
||||
"Change persona image": "NEEDS TRANSLATION",
|
||||
"Delete persona": "NEEDS TRANSLATION"
|
||||
},
|
||||
"ja-jp": {
|
||||
"clickslidertips": "スライダーの右側の数字をクリックすると手動で入力できます。",
|
||||
@@ -503,7 +789,6 @@
|
||||
"Auto-save Message Edits": "メッセージの編集を自動保存",
|
||||
"Auto-fix Markdown": "Markdownを自動修正",
|
||||
"Allow : in bot messages": "ボットメッセージで「:」を許可する",
|
||||
"Allow : in bot messages": "ボットメッセージで「:」を許可する",
|
||||
"Auto-scroll Chat": "チャット自動スクロール",
|
||||
"Render Formulas": "数式のレンダリング",
|
||||
"Send on Enter": "エンター入力で送信",
|
||||
@@ -581,7 +866,293 @@
|
||||
"WEBP": "WEBP",
|
||||
"presets": "プリセット",
|
||||
"Message Sound": "メッセージ音",
|
||||
"Author's Note": "作者の注記"
|
||||
"Author's Note": "作者の注記",
|
||||
"Send Jailbreak": "NEEDS TRANSLATION",
|
||||
"Replace empty message": "NEEDS TRANSLATION",
|
||||
"Send this text instead of nothing when the text box is empty.": "NEEDS TRANSLATION",
|
||||
"NSFW avoidance prompt": "NEEDS TRANSLATION",
|
||||
"Prompt that is used when the NSFW toggle is off": "NEEDS TRANSLATION",
|
||||
"Advanced prompt bits": "NEEDS TRANSLATION",
|
||||
"World Info format template": "NEEDS TRANSLATION",
|
||||
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "NEEDS TRANSLATION",
|
||||
"Unrestricted maximum value for the context slider": "NEEDS TRANSLATION",
|
||||
"Chat Completion Source": "NEEDS TRANSLATION",
|
||||
"Avoid sending sensitive information to the Horde.": "NEEDS TRANSLATION",
|
||||
"Review the Privacy statement": "NEEDS TRANSLATION",
|
||||
"Learn how to contribute your idel GPU cycles to the Horde": "NEEDS TRANSLATION",
|
||||
"Trusted workers only": "NEEDS TRANSLATION",
|
||||
"For privacy reasons, your API key will be hidden after you reload the page.": "NEEDS TRANSLATION",
|
||||
"-- Horde models not loaded --": "NEEDS TRANSLATION",
|
||||
"Example: http://127.0.0.1:5000/api ": "NEEDS TRANSLATION",
|
||||
"No connection...": "NEEDS TRANSLATION",
|
||||
"Get your NovelAI API Key": "NEEDS TRANSLATION",
|
||||
"KoboldAI Horde": "NEEDS TRANSLATION",
|
||||
"Text Gen WebUI (ooba)": "NEEDS TRANSLATION",
|
||||
"NovelAI": "NEEDS TRANSLATION",
|
||||
"Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale)": "NEEDS TRANSLATION",
|
||||
"OpenAI API key": "NEEDS TRANSLATION",
|
||||
"Trim spaces": "NEEDS TRANSLATION",
|
||||
"Trim Incomplete Sentences": "NEEDS TRANSLATION",
|
||||
"Include Newline": "NEEDS TRANSLATION",
|
||||
"Non-markdown strings": "NEEDS TRANSLATION",
|
||||
"Replace Macro in Sequences": "NEEDS TRANSLATION",
|
||||
"Presets": "NEEDS TRANSLATION",
|
||||
"Separator": "NEEDS TRANSLATION",
|
||||
"Start Reply With": "NEEDS TRANSLATION",
|
||||
"Show reply prefix in chat": "NEEDS TRANSLATION",
|
||||
"Worlds/Lorebooks": "NEEDS TRANSLATION",
|
||||
"Active World(s)": "NEEDS TRANSLATION",
|
||||
"Character Lore Insertion Strategy": "NEEDS TRANSLATION",
|
||||
"Sorted Evenly": "NEEDS TRANSLATION",
|
||||
"Character Lore First": "NEEDS TRANSLATION",
|
||||
"Global Lore First": "NEEDS TRANSLATION",
|
||||
"-- World Info not found --": "NEEDS TRANSLATION",
|
||||
"Recursive Scan": "NEEDS TRANSLATION",
|
||||
"Case Sensitive": "NEEDS TRANSLATION",
|
||||
"Match whole words": "NEEDS TRANSLATION",
|
||||
"World/Lore Editor": "NEEDS TRANSLATION",
|
||||
"--- None ---": "NEEDS TRANSLATION",
|
||||
"Comma seperated (ignored if empty)": "NEEDS TRANSLATION",
|
||||
"Use Probability": "NEEDS TRANSLATION",
|
||||
"Exclude from recursion": "NEEDS TRANSLATION",
|
||||
"Position:": "NEEDS TRANSLATION",
|
||||
"Before Char Defs": "NEEDS TRANSLATION",
|
||||
"After Char Defs": "NEEDS TRANSLATION",
|
||||
"Before AN": "NEEDS TRANSLATION",
|
||||
"After AN": "NEEDS TRANSLATION",
|
||||
"Order:": "NEEDS TRANSLATION",
|
||||
"Probability:": "NEEDS TRANSLATION",
|
||||
"Delete Entry": "NEEDS TRANSLATION",
|
||||
"User Message Blur Tint": "NEEDS TRANSLATION",
|
||||
"AI Message Blur Tint": "NEEDS TRANSLATION",
|
||||
"Chat Style:": "NEEDS TRANSLATION",
|
||||
"Chat Width (PC):": "NEEDS TRANSLATION",
|
||||
"Chat Timestamps": "NEEDS TRANSLATION",
|
||||
"Message IDs": "NEEDS TRANSLATION",
|
||||
"Prefer Character Card Prompt": "NEEDS TRANSLATION",
|
||||
"Prefer Character Card Jailbreak": "NEEDS TRANSLATION",
|
||||
"Press Send to continue": "NEEDS TRANSLATION",
|
||||
"Log prompts to console": "NEEDS TRANSLATION",
|
||||
"Never resize avatars": "NEEDS TRANSLATION",
|
||||
"Show avatar filenames": "NEEDS TRANSLATION",
|
||||
"Import Card Tags": "NEEDS TRANSLATION",
|
||||
"Confirm message deletion": "NEEDS TRANSLATION",
|
||||
"Spoiler Free Mode": "NEEDS TRANSLATION",
|
||||
"Auto-swipe": "NEEDS TRANSLATION",
|
||||
"Minimum generated message length": "NEEDS TRANSLATION",
|
||||
"Blacklisted words": "NEEDS TRANSLATION",
|
||||
"Blacklisted word count to swipe": "NEEDS TRANSLATION",
|
||||
"Reload Chat": "NEEDS TRANSLATION",
|
||||
"Not Connected": "NEEDS TRANSLATION",
|
||||
"Persona Management": "NEEDS TRANSLATION",
|
||||
"Persona Description": "NEEDS TRANSLATION",
|
||||
"Before Character Card": "NEEDS TRANSLATION",
|
||||
"After Character Card": "NEEDS TRANSLATION",
|
||||
"Top of Author's Note": "NEEDS TRANSLATION",
|
||||
"Bottom of Author's Note": "NEEDS TRANSLATION",
|
||||
"How do I use this?": "NEEDS TRANSLATION",
|
||||
"More...": "NEEDS TRANSLATION",
|
||||
"Link to World Info": "NEEDS TRANSLATION",
|
||||
"Import Card Lore": "NEEDS TRANSLATION",
|
||||
"Scenario Override": "NEEDS TRANSLATION",
|
||||
"Rename": "NEEDS TRANSLATION",
|
||||
"Character Description": "NEEDS TRANSLATION",
|
||||
"Creator's Notes": "NEEDS TRANSLATION",
|
||||
"A-Z": "NEEDS TRANSLATION",
|
||||
"Z-A": "NEEDS TRANSLATION",
|
||||
"Newest": "NEEDS TRANSLATION",
|
||||
"Oldest": "NEEDS TRANSLATION",
|
||||
"Favorites": "NEEDS TRANSLATION",
|
||||
"Recent": "NEEDS TRANSLATION",
|
||||
"Most chats": "NEEDS TRANSLATION",
|
||||
"Least chats": "NEEDS TRANSLATION",
|
||||
"Back": "NEEDS TRANSLATION",
|
||||
"Prompt Overrides (For OpenAI/Claude/Scale APIs, Window/OpenRouter, Poe, and Instruct mode)": "NEEDS TRANSLATION",
|
||||
"Insert {{original}} into either box to include the respective default prompt from system settings.": "NEEDS TRANSLATION",
|
||||
"Main Prompt": "NEEDS TRANSLATION",
|
||||
"Jailbreak": "NEEDS TRANSLATION",
|
||||
"Creator's Metadata (Not sent with the AI prompt)": "NEEDS TRANSLATION",
|
||||
"Everything here is optional": "NEEDS TRANSLATION",
|
||||
"Created by": "NEEDS TRANSLATION",
|
||||
"Character Version": "NEEDS TRANSLATION",
|
||||
"Tags to Embed": "NEEDS TRANSLATION",
|
||||
"How often the character speaks in group chats!": "NEEDS TRANSLATION",
|
||||
"Important to set the character's writing style.": "NEEDS TRANSLATION",
|
||||
"ATTENTION!": "NEEDS TRANSLATION",
|
||||
"Samplers Order": "NEEDS TRANSLATION",
|
||||
"Samplers will be applied in a top-down order. Use with caution.": "NEEDS TRANSLATION",
|
||||
"Repetition Penalty": "NEEDS TRANSLATION",
|
||||
"Epsilon Cutoff": "NEEDS TRANSLATION",
|
||||
"Eta Cutoff": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Range.": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Freq.": "NEEDS TRANSLATION",
|
||||
"Rep. Pen. Presence": "NEEDS TRANSLATION",
|
||||
"Follow_poe": "NEEDS TRANSLATION",
|
||||
"Enter it in the box below:": "NEEDS TRANSLATION",
|
||||
"separate with commas w/o space between": "NEEDS TRANSLATION",
|
||||
"Document": "NEEDS TRANSLATION",
|
||||
"Suggest replies": "NEEDS TRANSLATION",
|
||||
"Show suggested replies. Not all bots support this.": "NEEDS TRANSLATION",
|
||||
"Use 'Unlocked Context' to enable chunked generation.": "NEEDS TRANSLATION",
|
||||
"It extends the context window in exchange for reply generation speed.": "NEEDS TRANSLATION",
|
||||
"Safe Context Size values for Poe bots:": "NEEDS TRANSLATION",
|
||||
"ChatGPT / Sage = 3600-4000 tokens": "NEEDS TRANSLATION",
|
||||
"Claude-instant / Claude+ = 5000-5500 tokens": "NEEDS TRANSLATION",
|
||||
"GPT-4 = 7600-8000": "NEEDS TRANSLATION",
|
||||
"Purge Poe Chat": "NEEDS TRANSLATION",
|
||||
"Continue": "NEEDS TRANSLATION",
|
||||
"Editing:": "NEEDS TRANSLATION",
|
||||
"AI reply prefix": "NEEDS TRANSLATION",
|
||||
"Custom Stopping Strings": "NEEDS TRANSLATION",
|
||||
"JSON serialized array of strings": "NEEDS TRANSLATION",
|
||||
"words you dont want generated separated by comma ','": "NEEDS TRANSLATION",
|
||||
"Extensions URL": "NEEDS TRANSLATION",
|
||||
"API Key": "NEEDS TRANSLATION",
|
||||
"Enter your name": "NEEDS TRANSLATION",
|
||||
"Name this character": "NEEDS TRANSLATION",
|
||||
"Search / Create Tags": "NEEDS TRANSLATION",
|
||||
"Describe your character's physical and mental traits here.": "NEEDS TRANSLATION",
|
||||
"This will be the first message from the character that starts every chat.": "NEEDS TRANSLATION",
|
||||
"Chat Name (Optional)": "NEEDS TRANSLATION",
|
||||
"Filter...": "NEEDS TRANSLATION",
|
||||
"Search...": "NEEDS TRANSLATION",
|
||||
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "NEEDS TRANSLATION",
|
||||
"Any contents here will replace the default Jailbreak Prompt (Character Note for Poe) used for this character. (v2 spec: post_history_instructions)": "NEEDS TRANSLATION",
|
||||
"(Botmaker's name / Contact Info)": "NEEDS TRANSLATION",
|
||||
"(If you want to track character versions)": "NEEDS TRANSLATION",
|
||||
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "NEEDS TRANSLATION",
|
||||
"(Write a comma-separated list of tags)": "NEEDS TRANSLATION",
|
||||
"(A brief description of the personality)": "NEEDS TRANSLATION",
|
||||
"(Circumstances and context of the interaction)": "NEEDS TRANSLATION",
|
||||
"(Examples of chat dialog. Begin each example with START on a new line.)": "NEEDS TRANSLATION",
|
||||
"Injection text (supports parameters)": "NEEDS TRANSLATION",
|
||||
"Injection depth": "NEEDS TRANSLATION",
|
||||
"Type here...": "NEEDS TRANSLATION",
|
||||
"Comma separated (required)": "NEEDS TRANSLATION",
|
||||
"Comma separated (ignored if empty)": "NEEDS TRANSLATION",
|
||||
"What this keyword should mean to the AI, sent verbatim": "NEEDS TRANSLATION",
|
||||
"Not sent to the AI": "NEEDS TRANSLATION",
|
||||
"(This will be the first message from the character that starts every chat)": "NEEDS TRANSLATION",
|
||||
"Not connected to API!": "NEEDS TRANSLATION",
|
||||
"AI Response Configuration": "NEEDS TRANSLATION",
|
||||
"AI Configuration panel will stay open": "NEEDS TRANSLATION",
|
||||
"Update current preset": "NEEDS TRANSLATION",
|
||||
"Create new preset": "NEEDS TRANSLATION",
|
||||
"Import preset": "NEEDS TRANSLATION",
|
||||
"Export preset": "NEEDS TRANSLATION",
|
||||
"Delete the preset": "NEEDS TRANSLATION",
|
||||
"Attempts to automatically jailbreak the bot": "NEEDS TRANSLATION",
|
||||
"Purges the chat history on Poe site": "NEEDS TRANSLATION",
|
||||
"Inserts jailbreak as a last system message": "NEEDS TRANSLATION",
|
||||
"NSFW block goes first in the resulting prompt": "NEEDS TRANSLATION",
|
||||
"Enables OpenAI completion streaming": "NEEDS TRANSLATION",
|
||||
"Wrap user messages in quotes before sending": "NEEDS TRANSLATION",
|
||||
"Restore default prompt": "NEEDS TRANSLATION",
|
||||
"New preset": "NEEDS TRANSLATION",
|
||||
"Delete preset": "NEEDS TRANSLATION",
|
||||
"Restore default jailbreak": "NEEDS TRANSLATION",
|
||||
"Restore default reply": "NEEDS TRANSLATION",
|
||||
"Restore defaul note": "NEEDS TRANSLATION",
|
||||
"API Connections": "NEEDS TRANSLATION",
|
||||
"Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "NEEDS TRANSLATION",
|
||||
"Clear your API key": "NEEDS TRANSLATION",
|
||||
"Refresh models": "NEEDS TRANSLATION",
|
||||
"Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "NEEDS TRANSLATION",
|
||||
"Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "NEEDS TRANSLATION",
|
||||
"Create New": "NEEDS TRANSLATION",
|
||||
"Edit": "NEEDS TRANSLATION",
|
||||
"World Info & Soft Prompts": "NEEDS TRANSLATION",
|
||||
"Locked = World Editor will stay open": "NEEDS TRANSLATION",
|
||||
"Entries can activate other entries by mentioning their keywords": "NEEDS TRANSLATION",
|
||||
"Lookup for the entry keys in the context will respect the case": "NEEDS TRANSLATION",
|
||||
"If the entry key consists of only one word, it would not be matched as part of other words": "NEEDS TRANSLATION",
|
||||
"Open all Entries": "NEEDS TRANSLATION",
|
||||
"Close all Entries": "NEEDS TRANSLATION",
|
||||
"Create": "NEEDS TRANSLATION",
|
||||
"Import World Info": "NEEDS TRANSLATION",
|
||||
"Export World Info": "NEEDS TRANSLATION",
|
||||
"Delete World Info": "NEEDS TRANSLATION",
|
||||
"Rename World Info": "NEEDS TRANSLATION",
|
||||
"Save changes to a new theme file": "NEEDS TRANSLATION",
|
||||
"removes blur and uses alternative background color for divs": "NEEDS TRANSLATION",
|
||||
"If checked and the character card contains a prompt override (System Prompt), use that instead.": "NEEDS TRANSLATION",
|
||||
"If checked and the character card contains a jailbreak override (Post History Instruction), use that instead.": "NEEDS TRANSLATION",
|
||||
"AI Response Formatting": "NEEDS TRANSLATION",
|
||||
"Change Background Image": "NEEDS TRANSLATION",
|
||||
"Extensions": "NEEDS TRANSLATION",
|
||||
"Click to set a new User Name": "NEEDS TRANSLATION",
|
||||
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "NEEDS TRANSLATION",
|
||||
"Click to set user name for all messages": "NEEDS TRANSLATION",
|
||||
"Create a dummy persona": "NEEDS TRANSLATION",
|
||||
"Character Management": "NEEDS TRANSLATION",
|
||||
"Locked = Character Management panel will stay open": "NEEDS TRANSLATION",
|
||||
"Select/Create Characters": "NEEDS TRANSLATION",
|
||||
"Token counts may be inaccurate and provided just for reference.": "NEEDS TRANSLATION",
|
||||
"Click to select a new avatar for this character": "NEEDS TRANSLATION",
|
||||
"Add to Favorites": "NEEDS TRANSLATION",
|
||||
"Advanced Definition": "NEEDS TRANSLATION",
|
||||
"Character Lore": "NEEDS TRANSLATION",
|
||||
"Export and Download": "NEEDS TRANSLATION",
|
||||
"Duplicate Character": "NEEDS TRANSLATION",
|
||||
"Create Character": "NEEDS TRANSLATION",
|
||||
"Delete Character": "NEEDS TRANSLATION",
|
||||
"View all tags": "NEEDS TRANSLATION",
|
||||
"Click to set additional greeting messages": "NEEDS TRANSLATION",
|
||||
"Show / Hide Description and First Message": "NEEDS TRANSLATION",
|
||||
"Click to select a new avatar for this group": "NEEDS TRANSLATION",
|
||||
"Set a group chat scenario": "NEEDS TRANSLATION",
|
||||
"Restore collage avatar": "NEEDS TRANSLATION",
|
||||
"Create New Character": "NEEDS TRANSLATION",
|
||||
"Import Character from File": "NEEDS TRANSLATION",
|
||||
"Import content from external URL": "NEEDS TRANSLATION",
|
||||
"Create New Chat Group": "NEEDS TRANSLATION",
|
||||
"Characters sorting order": "NEEDS TRANSLATION",
|
||||
"Add chat injection": "NEEDS TRANSLATION",
|
||||
"Remove injection": "NEEDS TRANSLATION",
|
||||
"Remove": "NEEDS TRANSLATION",
|
||||
"Select a World Info file for": "NEEDS TRANSLATION",
|
||||
"Primary Lorebook": "NEEDS TRANSLATION",
|
||||
"A selected World Info will be bound to this character as its own Lorebook.": "NEEDS TRANSLATION",
|
||||
"When generating an AI reply, it will be combined with the entries from a global World Info selector.": "NEEDS TRANSLATION",
|
||||
"Exporting a character would also export the selected Lorebook file embedded in the JSON data.": "NEEDS TRANSLATION",
|
||||
"Additional Lorebooks": "NEEDS TRANSLATION",
|
||||
"Associate one or more auxillary Lorebooks with this character.": "NEEDS TRANSLATION",
|
||||
"NOTE: These choices are optional and won't be preserved on character export!": "NEEDS TRANSLATION",
|
||||
"Rename chat file": "NEEDS TRANSLATION",
|
||||
"Export JSONL chat file": "NEEDS TRANSLATION",
|
||||
"Download chat as plain text document": "NEEDS TRANSLATION",
|
||||
"Delete chat file": "NEEDS TRANSLATION",
|
||||
"Delete tag": "NEEDS TRANSLATION",
|
||||
"Translate message": "NEEDS TRANSLATION",
|
||||
"Generate Image": "NEEDS TRANSLATION",
|
||||
"Narrate": "NEEDS TRANSLATION",
|
||||
"Prompt": "NEEDS TRANSLATION",
|
||||
"Create Bookmark": "NEEDS TRANSLATION",
|
||||
"Copy": "NEEDS TRANSLATION",
|
||||
"Open bookmark chat": "NEEDS TRANSLATION",
|
||||
"Confirm": "NEEDS TRANSLATION",
|
||||
"Copy this message": "NEEDS TRANSLATION",
|
||||
"Delete this message": "NEEDS TRANSLATION",
|
||||
"Move message up": "NEEDS TRANSLATION",
|
||||
"Move message down": "NEEDS TRANSLATION",
|
||||
"Enlarge": "NEEDS TRANSLATION",
|
||||
"Temporarily disable automatic replies from this character": "NEEDS TRANSLATION",
|
||||
"Enable automatic replies from this character": "NEEDS TRANSLATION",
|
||||
"Trigger a message from this character": "NEEDS TRANSLATION",
|
||||
"Move up": "NEEDS TRANSLATION",
|
||||
"Move down": "NEEDS TRANSLATION",
|
||||
"View character card": "NEEDS TRANSLATION",
|
||||
"Remove from group": "NEEDS TRANSLATION",
|
||||
"Add to group": "NEEDS TRANSLATION",
|
||||
"Add": "NEEDS TRANSLATION",
|
||||
"Abort request": "NEEDS TRANSLATION",
|
||||
"Send a message": "NEEDS TRANSLATION",
|
||||
"Ask AI to write your message for you": "NEEDS TRANSLATION",
|
||||
"Continue the last message": "NEEDS TRANSLATION",
|
||||
"Bind user name to that avatar": "NEEDS TRANSLATION",
|
||||
"Select this as default persona for the new chats.": "NEEDS TRANSLATION",
|
||||
"Change persona image": "NEEDS TRANSLATION",
|
||||
"Delete persona": "NEEDS TRANSLATION"
|
||||
},
|
||||
"ko-kr": {
|
||||
"clickslidertips": "슬라이더의 오른쪽 숫자를 클릭하면 직접 입력할 수 있습니다.",
|
||||
@@ -1160,4 +1731,4 @@
|
||||
"Change persona image": "주인공 아바타 바꾸기",
|
||||
"Delete persona": "주인공 삭제하기"
|
||||
}
|
||||
}
|
||||
}
|
@@ -93,6 +93,7 @@
|
||||
<script type="module" src="scripts/secrets.js"></script>
|
||||
<script type="module" src="scripts/context-template.js"></script>
|
||||
<script type="module" src="scripts/extensions.js"></script>
|
||||
<script type="module" src="scripts/authors-note.js"></script>
|
||||
<script type="text/javascript" src="scripts/toolcool-color-picker.js"></script>
|
||||
|
||||
<title>SillyTavern</title>
|
||||
@@ -1033,6 +1034,54 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<h4 data-i18n="Mirostat (mode=1 is only for llama.cpp)">Mirostat (mode=1 is only for llama.cpp)</h4>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title" data-i18n="Mirostat Mode">
|
||||
Mirostat Mode
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="mirostat_mode_textgenerationwebui" name="volume" min="0" max="2" step="1" />
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div contenteditable="true" data-for="mirostat_mode_textgenerationwebui" id="mirostat_mode_counter_textgenerationwebui">
|
||||
select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title" data-i18n="Mirostat Tau">
|
||||
Mirostat Tau
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="mirostat_tau_textgenerationwebui" name="volume" min="0" max="10" step="0.01" />
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div contenteditable="true" data-for="mirostat_tau_textgenerationwebui" id="mirostat_tau_counter_textgenerationwebui">
|
||||
select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title" data-i18n="Mirostat Eta">
|
||||
Mirostat Eta
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="mirostat_eta_textgenerationwebui" name="volume" min="0" max="1" step="0.01" />
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div contenteditable="true" data-for="mirostat_eta_textgenerationwebui" id="mirostat_eta_counter_textgenerationwebui">
|
||||
select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title" data-i18n="Seed">
|
||||
Seed
|
||||
@@ -2246,12 +2295,42 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="MovingUI-presets-block" class="flex-container flexFlowColumn">
|
||||
<h4>
|
||||
<span data-i18n="MovingUI Preset">MovingUI Preset</span>
|
||||
</h4>
|
||||
<div class="flex-container flexnowrap alignitemscenter">
|
||||
<select id="movingUIPresets" class="margin0 margin-r5">
|
||||
</select>
|
||||
<div id="movingui-preset-save-button" title="Save changes to a new MovingUI preset file" data-i18n="[title]Save movingUI changes to a new file" class="menu_button padding5 margin0">
|
||||
<i class="fa-solid fa-save"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div id="movingUIreset" class="menu_button whitespacenowrap" data-i18n="Reset Panels">
|
||||
Reset MovingUI
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div name="UI Customization" class="flex-container drawer33pWidth">
|
||||
<div class="ui-settings">
|
||||
<h4><span data-i18n="UI Customization">UI Customization</span></h4>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title" data-i18n="Chat Width (PC)">
|
||||
Chat Width (PC)
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range">
|
||||
<input id="chat_width_slider" class="wide100p" type="range" min="25" max="75" step="1" value="50">
|
||||
<div class="slider_hint">
|
||||
<span>25%</span>
|
||||
<span>50%</span>
|
||||
<span>75%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span data-i18n="Avatar Style">Avatar Style:</span><br>
|
||||
<label>
|
||||
@@ -2271,17 +2350,6 @@
|
||||
<option value="2" data-i18n="Document">Single Document</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- <div id="sheldWidthToggleBlock">
|
||||
<span data-i18n="Chat Width (PC):">Chat Width (PC):</span><br>
|
||||
<label>
|
||||
<input name="sheld_width" type="radio" value="0" />
|
||||
800px
|
||||
</label>
|
||||
<label>
|
||||
<input name="sheld_width" type="radio" value="1" />
|
||||
1000px
|
||||
</label>
|
||||
</div> -->
|
||||
<div>
|
||||
<label for="play_message_sound" class="checkbox_label">
|
||||
<input id="play_message_sound" type="checkbox" />
|
||||
@@ -2351,8 +2419,7 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="movingUIreset" class="menu_button whitespacenowrap" data-i18n="Reset Panels">
|
||||
Reset Panels</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2864,6 +2931,7 @@
|
||||
<option data-field="date_last_chat" data-order="desc" data-i18n="Recent">Recent</option>
|
||||
<option data-field="chat_size" data-order="desc" data-i18n="Most chats">Most chats</option>
|
||||
<option data-field="chat_size" data-order="asc" data-i18n="Least chats">Least chats</option>
|
||||
<option data-field="name" data-order="random" data-i18n="Random">Random</option>
|
||||
</select>
|
||||
</form>
|
||||
<div class="rm_tag_controls">
|
||||
@@ -2995,7 +3063,7 @@
|
||||
<h5 data-i18n="How often the character speaks in group chats!">How often the character speaks in <span class="warning">group chats!</span>
|
||||
</h5>
|
||||
<input id="talkativeness_slider" name="talkativeness" type="range" min="0" max="1" step="0.05" value="0.5" form="form_create">
|
||||
<div id="talkativeness_hint">
|
||||
<div class="slider_hint">
|
||||
<span data-i18n="Shy">Shy</span>
|
||||
<span data-i18n="Normal">Normal</span>
|
||||
<span data-i18n="Chatty">Chatty</span>
|
||||
@@ -3041,6 +3109,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="background_template" class="template_element">
|
||||
<div class="bg_example flex-container" bgfile="" class="bg_example_img" title="">
|
||||
<div title="Rename background" bgfile="" class="bg_button bg_example_edit fa-solid fa-pencil"></div>
|
||||
<div title="Delete background" bgfile="" class="bg_button bg_example_cross fa-solid fa-circle-xmark"></div>
|
||||
<div class="BGSampleTitle">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- templates for JS to reuse when needed -->
|
||||
<div id="context_editor_template" class="template_element">
|
||||
<div class="context_editor">
|
||||
@@ -3434,7 +3511,7 @@
|
||||
<div class="mes_edit_buttons">
|
||||
<div class="mes_edit_done menu_button fa-solid fa-check" title="Confirm" data-i18n="[title]Confirm"></div>
|
||||
<div class="mes_edit_copy menu_button fa-solid fa-copy" title="Copy this message" data-i18n="[title]Copy this message"></div>
|
||||
<div class="mes_edit_delete menu_button fa-solid fa-scissors" title="Delete this message" data-i18n="[title]Delete this message">
|
||||
<div class="mes_edit_delete menu_button fa-solid fa-trash-can" title="Delete this message" data-i18n="[title]Delete this message">
|
||||
</div>
|
||||
<div class="mes_edit_up menu_button fa-solid fa-chevron-up " title="Move message up" data-i18n="[title]Move message up"></div>
|
||||
<div class="mes_edit_down menu_button fa-solid fa-chevron-down" title="Move message down" data-i18n="[title]Move message down">
|
||||
@@ -3556,7 +3633,101 @@
|
||||
<div id="typing_indicator_template" class="template_element">
|
||||
<div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div>
|
||||
</div>
|
||||
<div id="movingDivs"></div>
|
||||
<div id="movingDivs">
|
||||
<div id="floatingPrompt" class="drawer-content flexGap5">
|
||||
<div class="panelControlBar flex-container">
|
||||
<div id="floatingPromptheader" class="fa-solid fa-grip drag-grabber"></div>
|
||||
<div id="ANClose" class="fa-solid fa-circle-xmark"></div>
|
||||
</div>
|
||||
<div name="floatingPromptHolder">
|
||||
<div class="inline-drawer">
|
||||
<div id="ANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>
|
||||
<b>Unique to this chat</b>.<br>
|
||||
Bookmarks inherit the Note from their parent, and can be changed individually after that.<br>
|
||||
</small>
|
||||
<textarea id="extension_floating_prompt" class="text_pole" rows="8" maxlength="10000"></textarea>
|
||||
<div class="extension_token_counter">
|
||||
Tokens: <span id="extension_floating_prompt_token_counter">0</span>
|
||||
</div>
|
||||
|
||||
<div class="floating_prompt_radio_group">
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_position" value="0" />
|
||||
After scenario
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_position" value="1" />
|
||||
In-chat @ Depth <input id="extension_floating_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
|
||||
</label>
|
||||
</div>
|
||||
<!--<label for="extension_floating_interval">In-Chat Insertion Depth</label>-->
|
||||
|
||||
<label for="extension_floating_interval">Insertion Frequency</label>
|
||||
|
||||
<input id="extension_floating_interval" class="text_pole widthUnset" type="number" min="0" max="999" /><small> (0 = Disable, 1 = Always)</small>
|
||||
<br>
|
||||
|
||||
<span>User inputs until next insertion: <span id="extension_floating_counter">(disabled)</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="sysHR">
|
||||
<div class="inline-drawer">
|
||||
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Character Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be automatically added as the author's note for this character. Will be used in groups, but
|
||||
can't be modified when a group chat is open.</small>
|
||||
|
||||
<textarea id="extension_floating_chara" class="text_pole" rows="8" maxlength="10000" placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||
<div class="extension_token_counter">
|
||||
Tokens: <span id="extension_floating_chara_token_counter">0</span>
|
||||
</div>
|
||||
|
||||
<label class="checkbox_label" for="extension_use_floating_chara">
|
||||
<input id="extension_use_floating_chara" type="checkbox" />
|
||||
<span data-i18n="Use character author's note">Use character author's note</span>
|
||||
</label>
|
||||
<div class="floating_prompt_radio_group">
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="0" />
|
||||
Replace Author's Note
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="1" />
|
||||
Top of Author's Note
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="2" />
|
||||
Bottom of Author's Note
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="sysHR">
|
||||
<div class="inline-drawer">
|
||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Default Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be automatically added as the Author's Note for all new chats.</small>
|
||||
|
||||
<textarea id="extension_floating_default" class="text_pole" rows="8" maxlength="10000" placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||
<div class="extension_token_counter">
|
||||
Tokens: <span id="extension_floating_default_token_counter">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sheld">
|
||||
<div id="sheldheader" class="fa-solid fa-grip drag-grabber"></div>
|
||||
<div id="chat">
|
||||
@@ -3582,6 +3753,10 @@
|
||||
<!-- popups live outside sheld to avoid blur conflicts -->
|
||||
<div id="options" class="font-family-reset" style="display: none;">
|
||||
<div class="options-content">
|
||||
<a id="option_toggle_AN">
|
||||
<i class="fa-lg fa-solid fa-note-sticky"></i>
|
||||
<span data-i18n="Author's Note">Author's Note</span>
|
||||
</a>
|
||||
<a id="option_back_to_main">
|
||||
<i class="fa-lg fa-solid fa-left-long"></i>
|
||||
<span data-i18n="Back to parent chat">Back to parent chat</span>
|
||||
|
45
public/movingUI/Black Magic Time.json
Normal file
45
public/movingUI/Black Magic Time.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "Black Magic Time",
|
||||
"movingUIState": {
|
||||
"sheld": {
|
||||
"top": 488,
|
||||
"left": 1407,
|
||||
"right": 1,
|
||||
"bottom": 4,
|
||||
"margin": "unset",
|
||||
"width": 471,
|
||||
"height": 439
|
||||
},
|
||||
"floatingPrompt": {
|
||||
"width": 369,
|
||||
"height": 441
|
||||
},
|
||||
"right-nav-panel": {
|
||||
"top": 0,
|
||||
"left": 1400,
|
||||
"right": 111,
|
||||
"bottom": 446,
|
||||
"margin": "unset",
|
||||
"width": 479,
|
||||
"height": 487
|
||||
},
|
||||
"WorldInfo": {
|
||||
"top": 41,
|
||||
"left": 369,
|
||||
"right": 642,
|
||||
"bottom": 51,
|
||||
"margin": "unset",
|
||||
"width": 1034,
|
||||
"height": 858
|
||||
},
|
||||
"left-nav-panel": {
|
||||
"top": 442,
|
||||
"left": 0,
|
||||
"right": 1546,
|
||||
"bottom": 25,
|
||||
"margin": "unset",
|
||||
"width": 368,
|
||||
"height": 483
|
||||
}
|
||||
}
|
||||
}
|
4
public/movingUI/Default.json
Normal file
4
public/movingUI/Default.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Default",
|
||||
"movingUIState": {}
|
||||
}
|
179
public/script.js
179
public/script.js
@@ -166,7 +166,7 @@ import {
|
||||
import { EventEmitter } from './scripts/eventemitter.js';
|
||||
import { context_settings, loadContextTemplatesFromSettings } from "./scripts/context-template.js";
|
||||
import { markdownExclusionExt } from "./scripts/showdown-exclusion.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/extensions/floating-prompt/index.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/authors-note.js";
|
||||
import { deviceInfo } from "./scripts/RossAscends-mods.js";
|
||||
import { getRegexedString, regex_placement } from "./scripts/extensions/regex/engine.js";
|
||||
|
||||
@@ -365,7 +365,7 @@ const system_messages = {
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
mes:
|
||||
`Hello there! Please select the help topic you would like to learn more about:
|
||||
<ul>
|
||||
<li><a href="javascript:displayHelp('1')">Slash Commands</a> (or <tt>/help slash</tt>)</li>
|
||||
@@ -374,7 +374,6 @@ const system_messages = {
|
||||
<li><a href="javascript:displayHelp('4')">{{Macros}}</a> (or <tt>/help macros</tt>)</li>
|
||||
</ul>
|
||||
<br><b>Still got questions left? The <a target="_blank" href="https://docs.sillytavern.app/">Official SillyTavern Documentation Website</a> has much more information!</b>`
|
||||
]
|
||||
},
|
||||
slash_commands: {
|
||||
name: systemUserName,
|
||||
@@ -390,7 +389,7 @@ const system_messages = {
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
mes:
|
||||
`Hotkeys/Keybinds:
|
||||
<ul>
|
||||
<li><tt>Up</tt> = Edit last message in chat</li>
|
||||
@@ -404,7 +403,6 @@ const system_messages = {
|
||||
<li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li>
|
||||
<li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li>
|
||||
</ul>`
|
||||
]
|
||||
},
|
||||
formatting: {
|
||||
name: systemUserName,
|
||||
@@ -412,7 +410,7 @@ const system_messages = {
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
mes:
|
||||
`Text formatting commands:
|
||||
<ul>
|
||||
<li><tt>{{text}}</tt> - sets a one-time behavioral bias for the AI. Resets when you send the next message.</li>
|
||||
@@ -424,7 +422,6 @@ const system_messages = {
|
||||
<li><tt>$$ text $$</tt> - renders a LaTeX formula (if enabled)</li>
|
||||
<li><tt>$ text $</tt> - renders an AsciiMath formula (if enabled)</li>
|
||||
</ul>`
|
||||
]
|
||||
},
|
||||
macros: {
|
||||
name: systemUserName,
|
||||
@@ -432,7 +429,7 @@ const system_messages = {
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
mes:
|
||||
`System-wide Replacement Macros:
|
||||
<ul>
|
||||
<li><tt>{{user}}</tt> - your current Persona username</li>
|
||||
@@ -443,7 +440,6 @@ const system_messages = {
|
||||
<li><tt>{{idle_duration}}</tt> - the time since the last user message was sent</li>
|
||||
<li><tt>{{random:(args)}}</tt> - returns a random item from the list. (ex: {{random:1,2,3,4}} will return 1 of the 4 numbers at random. Works with text lists too.</li>
|
||||
</ul>`
|
||||
]
|
||||
},
|
||||
welcome:
|
||||
{
|
||||
@@ -554,6 +550,10 @@ async function getClientVersion() {
|
||||
}
|
||||
|
||||
function getTokenCount(str, padding = undefined) {
|
||||
if (typeof str !== 'string') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let tokenizerType = power_user.tokenizer;
|
||||
|
||||
if (main_api === 'openai') {
|
||||
@@ -971,22 +971,25 @@ async function getBackgrounds() {
|
||||
const getData = await response.json();
|
||||
//background = getData;
|
||||
//console.log(getData.length);
|
||||
$("#bg_menu_content").empty();
|
||||
for (const bg of getData) {
|
||||
const thumbPath = getThumbnailUrl('bg', bg);
|
||||
$("#bg_menu_content").append(
|
||||
`<div class="bg_example flex-container" bgfile="${bg}" class="bg_example_img" title="${bg}" style="background-image: url('${thumbPath}');">
|
||||
<div bgfile="${bg}" class="bg_example_cross fa-solid fa-circle-xmark"></div>
|
||||
<div class="BGSampleTitle">
|
||||
${bg
|
||||
.replace('.png', '')
|
||||
.replace('.jpg', '')
|
||||
.replace('.webp', '')}
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
const template = getBackgroundFromTemplate(bg);
|
||||
$("#bg_menu_content").append(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getBackgroundFromTemplate(bg) {
|
||||
const thumbPath = getThumbnailUrl('bg', bg);
|
||||
const template = $('#background_template .bg_example').clone();
|
||||
template.attr('bgfile', bg);
|
||||
template.attr('title', bg);
|
||||
template.find('.bg_button').attr('bgfile', bg);
|
||||
template.css('background-image', `url('${thumbPath}')`);
|
||||
template.find('.BGSampleTitle').text(bg.slice(0, bg.lastIndexOf('.')));
|
||||
return template;
|
||||
}
|
||||
|
||||
async function isColab() {
|
||||
is_checked_colab = true;
|
||||
const response = await fetch("/iscolab", {
|
||||
@@ -1110,6 +1113,7 @@ function clearChat() {
|
||||
$('.zoomed_avatar[forChar]').remove();
|
||||
} else { console.debug('saw no avatars') }
|
||||
itemizedPrompts = [];
|
||||
chat_metadata = {};
|
||||
}
|
||||
|
||||
async function deleteLastMessage() {
|
||||
@@ -1530,7 +1534,7 @@ function substituteParams(content, _name1, _name2, _original) {
|
||||
_name1 = _name1 ?? name1;
|
||||
_name2 = _name2 ?? name2;
|
||||
if (!content) {
|
||||
return ''
|
||||
return '';
|
||||
}
|
||||
|
||||
// Replace {{original}} with the original message
|
||||
@@ -1548,6 +1552,11 @@ function substituteParams(content, _name1, _name2, _original) {
|
||||
content = content.replace(/{{time}}/gi, moment().format('LT'));
|
||||
content = content.replace(/{{date}}/gi, moment().format('LL'));
|
||||
content = content.replace(/{{idle_duration}}/gi, () => getTimeSinceLastMessage());
|
||||
content = content.replace(/{{time_UTC([-+]\d+)}}/gi, (_, offset) => {
|
||||
const utcOffset = parseInt(offset, 10);
|
||||
const utcTime = moment().utc().utcOffset(utcOffset).format('LT');
|
||||
return utcTime;
|
||||
});
|
||||
content = randomReplace(content);
|
||||
return content;
|
||||
}
|
||||
@@ -1909,8 +1918,9 @@ class StreamingProcessor {
|
||||
|
||||
onProgressStreaming(messageId, text, isFinal) {
|
||||
const isImpersonate = this.type == "impersonate";
|
||||
const isContinue = this.type == "continue";
|
||||
text = this.removePrefix(text);
|
||||
let processedText = cleanUpMessage(text, isImpersonate, !isFinal);
|
||||
let processedText = cleanUpMessage(text, isImpersonate, isContinue, !isFinal);
|
||||
let result = extractNameFromMessage(processedText, this.force_name2, isImpersonate);
|
||||
let isName = result.this_mes_is_name;
|
||||
processedText = result.getMessage;
|
||||
@@ -2089,6 +2099,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
// OpenAI doesn't need instruct mode. Use OAI main prompt instead.
|
||||
const isInstruct = power_user.instruct.enabled && main_api !== 'openai';
|
||||
const isImpersonate = type == "impersonate";
|
||||
const isContinue = type == 'continue';
|
||||
|
||||
message_already_generated = isImpersonate ? `${name1}: ` : `${name2}: `;
|
||||
// Name for the multigen prefix
|
||||
@@ -2265,6 +2276,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
//////////////////////////////////
|
||||
|
||||
let chat2 = [];
|
||||
let continue_mag = '';
|
||||
for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) {
|
||||
// For OpenAI it's only used in WI
|
||||
if (main_api == 'openai' && (!world_info || world_info.length === 0)) {
|
||||
@@ -2275,8 +2287,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct);
|
||||
|
||||
// Do not suffix the message for continuation
|
||||
if (i === 0 && type == 'continue') {
|
||||
if (i === 0 && isContinue) {
|
||||
chat2[i] = chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length);
|
||||
continue_mag = coreChat[j].mes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2355,7 +2368,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
}
|
||||
|
||||
let cyclePrompt = '';
|
||||
if (type == 'continue') {
|
||||
if (isContinue) {
|
||||
cyclePrompt = chat2.shift();
|
||||
}
|
||||
|
||||
@@ -2404,15 +2417,16 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
console.debug('calling runGenerate');
|
||||
streamingProcessor = isStreamingEnabled() ? new StreamingProcessor(type, force_name2) : false;
|
||||
|
||||
if (type == 'continue') {
|
||||
if (isContinue) {
|
||||
// Coping mechanism for OAI spacing
|
||||
if ((main_api === 'openai' || main_api === 'poe') && !cyclePrompt.endsWith(' ')) {
|
||||
cyclePrompt += ' ';
|
||||
continue_mag += ' ';
|
||||
}
|
||||
|
||||
// Save reply does add cycle text to the prompt, so it's not needed here
|
||||
streamingProcessor && (streamingProcessor.firstMessageText = '');
|
||||
message_already_generated = cyclePrompt;
|
||||
message_already_generated = continue_mag;
|
||||
tokens_already_generated = 1; // Multigen copium
|
||||
}
|
||||
|
||||
@@ -2539,7 +2553,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
console.debug(`A prompt bias was found: ${promptBias}`);
|
||||
mesSendString += `${name2}: ${promptBias}`;
|
||||
}
|
||||
} else if (power_user.user_prompt_bias) {
|
||||
} else if (power_user.user_prompt_bias && !isImpersonate && !isInstruct) {
|
||||
console.debug(`A prompt bias was found without character's name appended: ${promptBias}`);
|
||||
mesSendString += substituteParams(power_user.user_prompt_bias);
|
||||
}
|
||||
@@ -2765,8 +2779,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
hideSwipeButtons();
|
||||
let getMessage = await streamingProcessor.generate();
|
||||
|
||||
if (type == 'continue') {
|
||||
getMessage = message_already_generated + getMessage;
|
||||
if (isContinue) {
|
||||
getMessage = continue_mag + getMessage;
|
||||
}
|
||||
|
||||
if (streamingProcessor && !streamingProcessor.isStopped && streamingProcessor.isFinished) {
|
||||
@@ -2804,7 +2818,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
({ type, getMessage } = saveReply('append', getMessage, this_mes_is_name, title));
|
||||
}
|
||||
} else {
|
||||
let chunk = cleanUpMessage(message_already_generated, true, true);
|
||||
let chunk = cleanUpMessage(message_already_generated, true, isContinue, true);
|
||||
let extract = extractNameFromMessage(chunk, force_name2, isImpersonate);
|
||||
$('#send_textarea').val(extract.getMessage).trigger('input');
|
||||
}
|
||||
@@ -2828,12 +2842,12 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
||||
getMessage = message_already_generated.substring(substringStart);
|
||||
}
|
||||
|
||||
if (type == 'continue') {
|
||||
getMessage = message_already_generated + getMessage;
|
||||
if (isContinue) {
|
||||
getMessage = continue_mag + getMessage;
|
||||
}
|
||||
|
||||
//Formating
|
||||
getMessage = cleanUpMessage(getMessage, isImpersonate);
|
||||
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue);
|
||||
|
||||
let this_mes_is_name;
|
||||
({ this_mes_is_name, getMessage } = extractNameFromMessage(getMessage, force_name2, isImpersonate));
|
||||
@@ -2945,6 +2959,10 @@ function getNextMessageId(type) {
|
||||
}
|
||||
|
||||
export function getBiasStrings(textareaText, type) {
|
||||
if (type == 'impersonate') {
|
||||
return { messageBias: '', promptBias: '', isUserPromptBias: false };
|
||||
}
|
||||
|
||||
let promptBias = '';
|
||||
let messageBias = extractMessageBias(textareaText);
|
||||
|
||||
@@ -3217,7 +3235,8 @@ function promptItemize(itemizedPrompts, requestedMesId) {
|
||||
//charDescriptionTokens +
|
||||
//charPersonalityTokens +
|
||||
//allAnchorsTokens +
|
||||
//worldInfoStringTokens +
|
||||
worldInfoStringTokens +
|
||||
afterScenarioAnchorTokens +
|
||||
examplesStringTokens;
|
||||
// OAI doesn't use padding
|
||||
thisPrompt_padding = 0;
|
||||
@@ -3248,7 +3267,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
|
||||
if (this_main_api == 'openai') {
|
||||
//console.log('-- applying % on OAI tokens');
|
||||
var oaiStartTokensPercentage = ((oaiStartTokens / (finalPromptTokens)) * 100).toFixed(2);
|
||||
var storyStringTokensPercentage = ((oaiPromptTokens / (finalPromptTokens)) * 100).toFixed(2);
|
||||
var storyStringTokensPercentage = (((examplesStringTokens + afterScenarioAnchorTokens + oaiPromptTokens) / (finalPromptTokens)) * 100).toFixed(2);
|
||||
var ActualChatHistoryTokensPercentage = ((ActualChatHistoryTokens / (finalPromptTokens)) * 100).toFixed(2);
|
||||
var promptBiasTokensPercentage = ((oaiBiasTokens / (finalPromptTokens)) * 100).toFixed(2);
|
||||
var worldInfoStringTokensPercentage = ((worldInfoStringTokens / (finalPromptTokens)) * 100).toFixed(2);
|
||||
@@ -3605,11 +3624,12 @@ function extractMessageFromData(data) {
|
||||
}
|
||||
}
|
||||
|
||||
function cleanUpMessage(getMessage, isImpersonate, displayIncompleteSentences = false) {
|
||||
function cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncompleteSentences = false) {
|
||||
// Add the prompt bias before anything else
|
||||
if (
|
||||
power_user.user_prompt_bias &&
|
||||
!isImpersonate &&
|
||||
!isContinue &&
|
||||
power_user.user_prompt_bias.length !== 0
|
||||
) {
|
||||
getMessage = substituteParams(power_user.user_prompt_bias) + getMessage;
|
||||
@@ -5170,7 +5190,10 @@ function messageEditAuto(div) {
|
||||
}
|
||||
|
||||
async function messageEditDone(div) {
|
||||
const { mesBlock, text, mes, bias } = updateMessage(div);
|
||||
let { mesBlock, text, mes, bias } = updateMessage(div);
|
||||
if (this_edit_mes_id == 0) {
|
||||
text = substituteParams(text);
|
||||
}
|
||||
|
||||
mesBlock.find(".mes_text").empty();
|
||||
mesBlock.find(".mes_edit_buttons").css("display", "none");
|
||||
@@ -5681,11 +5704,7 @@ function read_bg_load(input) {
|
||||
"background-image",
|
||||
`url("${e.target.result}")`
|
||||
);
|
||||
$("#form_bg_download").after(
|
||||
`<div class="bg_example" bgfile="${html}" style="background-image: url('${getThumbnailUrl('bg', html)}');">
|
||||
<div class="bg_example_cross fa-solid fa-circle-xmark"></div>
|
||||
</div>`
|
||||
);
|
||||
$("#form_bg_download").after(getBackgroundFromTemplate(html));
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
console.log(exception);
|
||||
@@ -6813,6 +6832,18 @@ async function doImpersonate() {
|
||||
$("#option_impersonate").trigger('click', { fromSlashCommand: true })
|
||||
}
|
||||
|
||||
async function doDeleteChat() {
|
||||
$("#option_select_chat").trigger('click', { fromSlashCommand: true })
|
||||
await delay(100)
|
||||
let currentChatDeleteButton = $(".select_chat_block[highlight='true']").parent().find('.PastChat_cross')
|
||||
$(currentChatDeleteButton).trigger('click', { fromSlashCommand: true })
|
||||
await delay(1)
|
||||
$("#dialogue_popup_ok").trigger('click')
|
||||
//200 delay needed let the past chat view reshow first
|
||||
await delay(200)
|
||||
$("#select_chat_cross").trigger('click')
|
||||
}
|
||||
|
||||
const isPwaMode = window.navigator.standalone;
|
||||
if (isPwaMode) { $("body").addClass('PWA') }
|
||||
|
||||
@@ -6836,6 +6867,7 @@ $(document).ready(function () {
|
||||
registerSlashCommand('dupe', DupeChar, [], "– duplicates the currently selected character", true, true);
|
||||
registerSlashCommand('api', connectAPISlash, [], "(kobold, horde, novel, ooba, oai, claude, poe, windowai) – connect to an API", true, true);
|
||||
registerSlashCommand('impersonate', doImpersonate, ['imp'], "- calls an impersonation response", true, true);
|
||||
registerSlashCommand('delchat', doDeleteChat, [], "- deletes the current chat", true, true);
|
||||
|
||||
|
||||
setTimeout(function () {
|
||||
@@ -7069,6 +7101,41 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$(document).on('click', '.bg_example_edit', async function (e) {
|
||||
e.stopPropagation();
|
||||
const old_bg = $(this).attr('bgfile');
|
||||
|
||||
if (!old_bg) {
|
||||
console.debug('no bgfile');
|
||||
return;
|
||||
}
|
||||
|
||||
const fileExtension = old_bg.split('.').pop();
|
||||
const old_bg_extensionless = old_bg.replace(`.${fileExtension}`, '');
|
||||
const new_bg_extensionless = await callPopup('<h3>Enter new background name:</h3>', 'input', old_bg_extensionless);
|
||||
const new_bg = `${new_bg_extensionless}.${fileExtension}`;
|
||||
|
||||
if (old_bg_extensionless === new_bg_extensionless) {
|
||||
console.debug('new_bg === old_bg');
|
||||
return;
|
||||
}
|
||||
|
||||
const data = { old_bg, new_bg };
|
||||
const response = await fetch('/renamebackground', {
|
||||
method: 'POST',
|
||||
headers:getRequestHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
cache: 'no-cache',
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
await getBackgrounds();
|
||||
} else {
|
||||
toastr.warning('Failed to rename background');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", ".bg_example_cross", function (e) {
|
||||
e.stopPropagation();
|
||||
bg_file_for_del = $(this);
|
||||
@@ -7080,7 +7147,7 @@ $(document).ready(function () {
|
||||
|
||||
$(document).on("click", ".PastChat_cross", function () {
|
||||
chat_file_for_del = $(this).attr('file_name');
|
||||
console.log('detected cross click for' + chat_file_for_del);
|
||||
console.debug('detected cross click for' + chat_file_for_del);
|
||||
popup_type = "del_chat";
|
||||
callPopup("<h3>Delete the Chat File?</h3>");
|
||||
});
|
||||
@@ -7231,7 +7298,6 @@ $(document).ready(function () {
|
||||
chat_metadata = {};
|
||||
characters[this_chid].chat = name2 + " - " + humanizedDateTime();
|
||||
$("#selected_chat_pole").val(characters[this_chid].chat);
|
||||
saveCharacterDebounced();
|
||||
getChat();
|
||||
}
|
||||
}
|
||||
@@ -7540,15 +7606,20 @@ $(document).ready(function () {
|
||||
var id = $(this).attr("id");
|
||||
|
||||
if (id == "option_select_chat") {
|
||||
if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press)) {
|
||||
if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press) || fromSlashCommand) {
|
||||
displayPastChats();
|
||||
$("#shadow_select_chat_popup").css("display", "block");
|
||||
$("#shadow_select_chat_popup").css("opacity", 0.0);
|
||||
$("#shadow_select_chat_popup").transition({
|
||||
opacity: 1.0,
|
||||
duration: animation_duration,
|
||||
easing: animation_easing,
|
||||
});
|
||||
//this is just to avoid the shadow for past chat view when using /delchat
|
||||
//however, the dialog popup still gets one..
|
||||
if (!fromSlashCommand) {
|
||||
console.log('displaying shadow')
|
||||
$("#shadow_select_chat_popup").css("display", "block");
|
||||
$("#shadow_select_chat_popup").css("opacity", 0.0);
|
||||
$("#shadow_select_chat_popup").transition({
|
||||
opacity: 1.0,
|
||||
duration: animation_duration,
|
||||
easing: animation_easing,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8333,7 +8404,7 @@ $(document).ready(function () {
|
||||
var icon = $(this).find('.inline-drawer-icon');
|
||||
icon.toggleClass('down up');
|
||||
icon.toggleClass('fa-circle-chevron-down fa-circle-chevron-up');
|
||||
$(this).closest('.inline-drawer').find('.inline-drawer-content').slideToggle();
|
||||
$(this).closest('.inline-drawer').find('.inline-drawer-content').stop().slideToggle();
|
||||
});
|
||||
|
||||
$(document).on('click', '.mes .avatar', function () {
|
||||
|
@@ -5,15 +5,14 @@ import {
|
||||
getTokenCount,
|
||||
saveSettingsDebounced,
|
||||
this_chid,
|
||||
} from "../../../script.js";
|
||||
import { selected_group } from "../../group-chats.js";
|
||||
import { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
||||
import { registerSlashCommand } from "../../slash-commands.js";
|
||||
import { getCharaFilename, debounce, waitUntilCondition, delay } from "../../utils.js";
|
||||
} from "../script.js";
|
||||
import { selected_group } from "./group-chats.js";
|
||||
import { extension_settings, getContext, saveMetadataDebounced } from "./extensions.js";
|
||||
import { registerSlashCommand } from "./slash-commands.js";
|
||||
import { getCharaFilename, debounce, waitUntilCondition, delay } from "./utils.js";
|
||||
export { MODULE_NAME as NOTE_MODULE_NAME };
|
||||
|
||||
const MODULE_NAME = '2_floating_prompt'; // <= Deliberate, for sorting lower than memory
|
||||
const UPDATE_INTERVAL = 1000;
|
||||
|
||||
const DEFAULT_DEPTH = 4;
|
||||
const DEFAULT_POSITION = 1;
|
||||
@@ -352,110 +351,10 @@ function onChatChanged() {
|
||||
$('#extension_floating_default_token_counter').text(tokenCounter3);
|
||||
}
|
||||
|
||||
function addExtensionsSettings() {
|
||||
const settingsHtml = `
|
||||
<div id="floatingPrompt" class="drawer-content flexGap5">
|
||||
<div class="panelControlBar flex-container">
|
||||
<div id="floatingPromptheader" class="fa-solid fa-grip drag-grabber"></div>
|
||||
<div id="ANClose" class="fa-solid fa-circle-xmark"></div>
|
||||
</div>
|
||||
<div name="floatingPromptHolder">
|
||||
<div class="inline-drawer">
|
||||
<div id="ANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>
|
||||
<b>Unique to this chat</b>.<br>
|
||||
Bookmarks inherit the Note from their parent, and can be changed individually after that.<br>
|
||||
</small>
|
||||
|
||||
<textarea id="extension_floating_prompt" class="text_pole" rows="8" maxlength="10000"></textarea>
|
||||
<div class="extension_token_counter">Tokens: <span id="extension_floating_prompt_token_counter">0</small></div>
|
||||
|
||||
<div class="floating_prompt_radio_group">
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_position" value="0" />
|
||||
After scenario
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_position" value="1" />
|
||||
In-chat @ Depth <input id="extension_floating_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
|
||||
</label>
|
||||
</div>
|
||||
<!--<label for="extension_floating_interval">In-Chat Insertion Depth</label>-->
|
||||
|
||||
<label for="extension_floating_interval">Insertion Frequency</label>
|
||||
|
||||
<input id="extension_floating_interval" class="text_pole widthUnset" type="number" min="0" max="999" /><small> (0 = Disable, 1 = Always)</small>
|
||||
<br>
|
||||
|
||||
<span>User inputs until next insertion: <span id="extension_floating_counter">(disabled)</span></span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<hr class="sysHR">
|
||||
<div class="inline-drawer">
|
||||
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Character Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be automatically added as the author's note for this character. Will be used in groups, but can't be modified when a group chat is open.</small>
|
||||
|
||||
<textarea id="extension_floating_chara" class="text_pole" rows="8" maxlength="10000"
|
||||
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||
<div class="extension_token_counter">Tokens: <span id="extension_floating_chara_token_counter">0</small></div>
|
||||
|
||||
<label class="checkbox_label" for="extension_use_floating_chara">
|
||||
<input id="extension_use_floating_chara" type="checkbox" />
|
||||
<span data-i18n="Use character author's note">Use character author's note</span>
|
||||
</label>
|
||||
<div class="floating_prompt_radio_group">
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="0" />
|
||||
Replace Author's Note
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="1" />
|
||||
Top of Author's Note
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="extension_floating_char_position" value="2" />
|
||||
Bottom of Author's Note
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="sysHR">
|
||||
<div class="inline-drawer">
|
||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Default Author's Note</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<small>Will be automatically added as the Author's Note for all new chats.</small>
|
||||
|
||||
<textarea id="extension_floating_default" class="text_pole" rows="8" maxlength="10000"
|
||||
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||
<div class="extension_token_counter">Tokens: <span id="extension_floating_default_token_counter">0</small></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const ANButtonHtml = `
|
||||
<a id="option_toggle_AN">
|
||||
<i class="fa-lg fa-solid fa-note-sticky"></i>
|
||||
<span data-i18n="Author's Note">Author's Note</span>
|
||||
</a>
|
||||
`;
|
||||
|
||||
$('#options .options-content').prepend(ANButtonHtml);
|
||||
$('#movingDivs').append(settingsHtml);
|
||||
// Inject extension when extensions_activating is fired
|
||||
// Inserts the extension first since it's statically imported
|
||||
jQuery(async () => {
|
||||
await waitUntilCondition(() => eventSource !== undefined);
|
||||
$('#extension_floating_prompt').on('input', onExtensionFloatingPromptInput);
|
||||
$('#extension_floating_interval').on('input', onExtensionFloatingIntervalInput);
|
||||
$('#extension_floating_depth').on('input', onExtensionFloatingDepthInput);
|
||||
@@ -473,13 +372,6 @@ function addExtensionsSettings() {
|
||||
setTimeout(function () { $('#floatingPrompt').hide() }, 200);
|
||||
})
|
||||
$("#option_toggle_AN").on('click', onANMenuItemClick);
|
||||
}
|
||||
|
||||
// Inject extension when extensions_activating is fired
|
||||
// Inserts the extension first since it's statically imported
|
||||
jQuery(async () => {
|
||||
await waitUntilCondition(() => eventSource !== undefined);
|
||||
eventSource.on(event_types.EXTENSIONS_FIRST_LOAD, addExtensionsSettings);
|
||||
|
||||
registerSlashCommand('note', setNoteTextCommand, [], "<span class='monospace'>(text)</span> – sets an author's note for the currently selected chat", true, true);
|
||||
registerSlashCommand('depth', setNoteDepthCommand, [], "<span class='monospace'>(number)</span> – sets an author's note depth for in-chat positioning", true, true);
|
@@ -411,9 +411,9 @@ async function generateExtensionHtml(name, manifest, isActive, isDisabled, isExt
|
||||
let toggleElement = isActive || isDisabled ?
|
||||
`<input type="checkbox" title="Click to toggle" data-name="${name}" class="${isActive ? 'toggle_disable' : 'toggle_enable'} ${checkboxClass}" ${isActive ? 'checked' : ''}>` :
|
||||
`<input type="checkbox" title="Cannot enable extension" data-name="${name}" class="extension_missing ${checkboxClass}" disabled>`;
|
||||
|
||||
|
||||
let deleteButton = isExternal ? `<span class="delete-button"><button class="btn_delete menu_button" data-name="${name.replace('third-party', '')}" title="Delete"><i class="fa-solid fa-trash-can"></i></button></span>` : '';
|
||||
|
||||
|
||||
// if external, wrap the name in a link to the repo
|
||||
|
||||
let extensionHtml = `<hr>
|
||||
@@ -423,7 +423,7 @@ async function generateExtensionHtml(name, manifest, isActive, isDisabled, isExt
|
||||
${originHtml}
|
||||
<span class="${isActive ? "extension_enabled" : isDisabled ? "extension_disabled" : "extension_missing"}">
|
||||
${DOMPurify.sanitize(displayName)}${displayVersion}
|
||||
</span>
|
||||
</span>
|
||||
${isExternal ? '</a>' : ''}
|
||||
|
||||
<span style="float:right;">${toggleElement}</span>
|
||||
|
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"display_name": "Author's Note",
|
||||
"loading_order": 1,
|
||||
"requires": [],
|
||||
"optional": [],
|
||||
"generate_interceptor": "AuthorNote_generateInterceptor",
|
||||
"js": "index.js",
|
||||
"css": "style.css",
|
||||
"author": "Cohee#1207",
|
||||
"version": "1.0.0",
|
||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
#floatingPrompt {
|
||||
overflow-y: auto;
|
||||
max-width: 90svw;
|
||||
max-height: 90svh;
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--white30a);
|
||||
position: fixed;
|
||||
padding: 10px;
|
||||
padding-top: 25px;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 0 10px var(--black70a);
|
||||
z-index: 3000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin: 0;
|
||||
right: unset;
|
||||
width: calc(((100svw - var(--sheldWidth)) / 2) - 1px);
|
||||
|
||||
}
|
||||
|
||||
.floating_prompt_radio_group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#extension_floating_counter {
|
||||
font-weight: 600;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.extension_token_counter {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.floating_prompt_settings textarea {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#ANClose {
|
||||
height: 15px;
|
||||
aspect-ratio: 1 / 1;
|
||||
font-size: 20px;
|
||||
opacity: 0.5;
|
||||
transition: all 250ms;
|
||||
}
|
||||
|
||||
#ANClose:hover {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#floatingPrompt .drag-grabber {
|
||||
position: unset;
|
||||
}
|
@@ -128,19 +128,46 @@ function substituteRegexParams(rawString, regexMatch, { characterOverride, repla
|
||||
finalString = substituteParams(finalString, undefined, characterOverride);
|
||||
|
||||
let overlaidMatch = regexMatch;
|
||||
// TODO: Maybe move the for loops into a separate function?
|
||||
if (replaceStrategy === regex_replace_strategy.OVERLAY) {
|
||||
const splitReplace = finalString.split("{{match}}");
|
||||
|
||||
// There's a prefix
|
||||
if (splitReplace[0]) {
|
||||
// Fetch the prefix
|
||||
const splicedPrefix = spliceSymbols(splitReplace[0], false);
|
||||
overlaidMatch = overlaidMatch.replace(splicedPrefix, "").trim();
|
||||
|
||||
// Sequentially remove all occurrences of prefix from start of split
|
||||
const splitMatch = overlaidMatch.split(splicedPrefix);
|
||||
let sliceNum = 0;
|
||||
for (let index = 0; index < splitMatch.length; index++) {
|
||||
if (splitMatch[index].length === 0) {
|
||||
sliceNum++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
overlaidMatch = splitMatch.slice(sliceNum, splitMatch.length).join(splicedPrefix);
|
||||
}
|
||||
|
||||
// There's a suffix
|
||||
if (splitReplace[1]) {
|
||||
// Fetch the suffix
|
||||
const splicedSuffix = spliceSymbols(splitReplace[1], true);
|
||||
overlaidMatch = overlaidMatch.replace(new RegExp(`${splicedSuffix}$`), "").trim();
|
||||
|
||||
// Sequential removal of all suffix occurrences from end of split
|
||||
const splitMatch = overlaidMatch.split(splicedSuffix);
|
||||
let sliceNum = 0;
|
||||
for (let index = splitMatch.length - 1; index >= 0; index--) {
|
||||
if (splitMatch[index].length === 0) {
|
||||
sliceNum++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
overlaidMatch = splitMatch.slice(0, splitMatch.length - sliceNum).join(splicedSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +177,7 @@ function substituteRegexParams(rawString, regexMatch, { characterOverride, repla
|
||||
return finalString;
|
||||
}
|
||||
|
||||
// Splices symbols and whitespace from the beginning and end of a string
|
||||
// Splices common sentence symbols and whitespace from the beginning and end of a string
|
||||
// Using a for loop due to sequential ordering
|
||||
function spliceSymbols(rawString, isSuffix) {
|
||||
let offset = 0;
|
||||
@@ -163,5 +190,5 @@ function spliceSymbols(rawString, isSuffix) {
|
||||
}
|
||||
}
|
||||
|
||||
return isSuffix ? rawString.substring(0, rawString.length - offset) : rawString.substring(offset);;
|
||||
return isSuffix ? rawString.substring(0, rawString.length - offset) : rawString.substring(offset);
|
||||
}
|
||||
|
@@ -236,5 +236,25 @@ jQuery(async () => {
|
||||
onRegexEditorOpenClick(false);
|
||||
});
|
||||
|
||||
$('#saved_regex_scripts').sortable({
|
||||
stop: function () {
|
||||
let newScripts = [];
|
||||
$('#saved_regex_scripts').children().each(function () {
|
||||
const scriptName = $(this).find(".regex_script_name").text();
|
||||
const existingScript = extension_settings.regex.find((e) => e.scriptName === scriptName);
|
||||
if (existingScript) {
|
||||
newScripts.push(existingScript);
|
||||
}
|
||||
});
|
||||
|
||||
extension_settings.regex = newScripts;
|
||||
saveSettingsDebounced();
|
||||
|
||||
console.debug("Regex scripts reordered");
|
||||
// TODO: Maybe reload regex scripts after move
|
||||
},
|
||||
});
|
||||
|
||||
await loadRegexScripts();
|
||||
$("#saved_regex_scripts").sortable("enable");
|
||||
});
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<div class="regex-script-label flex-container flexnowrap">
|
||||
<span class="drag-handle menu-handle">☰</span>
|
||||
<div class="regex_script_name flexGrow overflow-hidden"></div>
|
||||
<div class="flex-container flexnowrap">
|
||||
<div class="edit_existing_regex menu_button">
|
||||
|
@@ -539,9 +539,9 @@ function getSystemPrompt(systemPrompt, nsfw_toggle_prompt, enhance_definitions_p
|
||||
return whole_prompt;
|
||||
}
|
||||
|
||||
function tryParseStreamingError(str) {
|
||||
function tryParseStreamingError(response, decoded) {
|
||||
try {
|
||||
const data = JSON.parse(str);
|
||||
const data = JSON.parse(decoded);
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
@@ -550,7 +550,7 @@ function tryParseStreamingError(str) {
|
||||
checkQuotaError(data);
|
||||
|
||||
if (data.error) {
|
||||
toastr.error(response.statusText, 'API returned an error');
|
||||
toastr.error(data.error.message || response.statusText, 'API returned an error');
|
||||
throw new Error(data);
|
||||
}
|
||||
}
|
||||
@@ -784,26 +784,26 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
|
||||
let messageBuffer = "";
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
let response = decoder.decode(value);
|
||||
let decoded = decoder.decode(value);
|
||||
|
||||
// Claude's streaming SSE messages are separated by \r
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) {
|
||||
response = response.replace(/\r/g, "");
|
||||
decoded = decoded.replace(/\r/g, "");
|
||||
}
|
||||
|
||||
tryParseStreamingError(response);
|
||||
tryParseStreamingError(response, decoded);
|
||||
|
||||
let eventList = [];
|
||||
|
||||
// ReadableStream's buffer is not guaranteed to contain full SSE messages as they arrive in chunks
|
||||
// We need to buffer chunks until we have one or more full messages (separated by double newlines)
|
||||
if (!oai_settings.legacy_streaming) {
|
||||
messageBuffer += response;
|
||||
messageBuffer += decoded;
|
||||
eventList = messageBuffer.split("\n\n");
|
||||
// Last element will be an empty string or a leftover partial message
|
||||
messageBuffer = eventList.pop();
|
||||
} else {
|
||||
eventList = response.split("\n");
|
||||
eventList = decoded.split("\n");
|
||||
}
|
||||
|
||||
for (let event of eventList) {
|
||||
@@ -837,7 +837,7 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
|
||||
checkQuotaError(data);
|
||||
|
||||
if (data.error) {
|
||||
toastr.error(response.statusText, 'API returned an error');
|
||||
toastr.error(data.error.message || response.statusText, 'API returned an error');
|
||||
throw new Error(data);
|
||||
}
|
||||
|
||||
@@ -999,30 +999,50 @@ export function getTokenizerModel() {
|
||||
return oai_settings.openai_model;
|
||||
}
|
||||
|
||||
const turboTokenizer = 'gpt-3.5-turbo';
|
||||
const gpt4Tokenizer = 'gpt-4';
|
||||
const gpt2Tokenizer = 'gpt2';
|
||||
const claudeTokenizer = 'claude';
|
||||
|
||||
// Assuming no one would use it for different models.. right?
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) {
|
||||
return 'gpt-4';
|
||||
return gpt4Tokenizer;
|
||||
}
|
||||
|
||||
const turboTokenizer = 'gpt-3.5-turbo'
|
||||
// Select correct tokenizer for WindowAI proxies
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) {
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI && oai_settings.windowai_model) {
|
||||
if (oai_settings.windowai_model.includes('gpt-4')) {
|
||||
return 'gpt-4';
|
||||
return gpt4Tokenizer;
|
||||
}
|
||||
else if (oai_settings.windowai_model.includes('gpt-3.5-turbo')) {
|
||||
return turboTokenizer;
|
||||
}
|
||||
else if (oai_settings.windowai_model.includes('claude')) {
|
||||
return 'claude';
|
||||
return claudeTokenizer;
|
||||
}
|
||||
else if (oai_settings.windowai_model.includes('GPT-NeoXT')) {
|
||||
return 'gpt2';
|
||||
return gpt2Tokenizer;
|
||||
}
|
||||
}
|
||||
|
||||
// And for OpenRouter (if not a site model, then it's impossible to determine the tokenizer)
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER && oai_settings.openrouter_model) {
|
||||
if (oai_settings.openrouter_model.includes('gpt-4')) {
|
||||
return gpt4Tokenizer;
|
||||
}
|
||||
else if (oai_settings.openrouter_model.includes('gpt-3.5-turbo')) {
|
||||
return turboTokenizer;
|
||||
}
|
||||
else if (oai_settings.openrouter_model.includes('claude')) {
|
||||
return claudeTokenizer;
|
||||
}
|
||||
else if (oai_settings.openrouter_model.includes('GPT-NeoXT')) {
|
||||
return gpt2Tokenizer;
|
||||
}
|
||||
}
|
||||
|
||||
if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) {
|
||||
return 'claude';
|
||||
return claudeTokenizer;
|
||||
}
|
||||
|
||||
// Default to Turbo 3.5
|
||||
|
@@ -58,11 +58,6 @@ export const chat_styles = {
|
||||
DOCUMENT: 2,
|
||||
}
|
||||
|
||||
const sheld_width = {
|
||||
DEFAULT: 0,
|
||||
w1000px: 1,
|
||||
}
|
||||
|
||||
const pygmalion_options = {
|
||||
DISABLED: -1,
|
||||
AUTO: 0,
|
||||
@@ -117,7 +112,7 @@ let power_user = {
|
||||
fast_ui_mode: true,
|
||||
avatar_style: avatar_styles.ROUND,
|
||||
chat_display: chat_styles.DEFAULT,
|
||||
sheld_width: sheld_width.DEFAULT,
|
||||
chat_width: 50,
|
||||
never_resize_avatars: false,
|
||||
show_card_avatar_urls: false,
|
||||
play_message_sound: false,
|
||||
@@ -143,9 +138,11 @@ let power_user = {
|
||||
waifuMode: false,
|
||||
movingUI: false,
|
||||
movingUIState: {},
|
||||
movingUIPreset: '',
|
||||
noShadows: false,
|
||||
theme: 'Default (Dark) 1.7.1',
|
||||
|
||||
|
||||
auto_swipe: false,
|
||||
auto_swipe_minimum_length: 0,
|
||||
auto_swipe_blacklist: [],
|
||||
@@ -193,13 +190,14 @@ let power_user = {
|
||||
};
|
||||
|
||||
let themes = [];
|
||||
let movingUIPresets = [];
|
||||
let instruct_presets = [];
|
||||
|
||||
const storage_keys = {
|
||||
fast_ui_mode: "TavernAI_fast_ui_mode",
|
||||
avatar_style: "TavernAI_avatar_style",
|
||||
chat_display: "TavernAI_chat_display",
|
||||
sheld_width: "TavernAI_sheld_width",
|
||||
chat_width: "chat_width",
|
||||
font_scale: "TavernAI_font_scale",
|
||||
|
||||
main_text_color: "TavernAI_main_text_color",
|
||||
@@ -406,18 +404,11 @@ function applyChatDisplay() {
|
||||
}
|
||||
}
|
||||
|
||||
function applySheldWidth() {
|
||||
//disabled due to 50vw conversion
|
||||
return
|
||||
power_user.sheld_width = Number(localStorage.getItem(storage_keys.sheld_width) ?? chat_styles.DEFAULT);
|
||||
$("body").toggleClass("w1000px", power_user.sheld_width === sheld_width.w1000px);
|
||||
function applyChatWidth() {
|
||||
power_user.chat_width = Number(localStorage.getItem(storage_keys.chat_width) ?? 50);
|
||||
let r = document.documentElement;
|
||||
if (power_user.sheld_width === 1) {
|
||||
r.style.setProperty('--sheldWidth', '1000px');
|
||||
} else {
|
||||
r.style.setProperty('--sheldWidth', '800px');
|
||||
}
|
||||
$(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true);
|
||||
r.style.setProperty('--sheldWidth', `${power_user.chat_width}vw`);
|
||||
$('#chat_width_slider').val(power_user.chat_width);
|
||||
}
|
||||
|
||||
async function applyThemeColor(type) {
|
||||
@@ -542,10 +533,10 @@ async function applyTheme(name) {
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'sheld_width',
|
||||
key: 'chat_width',
|
||||
action: async () => {
|
||||
localStorage.setItem(storage_keys.sheld_width, power_user.sheld_width);
|
||||
applySheldWidth();
|
||||
localStorage.setItem(storage_keys.chat_width, power_user.chat_width);
|
||||
applyChatWidth();
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -594,10 +585,25 @@ async function applyTheme(name) {
|
||||
console.log('theme applied: ' + name);
|
||||
}
|
||||
|
||||
async function applyMovingUIPreset(name) {
|
||||
resetMovablePanels('quiet')
|
||||
const movingUIPreset = movingUIPresets.find(x => x.name == name);
|
||||
|
||||
if (!movingUIPreset) {
|
||||
return;
|
||||
}
|
||||
|
||||
power_user.movingUIState = movingUIPreset.movingUIState;
|
||||
|
||||
|
||||
console.log('MovingUI Preset applied: ' + name);
|
||||
loadMovingUIState()
|
||||
}
|
||||
|
||||
switchUiMode();
|
||||
applyFontScale();
|
||||
applyThemeColor();
|
||||
applySheldWidth();
|
||||
applyChatWidth();
|
||||
applyAvatarStyle();
|
||||
applyBlurStrength();
|
||||
applyShadowWidth();
|
||||
@@ -618,6 +624,10 @@ function loadPowerUserSettings(settings, data) {
|
||||
themes = data.themes;
|
||||
}
|
||||
|
||||
if (data.movingUIPresets !== undefined) {
|
||||
movingUIPresets = data.movingUIPresets;
|
||||
}
|
||||
|
||||
if (data.instruct !== undefined) {
|
||||
instruct_presets = data.instruct;
|
||||
}
|
||||
@@ -639,7 +649,7 @@ function loadPowerUserSettings(settings, data) {
|
||||
power_user.mesIDDisplay_enabled = mesIDDisplay === null ? true : mesIDDisplay == "true";
|
||||
power_user.avatar_style = Number(localStorage.getItem(storage_keys.avatar_style) ?? avatar_styles.ROUND);
|
||||
//power_user.chat_display = Number(localStorage.getItem(storage_keys.chat_display) ?? chat_styles.DEFAULT);
|
||||
power_user.sheld_width = Number(localStorage.getItem(storage_keys.sheld_width) ?? sheld_width.DEFAULT);
|
||||
power_user.chat_width = Number(localStorage.getItem(storage_keys.chat_width) ?? 50);
|
||||
power_user.font_scale = Number(localStorage.getItem(storage_keys.font_scale) ?? 1);
|
||||
power_user.blur_strength = Number(localStorage.getItem(storage_keys.blur_strength) ?? 10);
|
||||
|
||||
@@ -706,7 +716,7 @@ function loadPowerUserSettings(settings, data) {
|
||||
$("#prefer_character_jailbreak").prop("checked", power_user.prefer_character_jailbreak);
|
||||
$(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop("checked", true);
|
||||
$(`#chat_display option[value=${power_user.chat_display}]`).attr("selected", true).trigger('change');
|
||||
$(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true);
|
||||
$('#chat_width_slider').val(power_user.chat_width);
|
||||
$("#token_padding").val(power_user.token_padding);
|
||||
|
||||
$("#font_scale").val(power_user.font_scale);
|
||||
@@ -735,6 +745,15 @@ function loadPowerUserSettings(settings, data) {
|
||||
$("#themes").append(option);
|
||||
}
|
||||
|
||||
for (const movingUIPreset of movingUIPresets) {
|
||||
const option = document.createElement('option');
|
||||
option.value = movingUIPreset.name;
|
||||
option.innerText = movingUIPreset.name;
|
||||
option.selected = movingUIPreset.name == power_user.movingUIPreset;
|
||||
$("#movingUIPresets").append(option);
|
||||
}
|
||||
|
||||
|
||||
$(`#character_sort_order option[data-order="${power_user.sort_order}"][data-field="${power_user.sort_field}"]`).prop("selected", true);
|
||||
sortCharactersList();
|
||||
reloadMarkdownProcessor(power_user.render_formulas);
|
||||
@@ -917,6 +936,10 @@ export function formatInstructModePrompt(name, isImpersonate, promptBias, name1,
|
||||
|
||||
const sortFunc = (a, b) => power_user.sort_order == 'asc' ? compareFunc(a, b) : compareFunc(b, a);
|
||||
const compareFunc = (first, second) => {
|
||||
if (power_user.sort_order == 'random') {
|
||||
return Math.random() > 0.5 ? 1 : -1;
|
||||
}
|
||||
|
||||
switch (power_user.sort_rule) {
|
||||
case 'boolean':
|
||||
const a = first[power_user.sort_field];
|
||||
@@ -999,7 +1022,7 @@ async function saveTheme() {
|
||||
avatar_style: power_user.avatar_style,
|
||||
chat_display: power_user.chat_display,
|
||||
noShadows: power_user.noShadows,
|
||||
sheld_width: power_user.sheld_width,
|
||||
chat_width: power_user.chat_width,
|
||||
timer_enabled: power_user.timer_enabled,
|
||||
timestamps_enabled: power_user.timestamps_enabled,
|
||||
mesIDDisplay_enabled: power_user.mesIDDisplay_enabled,
|
||||
@@ -1034,6 +1057,48 @@ async function saveTheme() {
|
||||
}
|
||||
}
|
||||
|
||||
async function saveMovingUI() {
|
||||
const name = await callPopup('Enter a name for the MovingUI Preset:', 'input');
|
||||
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
|
||||
const movingUIPreset = {
|
||||
name,
|
||||
movingUIState: power_user.movingUIState
|
||||
}
|
||||
console.log(movingUIPreset)
|
||||
|
||||
const response = await fetch('/savemovingui', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify(movingUIPreset)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const movingUIPresetIndex = movingUIPresets.findIndex(x => x.name == name);
|
||||
|
||||
if (movingUIPresetIndex == -1) {
|
||||
movingUIPresets.push(movingUIPreset);
|
||||
const option = document.createElement('option');
|
||||
option.selected = true;
|
||||
option.value = name;
|
||||
option.innerText = name;
|
||||
$('#movingUIPresets').append(option);
|
||||
}
|
||||
else {
|
||||
movingUIPresets[movingUIPresetIndex] = movingUIPreset;
|
||||
$(`#movingUIPresets option[value="${name}"]`).attr('selected', true);
|
||||
}
|
||||
|
||||
power_user.movingUIPreset = name;
|
||||
saveSettingsDebounced();
|
||||
} else {
|
||||
toastr.warning('failed to save MovingUI state.')
|
||||
}
|
||||
}
|
||||
|
||||
async function resetMovablePanels(type) {
|
||||
const panelIds = [
|
||||
'sheld',
|
||||
@@ -1072,13 +1137,25 @@ async function resetMovablePanels(type) {
|
||||
await delay(50)
|
||||
|
||||
power_user.movingUIState = {};
|
||||
|
||||
//if user manually resets panels, deselect the current preset
|
||||
if (type !== 'quiet' && type !== 'resize') {
|
||||
power_user.movingUIPreset = 'Default'
|
||||
$(`#movingUIPresets option[value="Default"]`).prop('selected', true);
|
||||
}
|
||||
|
||||
saveSettingsDebounced();
|
||||
eventSource.emit(event_types.MOVABLE_PANELS_RESET);
|
||||
|
||||
eventSource.once(event_types.SETTINGS_UPDATED, () => {
|
||||
$(".resizing").removeClass('resizing');
|
||||
if (type === 'resize') {
|
||||
//if happening as part of preset application, do it quietly.
|
||||
if (type === 'quiet') {
|
||||
return
|
||||
//if happening due to resize, tell user.
|
||||
} else if (type === 'resize') {
|
||||
toastr.warning('Panel positions reset due to zoom/resize');
|
||||
//if happening due to manual button press
|
||||
} else {
|
||||
toastr.success('Panel positions reset');
|
||||
}
|
||||
@@ -1578,11 +1655,10 @@ $(document).ready(() => {
|
||||
|
||||
});
|
||||
|
||||
$(`input[name="sheld_width"]`).on('input', function (e) {
|
||||
power_user.sheld_width = Number(e.target.value);
|
||||
localStorage.setItem(storage_keys.sheld_width, power_user.sheld_width);
|
||||
//console.log("sheld width changing now");
|
||||
applySheldWidth();
|
||||
$('#chat_width_slider').on('input', function (e) {
|
||||
power_user.chat_width = Number(e.target.value);
|
||||
localStorage.setItem(storage_keys.chat_width, power_user.chat_width);
|
||||
applyChatWidth();
|
||||
});
|
||||
|
||||
$(`input[name="font_scale"]`).on('input', async function (e) {
|
||||
@@ -1655,7 +1731,17 @@ $(document).ready(() => {
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$("#movingUIPresets").on('change', async function () {
|
||||
console.log('saw MUI preset change')
|
||||
const movingUIPresetSelected = $(this).find(':selected').val();
|
||||
power_user.movingUIPreset = movingUIPresetSelected;
|
||||
applyMovingUIPreset(movingUIPresetSelected);
|
||||
saveSettingsDebounced();
|
||||
|
||||
});
|
||||
|
||||
$("#ui-preset-save-button").on('click', saveTheme);
|
||||
$("#movingui-preset-save-button").on('click', saveMovingUI);
|
||||
|
||||
$("#never_resize_avatars").on('input', function () {
|
||||
power_user.never_resize_avatars = !!$(this).prop('checked');
|
||||
|
@@ -20,6 +20,7 @@ import {
|
||||
replaceCurrentChat,
|
||||
setCharacterId,
|
||||
generateQuietPrompt,
|
||||
reloadCurrentChat,
|
||||
} from "../script.js";
|
||||
import { humanizedDateTime } from "./RossAscends-mods.js";
|
||||
import { resetSelectedGroup } from "./group-chats.js";
|
||||
@@ -125,11 +126,46 @@ parser.addCommand('flat', setFlatModeCallback, ['default'], ' – sets the messa
|
||||
parser.addCommand('continue', continueChatCallback, ['cont'], ' – continues the last message in the chat', true, true);
|
||||
parser.addCommand('go', goToCharacterCallback, ['char'], '<span class="monospace">(name)</span> – opens up a chat with the character by its name', true, true);
|
||||
parser.addCommand('sysgen', generateSystemMessage, [], '<span class="monospace">(prompt)</span> – generates a system message using a specified prompt', true, true);
|
||||
parser.addCommand('delname', deleteMessagesByNameCallback, ['cancel'], '<span class="monospace">(name)</span> – deletes all messages attributed to a specified name', true, true);
|
||||
|
||||
const NARRATOR_NAME_KEY = 'narrator_name';
|
||||
const NARRATOR_NAME_DEFAULT = 'System';
|
||||
const COMMENT_NAME_DEFAULT = 'Note';
|
||||
|
||||
async function deleteMessagesByNameCallback(_, name) {
|
||||
if (!name) {
|
||||
console.warn('WARN: No name provided for /delname command');
|
||||
return;
|
||||
}
|
||||
|
||||
name = name.trim();
|
||||
|
||||
const messagesToDelete = [];
|
||||
chat.forEach((value) => {
|
||||
if (value.name === name) {
|
||||
messagesToDelete.push(value);
|
||||
}
|
||||
});
|
||||
|
||||
if (!messagesToDelete.length) {
|
||||
console.debug('/delname: Nothing to delete');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const message of messagesToDelete) {
|
||||
const index = chat.indexOf(message);
|
||||
if (index !== -1) {
|
||||
console.debug(`/delname: Deleting message #${index}`, message);
|
||||
chat.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
await saveChatConditional();
|
||||
await reloadCurrentChat();
|
||||
|
||||
toastr.info(`Deleted ${messagesToDelete.length} messages from ${name}`);
|
||||
}
|
||||
|
||||
function findCharacterIndex(name) {
|
||||
const matchTypes = [
|
||||
(a, b) => a === b,
|
||||
|
@@ -311,7 +311,7 @@ function appendTagToList(listElement, tag, { removable, selectable, action, isGe
|
||||
}
|
||||
|
||||
if (tag.excluded) {
|
||||
isGeneralList ? $(tagElement).addClass('excluded') : $(listElement).parent().parent().addClass('hiddenByTag');
|
||||
isGeneralList ? $(tagElement).addClass('excluded') : $(listElement).closest('.character_select, .group_select').addClass('hiddenByTag');
|
||||
}
|
||||
|
||||
if (selectable) {
|
||||
@@ -329,7 +329,7 @@ function appendTagToList(listElement, tag, { removable, selectable, action, isGe
|
||||
$(listElement).append(tagElement);
|
||||
}
|
||||
|
||||
function onTagFilterClick(listElement, characterSelector) {
|
||||
function onTagFilterClick(listElement, characterSelector) {
|
||||
let excludeTag;
|
||||
if ($(this).hasClass('selected')) {
|
||||
$(this).removeClass('selected');
|
||||
|
@@ -38,6 +38,9 @@ let textgenerationwebui_settings = {
|
||||
skip_special_tokens: true,
|
||||
streaming: false,
|
||||
streaming_url: 'ws://127.0.0.1:5005/api/v1/stream',
|
||||
mirostat_mode: 0,
|
||||
mirostat_tau: 5,
|
||||
mirostat_eta: 0.1,
|
||||
};
|
||||
|
||||
let textgenerationwebui_presets = [];
|
||||
@@ -67,6 +70,9 @@ const setting_names = [
|
||||
"skip_special_tokens",
|
||||
"streaming",
|
||||
"streaming_url",
|
||||
"mirostat_mode",
|
||||
"mirostat_tau",
|
||||
"mirostat_eta",
|
||||
];
|
||||
|
||||
function selectPreset(name) {
|
||||
@@ -224,5 +230,8 @@ export function getTextGenGenerationData(finalPromt, this_amount_gen, isImperson
|
||||
'tfs': textgenerationwebui_settings.tfs,
|
||||
'epsilon_cutoff': textgenerationwebui_settings.epsilon_cutoff,
|
||||
'eta_cutoff': textgenerationwebui_settings.eta_cutoff,
|
||||
'mirostat_mode': textgenerationwebui_settings.mirostat_mode,
|
||||
'mirostat_tau': textgenerationwebui_settings.mirostat_tau,
|
||||
'mirostat_eta': textgenerationwebui_settings.mirostat_eta,
|
||||
};
|
||||
}
|
||||
|
@@ -86,6 +86,10 @@ export async function parseJsonFile(file) {
|
||||
}
|
||||
|
||||
export function getStringHash(str, seed = 0) {
|
||||
if (typeof str !== 'string') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let h1 = 0xdeadbeef ^ seed,
|
||||
h2 = 0x41c6ce57 ^ seed;
|
||||
for (let i = 0, ch; i < str.length; i++) {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { saveSettings, callPopup, substituteParams, getTokenCount, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type } from "../script.js";
|
||||
import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, delay, getCharaFilename, deepClone } from "./utils.js";
|
||||
import { getContext } from "./extensions.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from "./extensions/floating-prompt/index.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from "./authors-note.js";
|
||||
import { registerSlashCommand } from "./slash-commands.js";
|
||||
import { deviceInfo } from "./RossAscends-mods.js";
|
||||
|
||||
@@ -961,9 +961,13 @@ async function checkWorldInfo(chat, maxContext) {
|
||||
console.debug(`uid:${entry.uid}: checking logic: ${entry.selectiveLogic}`)
|
||||
secondary: for (let keysecondary of entry.keysecondary) {
|
||||
const secondarySubstituted = substituteParams(keysecondary);
|
||||
console.debug(`uid:${entry.uid}: filtering ${secondarySubstituted}`)
|
||||
console.debug(`uid:${entry.uid}: filtering ${secondarySubstituted}`);
|
||||
|
||||
// If selectiveLogic isn't found, assume it's AND
|
||||
const selectiveLogic = entry.selectiveLogic ?? 0;
|
||||
|
||||
//AND operator
|
||||
if (entry.selectiveLogic === 0) {
|
||||
if (selectiveLogic === 0) {
|
||||
console.debug('saw AND logic, checking..')
|
||||
if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) {
|
||||
console.log(`activating entry ${entry.uid} with AND found`)
|
||||
@@ -972,7 +976,7 @@ async function checkWorldInfo(chat, maxContext) {
|
||||
}
|
||||
}
|
||||
//NOT operator
|
||||
if (entry.selectiveLogic === 1) {
|
||||
if (selectiveLogic === 1) {
|
||||
console.debug(`uid ${entry.uid}: checking NOT logic for ${secondarySubstituted}`)
|
||||
if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) {
|
||||
console.debug(`uid ${entry.uid}: canceled; filtered out by ${secondarySubstituted}`)
|
||||
|
116
public/style.css
116
public/style.css
@@ -548,7 +548,7 @@ hr {
|
||||
#options,
|
||||
#extensionsMenu {
|
||||
display: flex;
|
||||
z-index: 100;
|
||||
z-index: 29999;
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
-webkit-backdrop-filter: blur(var(--SmartThemeBlurStrength));
|
||||
backdrop-filter: blur(var(--SmartThemeBlurStrength));
|
||||
@@ -695,6 +695,7 @@ hr {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#avatars-style .range-block-range,
|
||||
@@ -1205,6 +1206,7 @@ body.charListGrid #rm_print_characters_block {
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select {
|
||||
@@ -1264,6 +1266,67 @@ body.charListGrid #rm_print_characters_block .tags_inline {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#floatingPrompt {
|
||||
overflow-y: auto;
|
||||
max-width: 90svw;
|
||||
max-height: 90svh;
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--white30a);
|
||||
position: fixed;
|
||||
padding: 10px;
|
||||
padding-top: 25px;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 0 10px var(--black70a);
|
||||
z-index: 3000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin: 0;
|
||||
right: unset;
|
||||
width: calc(((100svw - var(--sheldWidth)) / 2) - 1px);
|
||||
|
||||
}
|
||||
|
||||
.floating_prompt_radio_group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#extension_floating_counter {
|
||||
font-weight: 600;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.extension_token_counter {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.floating_prompt_settings textarea {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#ANClose {
|
||||
height: 15px;
|
||||
aspect-ratio: 1 / 1;
|
||||
font-size: 20px;
|
||||
opacity: 0.5;
|
||||
transition: all 250ms;
|
||||
}
|
||||
|
||||
#ANClose:hover {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#floatingPrompt .drag-grabber {
|
||||
position: unset;
|
||||
}
|
||||
|
||||
/* ################################################################*/
|
||||
/* CUSTOMIZE THE DROPDOWN SELECT COLORS FOR RIGHT MENU
|
||||
/*#################################################################*/
|
||||
@@ -1563,6 +1626,7 @@ body.big-avatars .ch_description {
|
||||
cursor: pointer;
|
||||
aspect-ratio: 16/9;
|
||||
justify-content: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.BGSampleTitle {
|
||||
@@ -1579,12 +1643,10 @@ body.big-avatars .ch_description {
|
||||
font-size: calc(var(--fontScale) * 0.9em);
|
||||
}
|
||||
|
||||
.bg_example_cross {
|
||||
.bg_button {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
position: relative;
|
||||
/* float: right; */
|
||||
right: 10px;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
cursor: pointer;
|
||||
opacity: 0.7;
|
||||
@@ -1595,6 +1657,19 @@ body.big-avatars .ch_description {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
filter: drop-shadow(0px 0px 3px white);
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.bg_button:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.bg_example_cross {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.bg_example_edit {
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.no-border {
|
||||
@@ -2660,6 +2735,7 @@ input[type="range"]::-webkit-slider-thumb {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 5px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#anchor_checkbox label,
|
||||
@@ -3594,12 +3670,13 @@ span.warning {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
#talkativeness_hint {
|
||||
.slider_hint {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#talkativeness_expander {
|
||||
@@ -3611,21 +3688,14 @@ span.warning {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#talkativeness_hint span {
|
||||
min-width: 10em;
|
||||
.slider_hint span {
|
||||
font-size: calc(var(--mainFontSize) - .25rem);
|
||||
}
|
||||
|
||||
#talkativeness_hint span:nth-child(1) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#talkativeness_hint span:nth-child(2) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#talkativeness_hint span:nth-child(3) {
|
||||
text-align: right;
|
||||
.slider_hint span:nth-child(2) {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -4062,6 +4132,7 @@ input.extension_missing[type="checkbox"] {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inline-drawer-content {
|
||||
@@ -4096,7 +4167,7 @@ input.extension_missing[type="checkbox"] {
|
||||
margin: 0 auto;
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
|
||||
-webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
|
||||
z-index: 9999 !important;
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
/*to prevent draggables from being made too small to see*/
|
||||
@@ -4702,7 +4773,7 @@ body.waifuMode .zoomed_avatar {
|
||||
}
|
||||
|
||||
.zoomed_avatar img {
|
||||
border: 1px solid var(--white50a);
|
||||
/* border: 1px solid var(--white50a); */
|
||||
border-radius: 20px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -4856,6 +4927,7 @@ body.waifuMode .zoomed_avatar {
|
||||
align-items: start;
|
||||
height: min-content;
|
||||
align-content: start;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
#top-settings-holder,
|
||||
@@ -4991,10 +5063,6 @@ body.waifuMode .zoomed_avatar {
|
||||
max-height: 190px;
|
||||
}
|
||||
|
||||
#talkativeness_hint span {
|
||||
min-width: 33%;
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||
}
|
||||
|
145
server.js
145
server.js
@@ -262,6 +262,7 @@ const directories = {
|
||||
thumbnailsBg: 'thumbnails/bg/',
|
||||
thumbnailsAvatar: 'thumbnails/avatar/',
|
||||
themes: 'public/themes',
|
||||
movingUI: 'public/movingUI',
|
||||
extensions: 'public/scripts/extensions',
|
||||
instruct: 'public/instruct',
|
||||
context: 'public/context',
|
||||
@@ -395,7 +396,7 @@ app.post("/generate", jsonParser, async function (request, response_generate = r
|
||||
const controller = new AbortController();
|
||||
request.socket.removeAllListeners('close');
|
||||
request.socket.on('close', async function () {
|
||||
if (request.body.can_abort && !response_generate.finished) {
|
||||
if (request.body.can_abort && !response_generate.writableEnded) {
|
||||
try {
|
||||
console.log('Aborting Kobold generation...');
|
||||
// send abort signal to koboldcpp
|
||||
@@ -765,7 +766,7 @@ function convertToV2(char) {
|
||||
tags: char.tags,
|
||||
});
|
||||
|
||||
result.chat = char.chat;
|
||||
result.chat = char.chat ?? humanizedISO8601DateTime();
|
||||
result.create_date = char.create_date;
|
||||
return result;
|
||||
}
|
||||
@@ -825,6 +826,8 @@ function readFromV2(char) {
|
||||
char[charField] = v2Value;
|
||||
});
|
||||
|
||||
char['chat'] = char['chat'] ?? humanizedISO8601DateTime();
|
||||
|
||||
return char;
|
||||
}
|
||||
|
||||
@@ -1075,7 +1078,7 @@ app.post("/editcharacterattribute", jsonParser, async function (request, respons
|
||||
charaWrite(avatarPath, char, (request.body.avatar_url).replace('.png', ''), response, 'Character saved');
|
||||
}).catch((err) => {
|
||||
console.error('An error occured, character edit invalidated.', err);
|
||||
} );
|
||||
});
|
||||
}
|
||||
catch {
|
||||
console.error('An error occured, character edit invalidated.');
|
||||
@@ -1404,40 +1407,44 @@ app.post("/delchat", jsonParser, function (request, response) {
|
||||
return response.send('ok');
|
||||
});
|
||||
|
||||
app.post('/renamebackground', jsonParser, function (request, response) {
|
||||
if (!request.body) return response.sendStatus(400);
|
||||
|
||||
const oldFileName = path.join('public/backgrounds/', sanitize(request.body.old_bg));
|
||||
const newFileName = path.join('public/backgrounds/', sanitize(request.body.new_bg));
|
||||
|
||||
if (!fs.existsSync(oldFileName)) {
|
||||
console.log('BG file not found');
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
if (fs.existsSync(newFileName)) {
|
||||
console.log('New BG file already exists');
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
fs.renameSync(oldFileName, newFileName);
|
||||
invalidateThumbnail('bg', request.body.old_bg);
|
||||
return response.send('ok');
|
||||
});
|
||||
|
||||
app.post("/downloadbackground", urlencodedParser, function (request, response) {
|
||||
response_dw_bg = response;
|
||||
if (!request.body) return response.sendStatus(400);
|
||||
|
||||
let filedata = request.file;
|
||||
//console.log(filedata.mimetype);
|
||||
var fileType = ".png";
|
||||
var img_file = "ai";
|
||||
var img_path = "public/img/";
|
||||
|
||||
img_path = "uploads/";
|
||||
img_file = filedata.filename;
|
||||
if (filedata.mimetype == "image/jpeg") fileType = ".jpeg";
|
||||
if (filedata.mimetype == "image/png") fileType = ".png";
|
||||
if (filedata.mimetype == "image/gif") fileType = ".gif";
|
||||
if (filedata.mimetype == "image/bmp") fileType = ".bmp";
|
||||
fs.copyFile(img_path + img_file, 'public/backgrounds/' + img_file + fileType, (err) => {
|
||||
invalidateThumbnail('bg', img_file + fileType);
|
||||
if (err) {
|
||||
|
||||
return console.log(err);
|
||||
} else {
|
||||
//console.log(img_file+fileType);
|
||||
response_dw_bg.send(img_file + fileType);
|
||||
}
|
||||
//console.log('The image was copied from temp directory.');
|
||||
});
|
||||
if (!request.body || !request.file) return response.sendStatus(400);
|
||||
|
||||
const img_path = path.join("uploads/", request.file.filename);
|
||||
const filename = request.file.originalname;
|
||||
|
||||
try {
|
||||
fs.copyFileSync(img_path, path.join('public/backgrounds/', filename));
|
||||
invalidateThumbnail('bg', filename);
|
||||
response_dw_bg.send(filename);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
response_dw_bg.sendStatus(500);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
app.post("/savesettings", jsonParser, function (request, response) {
|
||||
fs.writeFile('public/settings.json', JSON.stringify(request.body, null, 4), 'utf8', function (err) {
|
||||
if (err) {
|
||||
@@ -1494,6 +1501,10 @@ function sortByModifiedDate(directory) {
|
||||
return (a, b) => new Date(fs.statSync(`${directory}/${b}`).mtime) - new Date(fs.statSync(`${directory}/${a}`).mtime);
|
||||
}
|
||||
|
||||
function sortByName(_) {
|
||||
return (a, b) => a.localeCompare(b);
|
||||
}
|
||||
|
||||
function readPresetsFromDirectory(directoryPath, options = {}) {
|
||||
const {
|
||||
sortFunction,
|
||||
@@ -1530,7 +1541,7 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||
// NovelAI Settings
|
||||
const { fileContents: novelai_settings, fileNames: novelai_setting_names }
|
||||
= readPresetsFromDirectory(directories.novelAI_Settings, {
|
||||
sortFunction: sortByModifiedDate(directories.novelAI_Settings),
|
||||
sortFunction: sortByName(directories.novelAI_Settings),
|
||||
removeFileExtension: true
|
||||
});
|
||||
|
||||
@@ -1543,13 +1554,13 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||
// TextGenerationWebUI Settings
|
||||
const { fileContents: textgenerationwebui_presets, fileNames: textgenerationwebui_preset_names }
|
||||
= readPresetsFromDirectory(directories.textGen_Settings, {
|
||||
sortFunction: sortByModifiedDate(directories.textGen_Settings), removeFileExtension: true
|
||||
sortFunction: sortByName(directories.textGen_Settings), removeFileExtension: true
|
||||
});
|
||||
|
||||
//Kobold
|
||||
const { fileContents: koboldai_settings, fileNames: koboldai_setting_names }
|
||||
= readPresetsFromDirectory(directories.koboldAI_Settings, {
|
||||
sortFunction: sortByModifiedDate(directories.koboldAI_Settings), removeFileExtension: true
|
||||
sortFunction: sortByName(directories.koboldAI_Settings), removeFileExtension: true
|
||||
})
|
||||
|
||||
const worldFiles = fs
|
||||
@@ -1559,6 +1570,7 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||
const world_names = worldFiles.map(item => path.parse(item).name);
|
||||
|
||||
const themes = readAndParseFromDirectory(directories.themes);
|
||||
const movingUIPresets = readAndParseFromDirectory(directories.movingUI);
|
||||
const instruct = readAndParseFromDirectory(directories.instruct);
|
||||
const context = readAndParseFromDirectory(directories.context);
|
||||
|
||||
@@ -1574,6 +1586,7 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||
textgenerationwebui_presets,
|
||||
textgenerationwebui_preset_names,
|
||||
themes,
|
||||
movingUIPresets,
|
||||
instruct,
|
||||
context,
|
||||
enable_extensions: enableExtensions,
|
||||
@@ -1619,6 +1632,17 @@ app.post('/savetheme', jsonParser, (request, response) => {
|
||||
return response.sendStatus(200);
|
||||
});
|
||||
|
||||
app.post('/savemovingui', jsonParser, (request, response) => {
|
||||
if (!request.body || !request.body.name) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const filename = path.join(directories.movingUI, sanitize(request.body.name) + '.json');
|
||||
fs.writeFileSync(filename, JSON.stringify(request.body, null, 4), 'utf8');
|
||||
|
||||
return response.sendStatus(200);
|
||||
});
|
||||
|
||||
function convertWorldInfoToCharacterBook(name, entries) {
|
||||
const result = { entries: [], name };
|
||||
|
||||
@@ -3469,9 +3493,26 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
||||
|
||||
function handleError(error, response_generate_openai, request) {
|
||||
console.error('Error:', error.message);
|
||||
|
||||
let message = error?.response?.statusText;
|
||||
|
||||
switch (error?.response?.status) {
|
||||
case 402:
|
||||
message = 'Credit limit reached';
|
||||
console.log(message);
|
||||
break;
|
||||
case 403:
|
||||
message = 'API key disabled or exhausted';
|
||||
console.log(message);
|
||||
break;
|
||||
}
|
||||
|
||||
const quota_error = error?.response?.status === 429 && error?.response?.data?.error?.type === 'insufficient_quota';
|
||||
const response = { error: { message }, quota_error: quota_error }
|
||||
if (!response_generate_openai.headersSent) {
|
||||
response_generate_openai.send({ error: true, quota_error: quota_error });
|
||||
response_generate_openai.send(response);
|
||||
} else if (!response_generate_openai.writableEnded) {
|
||||
response_generate_openai.write(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3544,7 +3585,7 @@ function createTokenizationHandler(getTokenizerFn) {
|
||||
app.post("/tokenize_llama", jsonParser, createTokenizationHandler(() => spp_llama));
|
||||
app.post("/tokenize_nerdstash", jsonParser, createTokenizationHandler(() => spp_nerd));
|
||||
app.post("/tokenize_nerdstash_v2", jsonParser, createTokenizationHandler(() => spp_nerd_v2));
|
||||
app.post("/tokenize_via_api", jsonParser, async function(request, response) {
|
||||
app.post("/tokenize_via_api", jsonParser, async function (request, response) {
|
||||
if (!request.body) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
@@ -3552,7 +3593,7 @@ app.post("/tokenize_via_api", jsonParser, async function(request, response) {
|
||||
|
||||
try {
|
||||
const args = {
|
||||
body: JSON.stringify({"prompt": text}),
|
||||
body: JSON.stringify({ "prompt": text }),
|
||||
headers: { "Content-Type": "application/json" }
|
||||
};
|
||||
|
||||
@@ -4542,22 +4583,22 @@ async function getManifest(extensionPath) {
|
||||
}
|
||||
|
||||
async function checkIfRepoIsUpToDate(extensionPath) {
|
||||
const git = simpleGit();
|
||||
await git.cwd(extensionPath).fetch('origin');
|
||||
const currentBranch = await git.cwd(extensionPath).branch();
|
||||
const currentCommitHash = await git.cwd(extensionPath).revparse(['HEAD']);
|
||||
const log = await git.cwd(extensionPath).log({
|
||||
from: currentCommitHash,
|
||||
to: `origin/${currentBranch.current}`,
|
||||
});
|
||||
const git = simpleGit();
|
||||
await git.cwd(extensionPath).fetch('origin');
|
||||
const currentBranch = await git.cwd(extensionPath).branch();
|
||||
const currentCommitHash = await git.cwd(extensionPath).revparse(['HEAD']);
|
||||
const log = await git.cwd(extensionPath).log({
|
||||
from: currentCommitHash,
|
||||
to: `origin/${currentBranch.current}`,
|
||||
});
|
||||
|
||||
// Fetch remote repository information
|
||||
const remotes = await git.cwd(extensionPath).getRemotes(true);
|
||||
// Fetch remote repository information
|
||||
const remotes = await git.cwd(extensionPath).getRemotes(true);
|
||||
|
||||
return {
|
||||
isUpToDate: log.total === 0,
|
||||
remoteUrl: remotes[0].refs.fetch, // URL of the remote repository
|
||||
};
|
||||
return {
|
||||
isUpToDate: log.total === 0,
|
||||
remoteUrl: remotes[0].refs.fetch, // URL of the remote repository
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -4672,7 +4713,7 @@ app.post('/get_extension_version', jsonParser, async (request, response) => {
|
||||
const extensionPath = path.join(directories.extensions, 'third-party', extensionName);
|
||||
|
||||
if (!fs.existsSync(extensionPath)) {
|
||||
return response.status(404).send(`Directory does not exist at ${extensionPath}`);
|
||||
return response.status(404).send(`Directory does not exist at ${extensionPath}`);
|
||||
}
|
||||
|
||||
const currentBranch = await git.cwd(extensionPath).branch();
|
||||
@@ -4689,7 +4730,7 @@ app.post('/get_extension_version', jsonParser, async (request, response) => {
|
||||
console.log('Getting extension version failed', error);
|
||||
return response.status(500).send(`Server Error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user