Merge pull request #1223 from SillyTavern/staging

Staging
This commit is contained in:
Cohee 2023-10-08 21:08:26 +03:00 committed by GitHub
commit c9c4f30637
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 2980 additions and 874 deletions

View File

@ -406,7 +406,6 @@
"tfs": 1,
"rep_pen_slope": 0,
"single_line": false,
"use_stop_sequence": false,
"streaming_kobold": false,
"sampler_order": [
6,
@ -416,7 +415,12 @@
3,
4,
5
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"use_default_badwordsids": false,
"grammar": ""
},
"oai_settings": {
"preset_settings_openai": "Default",

249
package-lock.json generated
View File

@ -1,18 +1,19 @@
{
"name": "sillytavern",
"version": "1.10.4",
"version": "1.10.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sillytavern",
"version": "1.10.4",
"version": "1.10.5",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
"@agnai/sentencepiece-js": "^1.1.1",
"@agnai/web-tokenizers": "^0.1.3",
"@dqbd/tiktoken": "^1.0.2",
"bing-translate-api": "^2.9.1",
"command-exists": "^1.2.9",
"compression": "^1",
"cookie-parser": "^1.4.6",
@ -694,11 +695,57 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
"node_modules/@sindresorhus/is": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
"node_modules/@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
"dependencies": {
"defer-to-connect": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"node_modules/@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
"dependencies": {
"@types/http-cache-semantics": "*",
"@types/keyv": "^3.1.4",
"@types/node": "*",
"@types/responselike": "^1.0.0"
}
},
"node_modules/@types/http-cache-semantics": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz",
"integrity": "sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw=="
},
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/long": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
@ -709,6 +756,14 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
},
"node_modules/@types/responselike": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.1.tgz",
"integrity": "sha512-TiGnitEDxj2X0j+98Eqk5lv/Cij8oHd32bU4D/Yw6AOq7vvTk0gSD2GPj0G/HkvhMoVsdlhYF4yqqlyPBTM6Sg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -858,6 +913,14 @@
}
]
},
"node_modules/bing-translate-api": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/bing-translate-api/-/bing-translate-api-2.9.1.tgz",
"integrity": "sha512-DaYqa7iupfj+fj/KeaeZSp5FUY/ZR4sZ6jqoTP0RHkYOUfo7wwoxlhYDkh4VcvBBzuVORnBEgdXBVQrfM4kk7g==",
"dependencies": {
"got": "^11.8.6"
}
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@ -999,6 +1062,31 @@
"node": ">= 0.8"
}
},
"node_modules/cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
"engines": {
"node": ">=10.6.0"
}
},
"node_modules/cacheable-request": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
"dependencies": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@ -1082,6 +1170,25 @@
"node": ">=12"
}
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"dependencies": {
"mimic-response": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/clone-response/node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -1290,7 +1397,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dev": true,
"dependencies": {
"mimic-response": "^3.1.0"
},
@ -1310,6 +1416,14 @@
"node": ">=4.0.0"
}
},
"node_modules/defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
"engines": {
"node": ">=10"
}
},
"node_modules/define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@ -1458,7 +1572,6 @@
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"dependencies": {
"once": "^1.4.0"
}
@ -1774,6 +1887,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/gifwrap": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
@ -1835,6 +1962,30 @@
"resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz",
"integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A=="
},
"node_modules/got": {
"version": "11.8.6",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
"dependencies": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=10.19.0"
},
"funding": {
"url": "https://github.com/sindresorhus/got?sponsor=1"
}
},
"node_modules/gpt-3-encoder": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/gpt-3-encoder/-/gpt-3-encoder-1.1.4.tgz",
@ -1922,6 +2073,11 @@
"entities": "^4.4.0"
}
},
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -1937,6 +2093,18 @@
"node": ">= 0.8"
}
},
"node_modules/http2-wrapper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
"dependencies": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
},
"engines": {
"node": ">=10.19.0"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
@ -2196,6 +2364,11 @@
"node": ">=4"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"node_modules/json-colorizer": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-2.2.2.tgz",
@ -2284,6 +2457,14 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/keyv": {
"version": "4.5.3",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
"integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
"dependencies": {
"json-buffer": "3.0.1"
}
},
"node_modules/load-bmfont": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
@ -2314,6 +2495,14 @@
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"engines": {
"node": ">=8"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -2403,7 +2592,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"dev": true,
"engines": {
"node": ">=10"
},
@ -2549,6 +2737,17 @@
}
}
},
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@ -2604,7 +2803,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -2682,6 +2880,14 @@
"follow-redirects": "^1.14.8"
}
},
"node_modules/p-cancelable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
"engines": {
"node": ">=8"
}
},
"node_modules/p-is-promise": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
@ -3108,7 +3314,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@ -3148,6 +3353,17 @@
}
]
},
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -3265,6 +3481,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
},
"node_modules/resolve/node_modules/is-core-module": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
@ -3297,6 +3518,17 @@
"node": ">= 0.6"
}
},
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"dependencies": {
"lowercase-keys": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -3905,8 +4137,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/write-file-atomic": {
"version": "5.0.1",

View File

@ -11,6 +11,7 @@
"device-detector-js": "^3.0.3",
"express": "^4.18.2",
"google-translate-api-browser": "^3.0.1",
"bing-translate-api": "^2.9.1",
"gpt3-tokenizer": "^1.1.5",
"ip-matching": "^2.1.2",
"ipaddr.js": "^2.0.1",
@ -46,7 +47,7 @@
"type": "git",
"url": "https://github.com/SillyTavern/SillyTavern.git"
},
"version": "1.10.4",
"version": "1.10.5",
"scripts": {
"start": "node server.js",
"start-multi": "node server.js --disableCsrf",

View File

@ -1,12 +1,12 @@
{
"temp": 1.15,
"top_k": 0,
"top_p": 0.95,
"top_a": 0,
"typical": 1,
"tfs": 0.8,
"rep_pen": 1.05,
"rep_pen_range": 2048,
"top_p": 0.95,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.8,
"rep_pen_slope": 7,
"sampler_order": [
6,
@ -16,5 +16,9 @@
5,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.59,
"top_k": 0,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.87,
"rep_pen": 1.1,
"rep_pen_range": 2048,
"top_p": 1,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.87,
"rep_pen_slope": 0.3,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.8,
"top_k": 100,
"top_p": 0.9,
"top_a": 0,
"typical": 1,
"tfs": 1,
"rep_pen": 1.15,
"rep_pen_range": 2048,
"top_p": 0.9,
"top_a": 0,
"top_k": 100,
"typical": 1,
"tfs": 1,
"rep_pen_slope": 3.4,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.51,
"top_p": 1,
"top_k": 0,
"tfs": 0.99,
"top_a": 0,
"typical": 1,
"rep_pen": 1.2,
"rep_pen_range": 2048,
"top_p": 1,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.99,
"rep_pen_slope": 0,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"single_line": false,
"sampler_order": [
6,
0,
@ -17,5 +16,9 @@
4,
2,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.63,
"top_k": 0,
"top_p": 0.98,
"top_a": 0,
"typical": 1,
"tfs": 0.98,
"rep_pen": 1.05,
"rep_pen_range": 2048,
"top_p": 0.98,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.98,
"rep_pen_slope": 0.1,
"sampler_order": [
6,
@ -16,5 +16,9 @@
5,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.7,
"top_k": 0,
"top_p": 0.5,
"top_a": 0.75,
"typical": 0.19,
"tfs": 0.97,
"rep_pen": 1.1,
"rep_pen_range": 1024,
"top_p": 0.5,
"top_a": 0.75,
"top_k": 0,
"typical": 0.19,
"tfs": 0.97,
"rep_pen_slope": 0.7,
"sampler_order": [
6,
@ -16,5 +16,9 @@
2,
1,
0
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.7,
"top_k": 0,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.9,
"rep_pen": 1.1,
"rep_pen_range": 1024,
"top_p": 1,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.9,
"rep_pen_slope": 0.7,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
4,
5
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.66,
"top_k": 0,
"top_p": 1,
"top_a": 0.96,
"typical": 0.6,
"tfs": 1,
"rep_pen": 1.1,
"rep_pen_range": 1024,
"top_p": 1,
"top_a": 0.96,
"top_k": 0,
"typical": 0.6,
"tfs": 1,
"rep_pen_slope": 0.7,
"sampler_order": [
6,
@ -16,5 +16,9 @@
0,
2,
3
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.94,
"top_k": 12,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.94,
"rep_pen": 1.05,
"rep_pen_range": 2048,
"top_p": 1,
"top_a": 0,
"top_k": 12,
"typical": 1,
"tfs": 0.94,
"rep_pen_slope": 0.2,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 1.5,
"top_k": 85,
"top_p": 0.24,
"top_a": 0,
"typical": 1,
"tfs": 1,
"rep_pen": 1.1,
"rep_pen_range": 2048,
"top_p": 0.24,
"top_a": 0,
"top_k": 85,
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 1.05,
"top_k": 0,
"top_p": 0.95,
"top_a": 0,
"typical": 1,
"tfs": 1,
"rep_pen": 1.1,
"rep_pen_range": 1024,
"top_p": 0.95,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0.7,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
4,
5
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0.9,
"single_line": false,
"sampler_order": [
6,
0,
@ -21,5 +20,5 @@
"mirostat": 2,
"mirostat_tau": 9.61,
"mirostat_eta": 1,
"use_default_badwordsids": true
}
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0.9,
"single_line": false,
"sampler_order": [
6,
0,
@ -21,5 +20,5 @@
"mirostat": 2,
"mirostat_tau": 9.91,
"mirostat_eta": 1,
"use_default_badwordsids": true
}
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0.9,
"single_line": false,
"sampler_order": [
6,
0,
@ -21,5 +20,5 @@
"mirostat": 2,
"mirostat_tau": 9.62,
"mirostat_eta": 1,
"use_default_badwordsids": true
}
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 1.07,
"top_k": 100,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.93,
"rep_pen": 1.05,
"rep_pen_range": 404,
"top_p": 1,
"top_a": 0,
"top_k": 100,
"typical": 1,
"tfs": 0.93,
"rep_pen_slope": 0.8,
"sampler_order": [
6,
@ -16,5 +16,9 @@
2,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.44,
"top_k": 0,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.9,
"rep_pen": 1.15,
"rep_pen_range": 2048,
"top_p": 1,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.9,
"rep_pen_slope": 6.8,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 1.35,
"top_k": 0,
"top_p": 1,
"top_a": 0,
"typical": 1,
"tfs": 0.69,
"rep_pen": 1.15,
"rep_pen_range": 2048,
"top_p": 1,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 0.69,
"rep_pen_slope": 0.1,
"sampler_order": [
6,
@ -16,5 +16,9 @@
0,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 1,
"top_k": 0,
"top_p": 0.95,
"top_a": 0,
"typical": 1,
"tfs": 1,
"rep_pen": 1.1,
"rep_pen_range": 600,
"top_p": 0.95,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
4,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"single_line": false,
"sampler_order": [
6,
0,
@ -17,5 +16,9 @@
4,
2,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -1,12 +1,12 @@
{
"temp": 0.72,
"tfs": 1,
"top_a": 0,
"top_k": 0,
"top_p": 0.73,
"typical": 1,
"rep_pen": 1.1,
"rep_pen_range": 2048,
"top_p": 0.73,
"top_a": 0,
"top_k": 0,
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0.2,
"sampler_order": [
6,
@ -16,5 +16,9 @@
3,
1,
4
]
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 0.95,
"rep_pen_slope": 0,
"single_line": false,
"sampler_order": [
6,
0,
@ -17,5 +16,9 @@
4,
2,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"single_line": false,
"sampler_order": [
6,
0,
@ -17,5 +16,9 @@
4,
2,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -8,7 +8,6 @@
"typical": 1,
"tfs": 1,
"rep_pen_slope": 0,
"single_line": false,
"sampler_order": [
6,
0,
@ -17,5 +16,9 @@
4,
2,
5
]
}
],
"mirostat": 0,
"mirostat_tau": 5,
"mirostat_eta": 0.1,
"grammar": ""
}

View File

@ -0,0 +1,6 @@
{
"story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
"chat_start": "",
"example_separator": "",
"name": "Adventure"
}

View File

@ -0,0 +1,6 @@
{
"story_string": "<|im_start|>system\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}<|im_end|>",
"chat_start": "",
"example_separator": "",
"name": "ChatML"
}

View File

@ -0,0 +1,6 @@
{
"story_string": "### Instruction:\nWrite {{char}}'s next reply in this roleplay with {{user}}. Use the provided character sheet and example dialogue for formatting direction and character speech patterns.\n\n{{#if system}}{{system}}\n\n{{/if}}### Character Sheet:\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
"chat_start": "### START ROLEPLAY:",
"example_separator": "### Example:",
"name": "Libra-32B"
}

View File

@ -0,0 +1,6 @@
{
"story_string": "{{system}}\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{char}}'s description:{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality:{{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{user}}'s persona: {{persona}}\n{{/if}}",
"chat_start": "This is the history of the roleplay:",
"example_separator": "Example of an interaction:",
"name": "Lightning 1.1"
}

View File

@ -0,0 +1,6 @@
{
"story_string": "[INST] {{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}[/INST]",
"chat_start": "",
"example_separator": "Examples:",
"name": "Mistral"
}

View File

@ -0,0 +1,6 @@
{
"story_string": "{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}",
"chat_start": "",
"example_separator": "",
"name": "Story"
}

View File

@ -35,7 +35,7 @@
max-width: 90svw;
}
.world_entry_thin_controls,
/* .world_entry_thin_controls, */
#persona-management-block,
#character_popup .flex-container {
flex-direction: column;
@ -63,6 +63,15 @@
display: none;
}
.world_entry .inline-drawer-toggle {
padding-bottom: 5px;
}
#worldInfoScanningCheckboxes {
flex-flow: row;
flex-wrap: wrap;
}
body {
touch-action: none;
overflow: hidden;
@ -70,6 +79,10 @@
}
.world_entry_form_control {
/* width: 100%; */
}
.drawer-content {
min-width: unset;
width: 100%;
@ -125,6 +138,20 @@
.wi-settings {
flex-direction: column;
gap: 5px !important;
}
.WIEntryTitleAndStatus,
.WIEntryHeaderControls {
width: 100%;
}
#WIEntryHeaderTitlesPC {
display: none;
}
.WIEntryHeaderTitleMobile {
display: block !important;
}
#character_popup,
@ -311,8 +338,7 @@
min-width: 100px;
min-height: 100px;
max-height: 50vh;
max-width: 50vh;
width: 50vw;
max-width: 90vw;
position: absolute;
padding: 0;
filter: drop-shadow(2px 2px 2px #51515199);

View File

@ -6,6 +6,10 @@
color: var(--fullred);
}
.m-t-0 {
margin-top: 0;
}
.m-t-1 {
margin-top: 1em;
}
@ -99,6 +103,10 @@
align-self: start;
}
.gap3px {
gap: 3px !important;
}
.gap5px {
gap: 5px !important;
}
@ -120,6 +128,10 @@
max-width: 100px;
}
.width100px {
width: 100px;
}
.widthUnset {
width: unset;
}
@ -147,6 +159,10 @@
font-weight: 600;
}
.textAlignCenter {
text-align: center;
}
.margin-right-10px {
margin-right: 10px;
}
@ -230,6 +246,10 @@
overflow: hidden;
}
.padding0 {
padding: 0;
}
.padding5 {
padding: 5px;
}
@ -366,6 +386,11 @@
cursor: pointer;
}
input:disabled,
textarea:disabled {
cursor: not-allowed;
}
.debug-red {
border: 1px solid red !important;
}
@ -394,6 +419,11 @@
font-size: calc(var(--mainFontSize) * 0.6) !important;
}
.paddingBottom5px {
padding: unset;
padding-bottom: 5px;
}
.paddingTopBot5 {
padding: 5px 0;
}
@ -421,4 +451,4 @@
.opacity1 {
opacity: 1 !important;
}
}

View File

@ -101,7 +101,7 @@
height: auto;
margin-top: 0;
margin-bottom: 0;
min-height: 32px;
min-height: calc(var(--mainFontSize) + 13px);
}
.delete_entry_button {
@ -157,6 +157,37 @@
width: 10em;
}
#world_info_search {
width: 10em;
#world_info_search,
#world_info_sort_order {
width: 7em;
}
.wi-card-entry {
border: 1px solid;
border-color: var(--SmartThemeBorderColor);
border-radius: 10px;
padding: 0 5px;
margin-bottom: 1px;
}
.world_entry {
transition: opacity 500ms;
}
.disabledWIEntry {
opacity: 0.4;
filter: grayscale(1);
}
.disabledWIEntry:not(input):hover {
opacity: 1;
filter: grayscale(0.5);
}
.height32px {
height: 32px;
}
.WIEntryHeaderTitleMobile {
display: none;
}

View File

@ -20,7 +20,7 @@
"select": "选择 ",
"context size(tokens)": "上下文大小 (Toekns)",
"unlocked": "解锁",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "只有在选定的模型支持大于 2048 个Toekn 时可以选择启用,在启用该选项时,你应该知道自己在做什么。",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "只有在选定的模型支持大于 4096 个Toekn 时可以选择启用,在启用该选项时,你应该知道自己在做什么。",
"rep.pen": "频率惩罚",
"rep.pen range": "存在惩罚",
"temperature": "温度设置",
@ -70,6 +70,9 @@
"Streaming": "流式响应",
"Display the response bit by bit as it is generated.": "在生成响应时逐位显示响应。",
"When this is off, responses will be displayed all at once when they are complete.": "关闭此选项后,响应将在完成后立即显示所有响应。",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "每个请求仅生成一行(仅限 KoboldAI被 KoboldCpp 忽略)。",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "禁止序列结束 (EOS) 代币(使用 KoboldCpp也可能使用 KoboldAI 禁止其他代币)。",
"Good for story writing, but should not be used for chat and instruct mode.": "适合故事写作,但不应用于聊天和指导模式。",
"Enhance Definitions": "增强定义",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "使用 OpenAI 知识库增强公众人物和已知虚构人物的定义",
"Wrap in Quotes": "用引号包裹",
@ -571,7 +574,7 @@
"select": "選択 ",
"context size(tokens)": "コンテキストサイズ(トークン数)",
"unlocked": "解除",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "2048トークンより大きいコンテキストサイズをサポートするのは、一部のモデルのみです。このオプションを変更する前に、自分が何をしているかを理解してください。",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "4096トークンより大きいコンテキストサイズをサポートするのは、一部のモデルのみです。このオプションを変更する前に、自分が何をしているかを理解してください。",
"rep.pen": "Rep. Pen.",
"rep.pen range": "Rep. Pen. 範囲",
"temperature": "温度",
@ -620,6 +623,9 @@
"Streaming": "ストリーミング",
"Display the response bit by bit as it is generated.": "生成されると、レスポンスをビットごとに表示します。",
"When this is off, responses will be displayed all at once when they are complete.": "これをオフにすると、レスポンスは完了時に一度にすべて表示されます。",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "リクエストごとに 1 行のみ生成します (KoboldAI のみ、KoboldCpp では無視されます)。",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "End-of-Sequence (EOS) トークンを禁止します (KoboldCpp を使用し、場合によっては KoboldAI を使用する他のトークンも禁止します)。",
"Good for story writing, but should not be used for chat and instruct mode.": "ストーリーを書くのには適していますが、チャットや指示モードには使用しないでください。",
"Enhance Definitions": "定義を強化",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "公共人物および既知の架空のキャラクターの定義を強化するためにOAIの知識ベースを使用する",
"Wrap in Quotes": "引用符で囲む",
@ -1122,7 +1128,7 @@
"select": "선택",
"context size(tokens)": "맥락 크기(토큰수)",
"Unlocked Context Size": "한도 해제",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "토큰 2049개 이상의 맥락을 사용할 수 있는 모델에서만 사용하세요. 파워유저 옵션이에요.",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "토큰 4096개 이상의 맥락을 사용할 수 있는 모델에서만 사용하세요. 파워유저 옵션이에요.",
"rep.pen": "반복 페널티",
"rep.pen range": "반복 페널티 범위",
"temperature": "온도",
@ -1172,6 +1178,9 @@
"Streaming": "스트리밍",
"Display the response bit by bit as it is generated.": "답변이 생성되는 도중 실시간으로 출력합니다.",
"When this is off, responses will be displayed all at once when they are complete.": "이 옵션을 해지하면 답변이 완성된 다음 한 번에 출력합니다.",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "요청당 한 줄만 생성합니다(KoboldAI만 해당, KoboldCpp에서는 무시됨).",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "EOS(End-of-Sequence) 토큰(KoboldCpp 및 KoboldAI의 다른 토큰 포함)을 금지합니다.",
"Good for story writing, but should not be used for chat and instruct mode.": "스토리 작성에 적합하지만 채팅 및 교육 모드에는 사용하면 안 됩니다.",
"Enhance Definitions": "똑똑해지기",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "OpenAI 지식 데이터베이스를 활용하여 공공인물, 유명한 캐릭터 등 이미 알려진 정보를 사용합니다.",
"Wrap in Quotes": "자동 따옴표",
@ -1677,7 +1686,7 @@
"select": "Выбрать",
"context size(tokens)": "Размер контекста (в токенах)",
"unlocked": "Неограниченный",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Только отдельные модели поддерживают контекст, превышающий 2048 токенов. Используйте только если понимаете, что делаете.",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Только отдельные модели поддерживают контекст, превышающий 4096 токенов. Используйте только если понимаете, что делаете.",
"rep.pen": "Rep. Pen.",
"rep.pen range": "Диапазон Rep. Pen.",
"temperature": "Температура",
@ -1739,6 +1748,9 @@
"Streaming": "Потоковый вывод текста",
"Display the response bit by bit as it is generated.": "Отображать ответ по кускам в процессе генерации.",
"When this is off, responses will be displayed all at once when they are complete.": "Если данная функция отключена, ответ будет отображен полностью после генерации.",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Генерируйте только одну строку для каждого запроса (только KoboldAI, игнорируется KoboldCpp).",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Запретите токен конца последовательности (EOS) (с помощью KoboldCpp и, возможно, также других токенов с помощью KoboldAI).",
"Good for story writing, but should not be used for chat and instruct mode.": "Подходит для написания историй, но не должен использоваться в режиме чата и инструктирования.",
"Enhance Definitions": "Улучшенная узнаваемость",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Позволяет использовать базу знаний, улучшающую узнаваемость ИИ публичных лиц и вымышленных персонажей",
"Wrap in Quotes": "Заключать в кавычки",
@ -2299,8 +2311,8 @@
"response legth(tokens)": "lunghezza risposta (in Token)",
"select": "seleziona",
"context size(tokens)": "dimensione contesto (in Token)",
"unlocked": "sbloccato",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Seleziona il supporto ai modls soltanto se le dimenzioni contesto sono più grandi di 2048 token. Procedi soltanto se sai cosa stai facendo.",
"unlocked": "Sblocca",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Seleziona il supporto ai modls soltanto se le dimenzioni contesto sono più grandi di 4096 token. Procedi soltanto se sai cosa stai facendo.",
"rep.pen": "rep.pen",
"rep.pen range": "rep.pen range",
"temperature": "temperature",
@ -2330,7 +2342,7 @@
"Typical P": "Typical P",
"Do Sample": "Do Sample",
"Add BOS Token": "Aggiungi BOS Token",
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Aggiungi bos_token all'inizio di un prompt. Disabilitarlo potrebbe rendere le risposte più creative.",
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Aggiungi bos_token all'inizio di un prompt. Disattivarlo potrebbe rendere le risposte più creative.",
"Ban EOS Token": "Blocca EOS Token",
"Ban the eos_token. This forces the model to never end the generation prematurely": "Blocca eos_token. Questo costringe il modello a non concludere prematuramente la generazione del testo.",
"Skip Special Tokens": "Salta Token speciali",
@ -2350,6 +2362,9 @@
"Streaming": "Streaming",
"Display the response bit by bit as it is generated.": "Mostra la risposta mano a mano che viene generata.",
"When this is off, responses will be displayed all at once when they are complete.": "Quando questa casella è disattivata, le risposte vengono mostrate soltanto una volta che il testo è stato ultimato.",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genera solo una riga per richiesta (solo KoboldAI, ignorata da KoboldCpp).",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Bandire il token End-of-Sequence (EOS) (con KoboldCpp, ed eventualmente anche altri token con KoboldAI).",
"Good for story writing, but should not be used for chat and instruct mode.": "Buono per scrivere storie, ma non dovrebbe essere usato per la modalità chat e istruzioni.",
"Enhance Definitions": "Migliora le definizioni",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa la conoscenza di OpenAI per migliorare le definizioni di personaggi pubblici e personaggi immaginari famosi.",
"Wrap in Quotes": "Invia i messaggi tra virgolette",
@ -2364,7 +2379,7 @@
"Impersonation prompt": "Prompt per l'impersonificazione dell'utente",
"Prompt that is used for Impersonation function": "Prompt utilizzato per la funzione di impersonificazione dell'utente",
"Logit Bias": "Logit Bias",
"Helps to ban or reenforce the usage of certain words": "Aiuta a bloccare o rinforzare l'utilizzo di alcuni tipi di parole.",
"Helps to ban or reenforce the usage of certain words": "Aiuta a disincentivare o rinforzare l'utilizzo di alcuni tipi di parole.",
"View / Edit bias preset": "Mostra / Modifica bias preset",
"Add bias entry": "Aggiungi voce bias",
"Jailbreak activation message": "Messaggio d'attivazione del Jailbreak",
@ -2378,7 +2393,7 @@
"Use Horde": "Usa Horde",
"API url": "Url API",
"Register a Horde account for faster queue times": "Crea un account Horde per tempi di attesa più brevi",
"Learn how to contribute your idle GPU cycles to the Hord": "Impara come fare in modo di usare i tuoi cicli GPU in idle per contribuire a Horde",
"Learn how to contribute your idle GPU cycles to the Hord": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
"Adjust context size to worker capabilities": "Sistema la grandezza del contesto alle sue capacità operazionali",
"Adjust response length to worker capabilities": "Sistema la lunghezza della risposta alle sue capacità operazionali",
"API key": "Chiave API",
@ -2391,15 +2406,17 @@
"Novel API key": "NovelAI API key",
"Follow": "Segui",
"these directions": "questi suggerimenti",
"to get your NovelAI API key.": "per acquisire la chiave API di NovelAI.",
"to get your NovelAI API key.": "per ottenere la chiave API di NovelAI.",
"Enter it in the box below": "Inserisci la chiave all'interno della casella qui sotto",
"Novel AI Model": "Modello di NovelAI",
"Euterpe": "Euterpe",
"Krake": "Krake",
"No connection": "Nessuna connessione",
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
"Make sure you run it with": "assicurati di farlo partire con",
"Blocking API url": "Bloccare l'indirizzo API",
"Blocking API url": "Blocca l'indirizzo API",
"Streaming API url": "Streaming dell'indirizzo API",
"to get your OpenAI API key.": "per acquisire la tua chiave API di OpenAI.",
"to get your OpenAI API key.": "per ottenere la tua chiave API di OpenAI.",
"OpenAI Model": "Modello di OpenAI",
"View API Usage Metrics": "Mostra le metriche di utilizzo delle API",
"Bot": "Bot",
@ -2408,14 +2425,14 @@
"View hidden API keys": "Mostra le chiavi API nascoste",
"Advanced Formatting": "Formattazione avanzata",
"AutoFormat Overrides": "Sovrascrittura AutoFormat",
"Disable description formatting": "Disabilita la formattazione della descrizione",
"Disable personality formatting": "Disabilita la formattazione della personalità",
"Disable scenario formatting": "Disabilita la formattazione dello scenario",
"Disable example chats formatting": "Disabilita la formattazione degli esempi di chat",
"Disable chat start formatting": "Disabilita la formattazione della chat iniziale",
"Disable description formatting": "Disattiva la formattazione della descrizione",
"Disable personality formatting": "Disattiva la formattazione della personalità",
"Disable scenario formatting": "Disattiva la formattazione dello scenario",
"Disable example chats formatting": "Disattiva la formattazione degli esempi di chat",
"Disable chat start formatting": "Disattiva la formattazione della chat iniziale",
"Custom Chat Separator": "Separatore di chat personalizzato",
"Instruct mode": "Modalità istruzione",
"Enabled": "Abilita",
"Enabled": "Attiva",
"Wrap Sequences with Newline": "Ogni sequenza viene rimandata a capo",
"Include Names": "Includi i nomi",
"System Prompt": "Prompt di sistema",
@ -2432,11 +2449,15 @@
"Sentencepiece (LLaMA)": "Sentencepiece (LLaMA)",
"Token Padding": "Token Padding",
"Always add character's name to prompt": "Aggiungi sempre il nome del personaggio al prompt",
"Keep Example Messages in Prompt": "Mantieni i messaggi d'esempio nel Prompt",
"Keep Example Messages in Prompt": "Mantieni i messaggi d'esempio dal prompt",
"Remove Empty New Lines from Output": "Rimuovi le linee di testo vuote dall'output",
"Disabled for all models": "Disabilita per tutti i modelli",
"Pygmalion Formatting": "Formattazione Pygmalion",
"Disabled for all models": "Disattiva per tutti i modelli",
"Automatic (based on model name)": "Automatico (basato sul nome del modello)",
"Enabled for all models": "Abilita per tutti i modelli",
"Enabled for all models": "Attiva per tutti i modelli",
"Multigen": "Multigen",
"First chunk (tokens)": "Primo pacchetto in Token",
"Next chunks (tokens)": "Pacchetto successivo in Token",
"Anchors Order": "Anchors Order",
"Character then Style": "Prima il personaggio, successivamente lo stile",
"Style then Character": "Prima lo stile, successivamente il personaggio",
@ -2452,35 +2473,35 @@
"About soft prompts": "Riguardo i prompt leggeri",
"None": "None",
"User Settings": "Settaggi utente",
"UI Customization": "Personalizzazione dell'interfaccia grafica",
"Avatar Style": "Stile dell'avatar",
"UI Customization": "Personalizzazione UI",
"Avatar Style": "Stile avatar",
"Circle": "Cerchio",
"Rectangle": "Rettangolo",
"Chat Style": "Stile della Chat",
"Default": "Predefinito",
"Bubbles": "Bolle",
"Chat Width (PC)": "Lunghezza della chat (PC)",
"No Blur Effect": "Nessun effetto di sfocatura",
"No Text Shadows": "Nessuna ombreggiatura del testo",
"No Blur Effect": "Nessun effetto sfocatura",
"No Text Shadows": "Nessuna ombreggiatura testo",
"Waifu Mode": "♡ Modalità Waifu ♡",
"Message Timer": "Timer del messaggio",
"Characters Hotswap": "Hotswap dei personaggi",
"Movable UI Panels": "Pannelli dell'interfaccia grafica movibili",
"Message Timer": "Timer messaggio",
"Characters Hotswap": "Hotswap personaggi",
"Movable UI Panels": "Pannelli UI movibili",
"Reset Panels": "Ripristina i pannelli",
"UI Colors": "Colori UI",
"Main Text": "Testo principale",
"Italics Text": "Testo in Italic",
"Quote Text": "Testo citato",
"Shadow Color": "Colore dell'ombreggiatura",
"Shadow Color": "Colore ombreggiatura",
"FastUI BG": "FastUI BG",
"Blur Tint": "Tinta della sfocatura",
"Font Scale": "Grandezza del font",
"Blur Strength": "Intensità della sfocatura",
"Text Shadow Width": "Larghezza dell'ombreggiatura del testo",
"UI Theme Preset": "Tema dell'interfaccia grafica",
"Power User Options": "Opzioni Power User",
"Blur Tint": "Tinta sfocatura",
"Font Scale": "Grandezza font",
"Blur Strength": "Intensità sfocatura",
"Text Shadow Width": "Larghezza ombreggiatura testo",
"UI Theme Preset": "Tema UI",
"Power User Options": "Opzioni utente avanzate",
"Swipes": "Swipes",
"Background Sound Only": "Soltanto il suono di background",
"Background Sound Only": "Soltanto suono di background",
"Auto-load Last Chat": "Carica automaticamente l'ultima chat",
"Auto-save Message Edits": "Salva automaticamente i messaggi editati",
"Auto-fix Markdown": "Correggi automaticamente il testo per la formattazione in Markdown",
@ -2488,13 +2509,13 @@
"Allow {{user}}: in bot messages": "Permetti {{user}} nei messaggi del bot",
"Auto-scroll Chat": "scorrimento automatico della chat",
"Render Formulas": "Renderizza le formule",
"Send on Enter": "Inviare premendo Invio",
"Always disabled": "Sempre disabilitato",
"Send on Enter": "Inoltrare premendo Invio",
"Always disabled": "Sempre disattivato",
"Automatic (desktop)": "Automatico (desktop)",
"Always enabled": "Sempre abilitato",
"Always enabled": "Sempre attivato",
"Name": "Nome",
"Your Avatar": "Il tuo avatar",
"Extensions API:": "Estensioni delle API:",
"Extensions API:": "Estensioni API aggiuntive:",
"SillyTavern-extras": "SillyTavern-extras",
"Auto-connect": "Connessione automatica",
"Active extensions": "Estensione attiva",
@ -2504,8 +2525,8 @@
"Group Controls": "Controlli del gruppo",
"Group reply strategy": "Organizzazione per le risposte del gruppo",
"Natural order": "Ordine naturale",
"List order": "Lista dell'ordine",
"Allow self responses": "Permetti la risposta automatica",
"List order": "Ordine lista",
"Allow self responses": "Permetti risposta automatica",
"Auto Mode": "Modalità automatica",
"Add Members": "Aggiungi membri",
"Current Members": "Membri correnti",
@ -2546,7 +2567,7 @@
"After Char": "Dopo Char",
"Insertion Order": "Ordine di inserimento",
"Tokens:": "Token",
"Disable": "Disabilita",
"Disable": "Disattiva",
"${characterName}": "${nomePersonaggio}",
"CHAR": "CHAR",
"is typing": "sta scrivendo...",
@ -2560,6 +2581,7 @@
"Regenerate": "Rigenera",
"PNG": "PNG",
"JSON": "JSON",
"WEBP": "WEBP",
"presets": "preset",
"Message Sound": "Suono del messaggio",
"Author's Note": "Note d'autore",
@ -2567,21 +2589,21 @@
"Replace empty message": "Sostituisci i messaggi vuoti",
"Send this text instead of nothing when the text box is empty.": "Quando il campo di testo è vuoto, invia invece questo messaggio.",
"NSFW avoidance prompt": "NSFW avoidance prompt",
"Prompt that is used when the NSFW toggle is off": "Prompt utilizzato quando la casella NSFW è disabilitata.",
"Prompt that is used when the NSFW toggle is off": "Prompt utilizzato quando la casella NSFW è disattivata.",
"Advanced prompt bits": "Advanced prompt bits",
"World Info format template": "Formattazione del modello 'Info Mondo'",
"World Info format template": "Formato template 'Info Mondo'",
"Wraps activated World Info entries before inserting into the prompt. Use {0} to mark a place where the content is inserted.": "Seleziona le informazioni del mondo attualmente attive prima di inserirle nel prompt. Usa {0} per segnalare dove vuoi che il contenuto venga inserito all'interno del prompt.",
"Unrestricted maximum value for the context slider": "Valore massimo illimitato per la grandezza del contesto.",
"Chat Completion Source": "Sorgente IA per la Chat",
"Avoid sending sensitive information to the Horde.": "Evita di inviare informazioni sensibili e personali a Horde",
"Review the Privacy statement": "Leggi l'informativa sulla privacy",
"Learn how to contribute your idel GPU cycles to the Horde": "Impara come fare in modo di usare i tuoi cicli GPU in idle per contribuire a Horde",
"Learn how to contribute your idel GPU cycles to the Horde": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
"Trusted workers only": "Utilizza solo utenti di fiducia",
"For privacy reasons, your API key will be hidden after you reload the page.": "Per motivi di sicurezza la tua chiave API verrà oscurata dopo aver ricaricato la pagina.",
"-- Horde models not loaded --": "-- Modelli Horde non caricati --",
"Example: http://127.0.0.1:5000/api ": "Esempio: http://127.0.0.1:5000/api",
"No connection...": "Nessuna connessione",
"Get your NovelAI API Key": "Acquisici la chiave API per NovelAI",
"Get your NovelAI API Key": "Ottieni la chiave API per NovelAI",
"KoboldAI Horde": "KoboldAI Horde",
"Text Gen WebUI (ooba)": "Text Gen WebUI (ooba)",
"NovelAI": "NovelAI",
@ -2595,7 +2617,7 @@
"Presets": "Preset",
"Separator": "Separatore",
"Start Reply With": "Inizia la risposta con",
"Show reply prefix in chat": "Mostra il prefix di risposta nella chat",
"Show reply prefix in chat": "Mostra il prefisso della risposta nella chat",
"Worlds/Lorebooks": "Mondi/Lorebook",
"Active World(s)": "Mondi Attivi",
"Character Lore Insertion Strategy": "Strategia per l'inserimento della lore all'interno del contesto dell'IA",
@ -2619,40 +2641,40 @@
"Order:": "Ordine",
"Probability:": "Probabilità:",
"Delete Entry": "Elimina Voce",
"User Message Blur Tint": "Sfocatura tinta per i messaggi dell'utente",
"AI Message Blur Tint": "Sfocatura tinta per i messaggi dell'IA",
"User Message Blur Tint": "Sfocatura sfondo utente",
"AI Message Blur Tint": "Sfocatura sfondo IA",
"Chat Style:": "Stile Chat",
"Chat Width (PC):": "Larghezza riquadro chat (PC)",
"Chat Timestamps": "Timestamp della chat",
"Message IDs": "ID del Messaggio",
"Prefer Character Card Prompt": "Prompt preferito per la 'Carta Personaggio'",
"Prefer Character Card Jailbreak": "Jailbreak preferito per la 'Carta Personaggio'",
"Prefer Character Card Prompt": "Priorità prompt 'Carta Personaggio'",
"Prefer Character Card Jailbreak": "Priorità jailbreak 'Carta Personaggio'",
"Press Send to continue": "Premi Invio per continuare",
"Log prompts to console": "Registro prompt a console",
"Never resize avatars": "Non ridimensionare mai l'avatar",
"Show avatar filenames": "Mostra il nome del file dell'avatar",
"Import Card Tags": "Importa i tag della carta",
"Confirm message deletion": "Conferma l'eliminazione del messaggio",
"Spoiler Free Mode": "Modalità Spoiler Free",
"Spoiler Free Mode": "Modalità spoiler free",
"Auto-swipe": "Auto-swipe",
"Minimum generated message length": "Lunghezza minima per i messaggi generati",
"Blacklisted words": "Parole nella lista nera",
"Blacklisted word count to swipe": "Numero delle parole nella lista nera",
"Reload Chat": "Ricarica la chat",
"Not Connected": "Non connesso",
"Persona Management": "Gestione della proprio alterego",
"Persona Description": "Descrizione dell'alterego",
"Persona Management": "Gestione del proprio alter ego",
"Persona Description": "Descrizione alter ego",
"Before Character Card": "Prima della 'Carta Personaggio'",
"After Character Card": "Dopo la 'Carta Personaggio'",
"Top of Author's Note": "Inizio delle note d'autore",
"Bottom of Author's Note": "Fine delle note d'autore",
"Top of Author's Note": "All'inizio delle note d'autore",
"Bottom of Author's Note": "Alla fine delle note d'autore",
"How do I use this?": "Cos'è e cosa posso farci?",
"More...": "Mostra di più...",
"Link to World Info": "Collegamento alle 'Info Mondo'",
"Link to World Info": "Collegamento 'Info Mondo'",
"Import Card Lore": "Importa la storia dell carta",
"Scenario Override": "Sovrascrizione dello scenario",
"Scenario Override": "Sovrascrittura dello scenario",
"Rename": "Rinomina",
"Character Description": "Descrizione del personaggio",
"Character Description": "Descrizione personaggio",
"Creator's Notes": "Note del Creatore",
"A-Z": "A-Z",
"Z-A": "Z-A",
@ -2667,13 +2689,13 @@
"Insert {{original}} into either box to include the respective default prompt from system settings.": "Inserisci {{original}} all'intero della casella per includere i rispettivi prompt predefiniti dai settaggi di sistema.",
"Main Prompt": "Prompt Principale",
"Jailbreak": "Jailbreak",
"Creator's Metadata (Not sent with the AI prompt)": "Metadata del creatore (Non viene inviata all'IA)",
"Creator's Metadata (Not sent with the AI prompt)": "Metadata del creatore (Non viene inviato all'IA)",
"Everything here is optional": "Tutto ciò che si trova qui è opzionale",
"Created by": "Creato da",
"Character Version": "Versione del personaggio",
"Tags to Embed": "Tag da incorporare",
"How often the character speaks in group chats!": "La frequenza con la quale il personaggio parla all'interno delle chat di gruppo!",
"Important to set the character's writing style.": "Esso è importante per impostare lo stile di scrittura del personaggio",
"Important to set the character's writing style.": "È importante per impostare lo stile di scrittura del personaggio",
"ATTENTION!": "ATTENZIONE!",
"Samplers Order": "Ordine dei campionatori",
"Samplers will be applied in a top-down order. Use with caution.": "L'ordine dei campioni va dall'alto verso il basso. Usalo con cautela.",
@ -2697,9 +2719,9 @@
"Enter your name": "Inserisci il tuo nome",
"Name this character": "Dai un nome a questo personaggio",
"Search / Create Tags": "Cerca / Crea tag",
"Describe your character's physical and mental traits here.": "Descrivi qui le caratteristiche fisiche e psicologiche del tuo personaggio.",
"Describe your character's physical and mental traits here.": "Descrivi le caratteristiche fisiche e psicologiche del tuo personaggio.",
"This will be the first message from the character that starts every chat.": "Questo sarà il primo messaggio che il personaggio utilizzerà all'inizio di ogni chat.",
"Chat Name (Optional)": "Nome della chat(Opzionale)",
"Chat Name (Optional)": "Nome della chat (opzionale)",
"Filter...": "Filtro...",
"Search...": "Cerca...",
"Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "Ogni elemento racchiuso qui dentro sostituirà il prompt principale predefinito usato da questo personaggio. (v2 spec: system_prompt)",
@ -2709,7 +2731,7 @@
"(Describe the bot, give use tips, or list the chat models it has been tested on. This will be displayed in the character list.)": "(Descrivi il bot, scrivi dei suggerimenti o informa riguardo i modelli IA su cui è stato testato. Questo verrà mostrato nella lista personaggio)",
"(Write a comma-separated list of tags)": "(Scrivi una lista di tag separati dalle virgole)",
"(A brief description of the personality)": "(Scrivi una breve descrizione della sua personalità)",
"(Circumstances and context of the interaction)": "(Scrivi le circostanze e il contesto della scena)",
"(Circumstances and context of the interaction)": "(Scrivi le circostanze e il contesto dello scenario)",
"(Examples of chat dialog. Begin each example with START on a new line.)": "(Esempi di dialogo. Inizia ogni esempio con START quando vai a capo.)",
"Injection text (supports parameters)": "Injection text (supporta i parametri)",
"Injection depth": "Profondità dell'Injection",
@ -2722,14 +2744,14 @@
"Not connected to API!": "Non connesso a nessuna API!",
"AI Response Configuration": "Configurazione della risposta dell'IA",
"AI Configuration panel will stay open": "Se clicchi il lucchetto, il pannello di configurazione dell'IA rimarrà aperto",
"Update current preset": "Aggiorna il preset corrente",
"Update current preset": "Aggiorna preset corrente",
"Create new preset": "Crea un nuovo preset",
"Import preset": "Importa preset",
"Export preset": "Esporta preset",
"Delete the preset": "Cancella il preset",
"Delete the preset": "Cancella preset",
"Inserts jailbreak as a last system message": "Inserisci il Jailbreak come ultimo messaggio del sistema",
"NSFW block goes first in the resulting prompt": "Il blocco al contenuto NSFW spunterà per primo nel prompt corrente",
"Enables OpenAI completion streaming": "Abilita 'streaming completion' per OpenAI",
"Enables OpenAI completion streaming": "Attiva 'streaming completion' per OpenAI",
"Wrap user messages in quotes before sending": "Mette tra il messaggio dell'utente in virgolette prima di inviare il messaggio",
"Restore default prompt": "Ripristina il prompt predefinito",
"New preset": "Nuovo preset",
@ -2765,18 +2787,18 @@
"Change Background Image": "Cambia l'immagine dello sfondo",
"Extensions": "Estensioni",
"Click to set a new User Name": "Clicca qui per impostare un nuovo nome utente",
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "Clicca qui per bloccare l'alterego selezionato alla chat corrente. Clicca di nuovo per rimuovere il blocco.",
"Click to lock your selected persona to the current chat. Click again to remove the lock.": "Clicca qui per bloccare l'alter ego selezionato alla chat corrente. Clicca di nuovo per rimuovere il blocco.",
"Click to set user name for all messages": "Clicca qui per impostare il nome utente per tutti i messaggi",
"Create a dummy persona": "Crea una tuo alterego fittizio",
"Create a dummy persona": "Crea una tuo alter ego fittizio",
"Character Management": "Gestione personaggio",
"Locked = Character Management panel will stay open": "Se clicchi il lucchetto, il pannello della Gestione personaggio rimarrà aperto",
"Locked = Character Management panel will stay open": "Se clicchi il lucchetto, il pannello di gestione del personaggio rimarrà aperto",
"Select/Create Characters": "Seleziona/Crea Personaggi",
"Token counts may be inaccurate and provided just for reference.": "Il conteggio dei Token potrebbe risultare inaccurato, perciò è da utilizzarsi solo come una approssimazione.",
"Click to select a new avatar for this character": "Clicca qui per selezionare un nuovo avatar per questo personaggio",
"Add to Favorites": "Aggiungi ai Favoriti",
"Advanced Definition": "Definizioni Avanzate",
"Add to Favorites": "Aggiungi ai favoriti",
"Advanced Definition": "Definizioni avanzate",
"Character Lore": "Storia del personaggio",
"Export and Download": "Esporta e Scarica",
"Export and Download": "Esporta e scarica",
"Duplicate Character": "Duplica il personaggio",
"Create Character": "Crea un personaggio",
"Delete Character": "Elimina un personaggio",
@ -2820,8 +2842,8 @@
"Move message up": "Muovi il messaggio in alto",
"Move message down": "Muovi il messaggio in basso",
"Enlarge": "Ingrandisci",
"Temporarily disable automatic replies from this character": "Disabilita temporaneamente le risposte in automatico da parte di questo personaggio",
"Enable automatic replies from this character": "Abilita le risposte in automatico da parte di questo personaggio",
"Temporarily disable automatic replies from this character": "Disattiva temporaneamente le risposte in automatico da parte di questo personaggio",
"Enable automatic replies from this character": "Attiva le risposte in automatico da parte di questo personaggio",
"Trigger a message from this character": "Innesca un messaggio di risposta da parte di questo personaggio",
"Move up": "Muovi sopra",
"Move down": "Muovi sotto",
@ -2834,13 +2856,13 @@
"Ask AI to write your message for you": "Chiedi all'IA di scrivere un messaggio al posto tuo",
"Continue the last message": "Continua l'ultimo messaggio in chat",
"Bind user name to that avatar": "Lega il nome utente a questo avatar",
"Select this as default persona for the new chats.": "Seleziona questo alterego come predefinito per tutte le nuove chat",
"Change persona image": "Cambia l'immagine del tuo alterego",
"Delete persona": "Elimina il tuo alterego",
"--- Pick to Edit ---": "--- Scegli per modificare ---",
"Add text here that would make the AI generate things you don't want in your outputs.": "Scrivi qui ciò che non vuoi l'IA generi nel suo output.",
"Select this as default persona for the new chats.": "Seleziona questo alter ego come predefinito per tutte le nuove chat",
"Change persona image": "Cambia l'immagine del tuo alter ego",
"Delete persona": "Elimina il tuo alter ego",
"--- Pick to Edit ---": "--- Seleziona per modificare ---",
"Add text here that would make the AI generate things you don't want in your outputs.": "Scrivi ciò che non vuoi l'IA generi nel suo output.",
"write short replies, write replies using past tense": "Scrivi risposte brevi, scrivi risposte usando il passato",
"Alert if your world info is greater than the allocated budget.": "Questo avvisa nel momento in cui le 'Info Mondo' consumano più di quanto allocato nel budget.",
"Alert if your world info is greater than the allocated budget.": "Ti avvisa nel momento in cui 'Info Mondo' consuma più di quanto allocato nel budget.",
"Clear your cookie": "Cancella i cookie",
"Restore new group chat prompt": "Ripristina il prompt della nuova chat di gruppo",
"Save movingUI changes to a new file": "Salva i cambiamenti apportati alla posizione dei pannelli dell'UI (MovingUI) in un nuovo file",
@ -2851,25 +2873,25 @@
"Prompts": "Prompt",
"Tokens": "Token",
"Reset current character": "Ripristina il personaggio attuale",
"(0 = disabled)": "(0 = disabilitato)",
"1 = disabled": "1 = disabilitato",
"(0 = disabled)": "(0 = disattivato)",
"1 = disabled": "1 = disattivato",
"Activation Regex": "Attivazione Regex",
"Active World(s) for all chats": "Attiva i Mondi per tutte le chat",
"Add character names": "Aggiungi i nomi dei personaggi",
"Add Memo": "Aggiungi note",
"Advanced Character Search": "Ricerca dei personaggi avanzata",
"Advanced Character Search": "Ricerca personaggi avanzata",
"Aggressive": "Aggressivo",
"AI21 Model": "Modello AI21",
"Alert On Overflow": "Avviso in caso di Overflow",
"Allow fallback routes": "Permetti fallback routes",
"Allow fallback routes Description": "Permetti la descrizione di fallback routes",
"Allow fallback routes Description": "Permetti descrizione fallback routes",
"Alt Method": "Metodo Alt",
"Alternate Greetings": "Alterna i saluti",
"Alternate Greetings Hint": "Suggerimenti per i saluti alternati",
"Alternate Greetings Subtitle": "Sottotitoli per i saluti alternati",
"Alternate Greetings Hint": "Premi la croce in alto a destra per generare una nuova casella di testo",
"Alternate Greetings Subtitle": "Qui saranno presenti i saluti alternativi",
"Assistant Prefill": "Assistant Prefill",
"Banned Tokens": "Token banditi",
"Blank": "In bianco",
"Blank": "Nuovo",
"Browser default": "Predefinito del browser",
"Budget Cap": "Limite budget",
"CFG": "CFG",
@ -2887,13 +2909,14 @@
"Example Separator": "Separatore d'esempio",
"Exclude Assistant suffix": "Escludi il suffisso assistente",
"Exclude the assistant suffix from being added to the end of prompt.": "Esclude il suffisso assistente dall'essere aggiunto alla fine del prompt.",
"Force for Groups and Personas": "Forzalo per gruppi e alterego",
"Force for Groups and Personas": "Forzalo per gruppi e alter ego",
"Global Negatives": "Global Negatives",
"In Story String / Chat Completion: After Character Card": "Nella stringa narrativa / Chat Completion: Dopo la 'Carta Personaggio'",
"In Story String / Chat Completion: Before Character Card": "Nella stringa narrativa / Chat Completion: Prima della 'Carta Personaggio",
"Instruct": "Instruct",
"Instruct Mode": "Modalità Instruct",
"Last Sequence": "Ultima sequenza",
"Lazy Chat Loading": "Caricamento svogliato della chat",
"Least tokens": "Token minimi",
"Light": "Leggero",
"Load koboldcpp order": "Ripristina l'ordine di koboldcpp",
@ -2908,7 +2931,7 @@
"Mirostat LR": "Mirostat LR",
"Mirostat Mode": "Mirostat Mode",
"Mirostat Tau": "Mirostat Tau",
"Model Icon": "Icona del modello",
"Model Icon": "Icona modello",
"Most tokens": "Token massimi",
"MovingUI Preset": "Preset MovingUI",
"Negative Prompt": "Prompt negativo",
@ -2936,7 +2959,7 @@
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che una nuova chat sta per iniziare.",
"Set at the beginning of the chat history to indicate that a new group chat is about to start.": "Impostato all'inizio della cronologia chat per indicare che un nuova chat di gruppo sta per iniziare.",
"Show External models (provided by API)": "Mostra modelli esterni (Forniti dall'API)",
"Show Notifications Show notifications on switching personas": "Mostra una notifica quando l'alterego viene cambiato",
"Show Notifications Show notifications on switching personas": "Mostra una notifica quando l'alter ego viene cambiato",
"Show tags in responses": "Mostra i tag nelle risposte",
"Story String": "Stringa narrativa",
"Text Adventure": "Avventura testuale",
@ -2944,23 +2967,101 @@
"Toggle Panels": "Interruttore pannelli",
"Top A Sampling": "Top A Sampling",
"Top K Sampling": "Top K Sampling",
"UI Language": "Linguaggio interfaccia grafica",
"UI Language": "Linguaggio UI",
"Unlocked Context Size": "Sblocca dimensione contesto",
"Usage Stats": "Statistiche di utilizzo",
"Use AI21 Tokenizer": "Utilizza il Tokenizer di AI21",
"Use API key (Only required for Mancer)": "Utilizza la chiave API (Necessario soltanto per Mancer)",
"Use character author's note": "Utilizza le note d'autore del personaggio",
"Use character CFG scales": "Utilizza CFG scales del personaggio",
"Use Proxy password field instead. This input will be ignored.": "Utilizza il campo del password proxy al suo posto. Questo input verrà ignorato.",
"Use Proxy password field instead. This input will be ignored.": "Utilizza il campo della password proxy al suo posto. Questo input verrà ignorato.",
"Use style tags to modify the writing style of the output": "Utilizza lo stile delle tag per modificare lo stile di scrittura in output",
"Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.": "Utilizza il tokenizer appropiato per i modelli giurassici, visto che è più efficente di quello di GPT.",
"Used if CFG Scale is unset globally, per chat or character": "Usato se CFG Scale non è settato globalmente, per le chat o per i personaggi",
"Used if CFG Scale is unset globally, per chat or character": "È utilizzato soltanto se CFG Scale non è settato globalmente, per le chat o per i personaggi",
"Very aggressive": "Esageratamente aggressivo",
"Very light": "Esageratamente leggero",
"Welcome to SillyTavern!": "Benvenuto in SillyTavern!",
"Will be used as a password for the proxy instead of API key.": "Verrà usato come password per il proxy invece che la chiave API.",
"Window AI Model": "Modello Window AI",
"Your Persona": "Il tuo alterego"
"Your Persona": "Il tuo alter ego",
"Start Claude's answer with...": "Inizia la risposta di Claude con...",
"# of messages (0 = disabled)": "'# dei messaggi (0 = disattivato)'",
"Advanced": "Avanzata",
"AI Module": "Modulo IA",
"AI21 API Key": "Chiave API AI21",
"Allow NSFW images from Horde": "Permetti immagini NSFW da Horde",
"Anthropic's developer console": "Console di sviluppo per Anthropic",
"Avoid spending Anlas": "Evita di spendere Anlas",
"Click Authorize below or get the key from": "Clicca Autorizza qui sotto oppure ottieni la chiave da",
"Connect": "Connettiti",
"Context Order": "Ordine del contesto",
"Continue nudge": "Continua nudge (spinta)",
"Convert to Persona": "Converti in alter ego",
"Debug Menu": "Menu Debug",
"Debug Warning": "Avviso Debug",
"Enable simple UI mode": "Avvia la modalità UI semplice",
"Enter": "Invio",
"Example Dialogues": "Dialoghi d'esempio",
"Example: https://neuro.mancer.tech/webui/MODEL/api": "Esempio: https://neuro.mancer.tech/webui/MODEL/api",
"Example: ws://127.0.0.1:5005/api/v1/stream": "Esempio: ws://127.0.0.1:5005/api/v1/stream",
"Execute": "Esegui",
"Get it here:": "Ottienila qui:",
"Get your key from": "Ottieni la tua chiave da",
"Hint": "Suggerimento",
"If you are using:": "Se stai usando:",
"In Story String / Prompt Manager": "Stringa narrativa / Gestione prompt",
"In-Chat Position not affected": "La posizione in-chat non è influenzata",
"Karras (not all samplers supported)": "Karras (Non tutti i sampler sono supportati)",
"Learn how to contribute your idle GPU cycles to the Horde": "Impara come utilizzare i tuoi cicli GPU in idle per contribuire a Horde",
"Models": "Modelli",
"New Chat": "Nuova chat",
"New Example Chat": "Esempio nuova chat",
"New Group Chat": "Nuova chat di gruppo",
"Not connected...": "Non connesso...",
"Not connected...": "Non connesso...",
"Opus tier": "Opus tier",
"Output Sequence": "Sequenza Output",
"Permanent": "Permanente",
"Scale API Key": "Chiave API Scale",
"Send names in the ChatML objects.": "Condividi a ChatML i nomi dei partecipanti.",
"Show impersonated replies in groups": "Mostra risposte impersonate nelle chat di gruppo",
"Show Message Token Count": "Mostra costo in Token per messaggio",
"Show notifications on switching personas": "Mostra notifiche quando l'alter ego cambia",
"Simple": "Semplice",
"Slack and Poe cookies will not work here, do not bother trying.": "I cookie di Slack e Poe non funzioneranno qui, non perdere tempo provandoci.",
"Strip Example Messages from Prompt": "Rimuovi i messaggi d'esempio dal prompt",
"Summary": "Riassunto",
"to use anonymous mode.": "per utilizzare la modalità in anonimo.",
"UI Mode": "Modalità UI",
"Use style tags to modify the writing style of the output.": "Utilizza i tag di stile per modificare la forma di scrittura in uscita.",
"Utility Prompts": "Utility Prompt",
"View my Kudos": "Mostra i miei Kudos",
"View Remaining Credits": "Mostra crediti rimanenti",
"World Info Format Template": "Formato template 'Info Mondo'",
"Wraps activated World Info entries before inserting into the prompt.": "Seleziona le informazioni del mondo attualmente attive prima di inserirle nel prompt.",
"Local server classification": "Classificazione server locale",
"Create Branch": "Crea nuovo ramo",
"removes blur from window backgrounds": "Elimina la sfocatura dagli sfondi delle finestre",
"Allow for Chat Completion APIs": "Permetti per le 'Chat Completion API'",
"at Depth": "a profondità",
"Auto-Continue": "Risposta continua",
"Auto-Expand Message Actions": "Espansione automatica dei messaggi d'azione",
"Automatic (PC)": "Automatico (PC)",
"Character Exclusion": "Estromissione del personaggio",
"Chat Background": "Sfondo chat",
"Custom CSS": "CSS personalizzato",
"Depth:": "Profondità:",
"Disabled": "Disattivato",
"Filter to Character(s)": "Filtra per personaggio",
"Grammar": "Grammatica",
"Miscellaneous": "Varie",
"PaLM API Key": "Chiave API PaLM",
"Relax message trim in Groups": "Troncatura leggera dei messaggi nelle chat di gruppo",
"Target length (tokens)": "Lunghezza target (in token)",
"Theme Toggles": "Interruttore tema",
"Type in the desired custom grammar (GBNF).": "Scrivi la tua grammatica personalizzata (GBNF).",
"UI Background": "Sfondo UI",
"UI Border": "Bordo UI"
},
"nl-nl": {
"clickslidertips": "klikregel tips",
@ -2974,7 +3075,7 @@
"select": "selecteer",
"context size(tokens)": "contextgrootte (in tokens)",
"unlocked": "ontgrendeld",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Selecteer alleen modellen die contextgroottes groter dan 2048 tokens ondersteunen. Ga alleen verder als je weet wat je doet!",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Selecteer alleen modellen die contextgroottes groter dan 4096 tokens ondersteunen. Ga alleen verder als je weet wat je doet!",
"rep.pen": "rep.pen",
"rep.pen range": "rep.pen bereik",
"temperature": "temperatuur",
@ -3024,6 +3125,9 @@
"Streaming": "Streaming",
"Display the response bit by bit as it is generated.": "Toon het antwoord stukje bij beetje terwijl het wordt gegenereerd.",
"When this is off, responses will be displayed all at once when they are complete.": "Wanneer dit is uitgeschakeld, worden antwoorden in één keer weergegeven wanneer ze compleet zijn.",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genereer slechts één regel per verzoek (alleen KoboldAI, genegeerd door KoboldCpp).",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Verbied het End-of-Sequence (EOS) token (met KoboldCpp, en mogelijk ook andere tokens met KoboldAI).",
"Good for story writing, but should not be used for chat and instruct mode.": "Goed voor het schrijven van verhalen, maar mag niet worden gebruikt voor de chat- en instructiemodus.",
"Enhance Definitions": "Verbeter definities",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Gebruik de OAI-kennisbank om definities van publieke figuren en bekende fictieve personages te verbeteren.",
"Wrap in Quotes": "Wikkel in aanhalingstekens",
@ -3511,165 +3615,168 @@
"Select this as default persona for the new chats.": "Selecteer dit als standaard persona voor de nieuwe chats.",
"Change persona image": "persona afbeelding wijzigen",
"Delete persona": "persona verwijderen"
},
},
"es-spa": {
"clickslidertips": "Haz click en el número al lado de la barra \npara seleccionar un número manualmente.",
"kobldpresets": "Configuraciones de KoboldAI",
"guikoboldaisettings": "Configuración actual de la interfaz de KoboldAI",
"novelaipreserts": "Configuraciones de NovelAI",
"default": "Predeterminado",
"openaipresets": "Configuraciones de OpenAI",
"text gen webio(ooba) presets": "Configuraciones de WebUI(ooba)",
"response legth(tokens)": "Largo de la respuesta de la IA (en Tokens)",
"select": "Seleccionar",
"context size(tokens)": "Tamaño del contexto (en Tokens)",
"unlocked": "Desbloqueado",
"only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing": "Solo algunos modelos tienen soporte para tamaños de más de 2048 tokens. Procede solo si sabes lo que estás haciendo.",
"rep.pen": "Rep. Pen.",
"rep.pen range": "Rango de Rep. Pen.",
"temperature": "Temperature",
"Encoder Rep. Pen.": "Encoder Rep. Pen.",
"No Repeat Ngram Size": "No Repeat Ngram Size",
"Min Length": "Largo mínimo",
"OpenAI Reverse Proxy": "Reverse Proxy de OpenAI",
"Alternative server URL (leave empty to use the default value).": "URL del server alternativo (deja vacío para usar el predeterminado)",
"Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Borra tu clave(API) real de OpenAI ANTES de escribir nada en este campo.",
"We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "SillyTaven no puede dar soporte por problemas encontrados durante el uso de un proxy no-oficial de OpenAI",
"Legacy Streaming Processing": "Processo Streaming Legacy",
"Enable this if the streaming doesn't work with your proxy": "Habilita esta opción si el \"streaming\" no está funcionando.",
"Context Size (tokens)": "Tamaño del contexto (en Tokens)",
"Max Response Length (tokens)": "Tamaño máximo (en Tokens)",
"Temperature": "Temperatura",
"Frequency Penalty": "Frequency Penalty",
"Presence Penalty": "Presence Penalty",
"Top-p": "Top-p",
"Display bot response text chunks as they are generated": "Muestra el texto poco a poco al mismo tiempo que es generado.",
"Top A": "Top-a",
"Typical Sampling": "Typical Sampling",
"Tail Free Sampling": "Tail Free Sampling",
"Rep. Pen. Slope": "Rep. Pen. Slope",
"Single-line mode": "Modo \"Solo una línea\"",
"Top K": "Top-k",
"Top P": "Top-p",
"Do Sample": "Do Sample",
"Add BOS Token": "Añadir BOS Token",
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Añade el \"bos_token\" al inicio del prompt. Desabilitar esto puede hacer las respuestas de la IA más creativas",
"Ban EOS Token": "Prohibir EOS Token",
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibe el \"eos_token\". Esto obliga a la IA a no terminar su generación de forma prematura",
"Skip Special Tokens": "Saltarse Tokens Especiales",
"Beam search": "Beam Search",
"Number of Beams": "Number of Beams",
"Length Penalty": "Length Penalty",
"Early Stopping": "Early Stopping",
"Contrastive search": "Contrastive search",
"Penalty Alpha": "Penalty Alpha",
"Seed": "Seed",
"Inserts jailbreak as a last system message.": "Inserta el \"jailbreak\" como el último mensaje del Sistema",
"This tells the AI to ignore its usual content restrictions.": "Esto ayuda a la IA para ignorar sus restricciones de contenido",
"NSFW Encouraged": "Alentar \"NSFW\"",
"Tell the AI that NSFW is allowed.": "Le dice a la IA que el contenido NSFW (+18) está permitido",
"NSFW Prioritized": "Priorizar NSFW",
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El \"prompt NSFW\" va antes para enfatizar su efecto",
"Streaming": "Streaming",
"Display the response bit by bit as it is generated.": "Enseña el texto poco a poco mientras es generado",
"When this is off, responses will be displayed all at once when they are complete.": "Cuando esto está deshabilitado, las respuestas se mostrarán de una vez cuando la generación se haya completado",
"Enhance Definitions": "Definiciones Mejoradas",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa el conocimiento de OpenAI (GPT 3.5, GPT 4, ChatGPT) para mejorar las definiciones de figuras públicas y personajes ficticios",
"Wrap in Quotes": "Envolver En Comillas",
"Wrap entire user message in quotes before sending.": "Envuelve todo el mensaje en comillas antes de enviar",
"Leave off if you use quotes manually for speech.": "Déjalo deshabilitado si usas comillas manualmente para denotar diálogo",
"Main prompt": "Prompt Principal",
"The main prompt used to set the model behavior": "El prompt principal usado para definir el comportamiento de la IA",
"NSFW prompt": "Prompt NSFW",
"Prompt that is used when the NSFW toggle is on": "Prompt que es utilizado cuando \"Alentar NSFW\" está activado",
"Jailbreak prompt": "Jailbreak prompt",
"Prompt that is used when the Jailbreak toggle is on": "Prompt que es utilizado cuando Jailbreak Prompt está activado",
"Impersonation prompt": "Prompt \"Impersonar\"",
"Prompt that is used for Impersonation function": "Prompt que es utilizado para la función \"Impersonar\"",
"Restore default prompt":"Restaurar el prompt por defecto",
"Logit Bias": "Logit Bias",
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o alentar el uso de algunas palabras",
"View / Edit bias preset": "Ver/Editar configuración de \"Logit Bias\"",
"Add bias entry": "Añadir bias",
"Jailbreak activation message": "Mensaje de activación de Jailbrak",
"Message to send when auto-jailbreak is on.": "Mensaje enviado cuando auto-jailbreak está activado",
"Jailbreak confirmation reply": "Mensaje de confirmación de Jailbreak",
"Bot must send this back to confirm jailbreak": "La IA debe enviar un mensaje para confirmar el jailbreak",
"Character Note": "Nota del personaje",
"Influences bot behavior in its responses": "Influencia el comportamiento de la IA y sus respuestas",
"API": "API",
"KoboldAI": "KoboldAI",
"Use Horde": "Usar AI Horde de KoboldAI",
"API url": "URL de la API",
"Register a Horde account for faster queue times": "Regístrate en KoboldAI para conseguir respuestas más rápido",
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir a AI Horde con tu GPU",
"Adjust context size to worker capabilities": "Ajustar tamaño del contexto a las capacidades del trabajador",
"Adjust response length to worker capabilities": "Ajustar tamaño de la respuesta a las capacidades del trabajador",
"API key": "API key",
"Register": "Registrarse",
"For privacy reasons": "Por motivos de privacidad, tu API será ocultada cuando se vuelva a cargar la página",
"Model": "Modelo IA",
"Hold Control / Command key to select multiple models.": "Presiona Ctrl/Command Key para seleccionar multiples modelos",
"Horde models not loaded": "Modelos del Horde no cargados",
"Not connected": "Desconectado",
"Novel API key": "API key de NovelAI",
"Follow": "Sigue",
"these directions": "estas instrucciones",
"to get your NovelAI API key.": "para conseguir tu NovelAI API key",
"Enter it in the box below": "Introduce tu clave API de OpenAI en el siguiente campo",
"Novel AI Model": "Modelo IA de NovelAI",
"No connection": "Desconectado",
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
"Make sure you run it with": "Asegúrate de usar el argumento --api cuando se ejecute",
"Blocking API url": "API URL",
"Streaming API url": "Streaming API URL",
"to get your OpenAI API key.": "para conseguir tu clave API de OpenAI",
"OpenAI Model": "Modelo AI de OpenAI",
"View API Usage Metrics": "Ver métricas de uso de la API",
"Bot": "Bot",
"Auto-connect to Last Server": "Auto-conectarse con el último servidor",
"View hidden API keys": "Ver claves API ocultas",
"Advanced Formatting": "Formateo avanzado",
"AutoFormat Overrides": "Autoformateo de overrides",
"Samplers Order": "Orden de Samplers",
"Samplers will be applied in a top-down order. Use with caution.": "Los Samplers serán aplicados de orden superior a inferior. \nUsa con precaución",
"Load koboldcpp order": "Cargar el orden de koboldcpp",
"Unlocked Context Size": "Desbloquear Tamaño Del Contexto",
"Unrestricted maximum value for the context slider":"Desbloquea el Tamaño máximo del contexto. Solo habilita esto si sabes lo que estás haciendo.",
"Quick Edit": "Editor Rápido de Prompts",
"Main": "Principal",
"Assistant Prefill": "Prefijo del Asistente",
"Start Claude's answer with...": "Inicia la respuesta de Claude con...",
"Utility Prompts": "Indicaciones Útiles",
"World Info Format Template": "Plantilla para formato de World Info",
"NSFW avoidance prompt": "Prompt para evitar NSFW",
"Prompt that is used when the NSFW toggle is O": "Prompt utilizado para evitar NSFW cuando \"Alentar NSFW\" está deshabilitado",
"Wraps activated World Info entries before inserting into the prompt.": "Envuelve las entradas activadas de World Info antes de insertarlas en el prompt.",
"New Chat": "Chat Nuevo",
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Colocado al inicio del historial de chat para indicar que un nuevo chat va a comenzar.",
"New Group Chat": "Nuevo Chat Grupal",
"Set at the beginning of the chat history to indicate that a new group chat is about to start.":"Colocado al inicio del historial de chat para indicarle a la IA que un nuevo Chat Grupal va a comenzar",
"New Example Chat": "Nuevo Ejemplo De Chat",
"Add character names": "Incluír nombre del personaje",
"Send names in the ChatML objects.": "Envía los mensajes al objeto ChatML. Ayuda a la IA a asociar mensajes con nombres en un chat grupal.",
"Proxy Password": "Contraseña del Proxy",
"Will be used as a password for the proxy instead of API key.": "Será utilizado como contraseña del proxy en vez de la clave API.",
"Chat Completion Source": "Fuente de Chat",
"Use Proxy password field instead. This input will be ignored.": "Utiliza el campo de Contraseña del Proxy. Lo que pongas aquí será ignorado.",
"Show External models (provided by API)": "Mostrar modelos externos (Proveídos por la API)",
"Connect": "Conectarse",
"[title]Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica que tu conexión con la API enviando un mensaje corto. ¡Ten en cuenta que se te cobrará por ello!",
"Continue nudge": "Empujuón para continuar",
"Replace empty message": "Reemplazar mensaje vacío",
"Send this text instead of nothing when the text box is empty.": "Envía este mensaje en vez de nada cuando la barra de chat está vacía",
"No connection...": "Sin conexión...",
"Avoid sending sensitive information to the Horde.": "No envíes información personal a Horde.",
"Review the Privacy statement": "Revisa el aviso de privacidad",
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende como contribuír a Horde con tu GPU.",
"Trusted workers only": "Solo trabajadores de confianza",
"API Key": "Clave API",
"Get it here:": "Consíguela aquí:",
"View my Kudos": "Ver mis Kudos",
"Models": "Modelos IA"
"clickslidertips": "Haz click en el número al lado de la barra \npara seleccionar un número manualmente.",
"kobldpresets": "Configuraciones de KoboldAI",
"guikoboldaisettings": "Configuración actual de la interfaz de KoboldAI",
"novelaipreserts": "Configuraciones de NovelAI",
"default": "Predeterminado",
"openaipresets": "Configuraciones de OpenAI",
"text gen webio(ooba) presets": "Configuraciones de WebUI(ooba)",
"response legth(tokens)": "Largo de la respuesta de la IA (en Tokens)",
"select": "Seleccionar",
"context size(tokens)": "Tamaño del contexto (en Tokens)",
"unlocked": "Desbloqueado",
"Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.": "Solo algunos modelos tienen soporte para tamaños de más de 4096 tokens. Procede solo si sabes lo que estás haciendo.",
"rep.pen": "Rep. Pen.",
"rep.pen range": "Rango de Rep. Pen.",
"temperature": "Temperature",
"Encoder Rep. Pen.": "Encoder Rep. Pen.",
"No Repeat Ngram Size": "No Repeat Ngram Size",
"Min Length": "Largo mínimo",
"OpenAI Reverse Proxy": "Reverse Proxy de OpenAI",
"Alternative server URL (leave empty to use the default value).": "URL del server alternativo (deja vacío para usar el predeterminado)",
"Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Borra tu clave(API) real de OpenAI ANTES de escribir nada en este campo.",
"We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "SillyTaven no puede dar soporte por problemas encontrados durante el uso de un proxy no-oficial de OpenAI",
"Legacy Streaming Processing": "Processo Streaming Legacy",
"Enable this if the streaming doesn't work with your proxy": "Habilita esta opción si el \"streaming\" no está funcionando.",
"Context Size (tokens)": "Tamaño del contexto (en Tokens)",
"Max Response Length (tokens)": "Tamaño máximo (en Tokens)",
"Temperature": "Temperatura",
"Frequency Penalty": "Frequency Penalty",
"Presence Penalty": "Presence Penalty",
"Top-p": "Top-p",
"Display bot response text chunks as they are generated": "Muestra el texto poco a poco al mismo tiempo que es generado.",
"Top A": "Top-a",
"Typical Sampling": "Typical Sampling",
"Tail Free Sampling": "Tail Free Sampling",
"Rep. Pen. Slope": "Rep. Pen. Slope",
"Single-line mode": "Modo \"Solo una línea\"",
"Top K": "Top-k",
"Top P": "Top-p",
"Do Sample": "Do Sample",
"Add BOS Token": "Añadir BOS Token",
"Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.": "Añade el \"bos_token\" al inicio del prompt. Desabilitar esto puede hacer las respuestas de la IA más creativas",
"Ban EOS Token": "Prohibir EOS Token",
"Ban the eos_token. This forces the model to never end the generation prematurely": "Prohibe el \"eos_token\". Esto obliga a la IA a no terminar su generación de forma prematura",
"Skip Special Tokens": "Saltarse Tokens Especiales",
"Beam search": "Beam Search",
"Number of Beams": "Number of Beams",
"Length Penalty": "Length Penalty",
"Early Stopping": "Early Stopping",
"Contrastive search": "Contrastive search",
"Penalty Alpha": "Penalty Alpha",
"Seed": "Seed",
"Inserts jailbreak as a last system message.": "Inserta el \"jailbreak\" como el último mensaje del Sistema",
"This tells the AI to ignore its usual content restrictions.": "Esto ayuda a la IA para ignorar sus restricciones de contenido",
"NSFW Encouraged": "Alentar \"NSFW\"",
"Tell the AI that NSFW is allowed.": "Le dice a la IA que el contenido NSFW (+18) está permitido",
"NSFW Prioritized": "Priorizar NSFW",
"NSFW prompt text goes first in the prompt to emphasize its effect.": "El \"prompt NSFW\" va antes para enfatizar su efecto",
"Streaming": "Streaming",
"Display the response bit by bit as it is generated.": "Enseña el texto poco a poco mientras es generado",
"When this is off, responses will be displayed all at once when they are complete.": "Cuando esto está deshabilitado, las respuestas se mostrarán de una vez cuando la generación se haya completado",
"Generate only one line per request (KoboldAI only, ignored by KoboldCpp).": "Genera solo una línea por solicitud (solo KoboldAI, ignorada por KoboldCpp).",
"Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).": "Prohibir el token de fin de secuencia (EOS) (con KoboldCpp, y posiblemente también otros tokens con KoboldAI).",
"Good for story writing, but should not be used for chat and instruct mode.": "Bueno para escribir historias, pero no debe usarse para chatear ni para el modo de instrucción.",
"Enhance Definitions": "Definiciones Mejoradas",
"Use OAI knowledge base to enhance definitions for public figures and known fictional characters": "Usa el conocimiento de OpenAI (GPT 3.5, GPT 4, ChatGPT) para mejorar las definiciones de figuras públicas y personajes ficticios",
"Wrap in Quotes": "Envolver En Comillas",
"Wrap entire user message in quotes before sending.": "Envuelve todo el mensaje en comillas antes de enviar",
"Leave off if you use quotes manually for speech.": "Déjalo deshabilitado si usas comillas manualmente para denotar diálogo",
"Main prompt": "Prompt Principal",
"The main prompt used to set the model behavior": "El prompt principal usado para definir el comportamiento de la IA",
"NSFW prompt": "Prompt NSFW",
"Prompt that is used when the NSFW toggle is on": "Prompt que es utilizado cuando \"Alentar NSFW\" está activado",
"Jailbreak prompt": "Jailbreak prompt",
"Prompt that is used when the Jailbreak toggle is on": "Prompt que es utilizado cuando Jailbreak Prompt está activado",
"Impersonation prompt": "Prompt \"Impersonar\"",
"Prompt that is used for Impersonation function": "Prompt que es utilizado para la función \"Impersonar\"",
"Restore default prompt":"Restaurar el prompt por defecto",
"Logit Bias": "Logit Bias",
"Helps to ban or reenforce the usage of certain words": "Ayuda a prohibir o alentar el uso de algunas palabras",
"View / Edit bias preset": "Ver/Editar configuración de \"Logit Bias\"",
"Add bias entry": "Añadir bias",
"Jailbreak activation message": "Mensaje de activación de Jailbrak",
"Message to send when auto-jailbreak is on.": "Mensaje enviado cuando auto-jailbreak está activado",
"Jailbreak confirmation reply": "Mensaje de confirmación de Jailbreak",
"Bot must send this back to confirm jailbreak": "La IA debe enviar un mensaje para confirmar el jailbreak",
"Character Note": "Nota del personaje",
"Influences bot behavior in its responses": "Influencia el comportamiento de la IA y sus respuestas",
"API": "API",
"KoboldAI": "KoboldAI",
"Use Horde": "Usar AI Horde de KoboldAI",
"API url": "URL de la API",
"Register a Horde account for faster queue times": "Regístrate en KoboldAI para conseguir respuestas más rápido",
"Learn how to contribute your idle GPU cycles to the Hord": "Aprende cómo contribuir a AI Horde con tu GPU",
"Adjust context size to worker capabilities": "Ajustar tamaño del contexto a las capacidades del trabajador",
"Adjust response length to worker capabilities": "Ajustar tamaño de la respuesta a las capacidades del trabajador",
"API key": "API key",
"Register": "Registrarse",
"For privacy reasons": "Por motivos de privacidad, tu API será ocultada cuando se vuelva a cargar la página",
"Model": "Modelo IA",
"Hold Control / Command key to select multiple models.": "Presiona Ctrl/Command Key para seleccionar multiples modelos",
"Horde models not loaded": "Modelos del Horde no cargados",
"Not connected": "Desconectado",
"Novel API key": "API key de NovelAI",
"Follow": "Sigue",
"these directions": "estas instrucciones",
"to get your NovelAI API key.": "para conseguir tu NovelAI API key",
"Enter it in the box below": "Introduce tu clave API de OpenAI en el siguiente campo",
"Novel AI Model": "Modelo IA de NovelAI",
"No connection": "Desconectado",
"oobabooga/text-generation-webui": "oobabooga/text-generation-webui",
"Make sure you run it with": "Asegúrate de usar el argumento --api cuando se ejecute",
"Blocking API url": "API URL",
"Streaming API url": "Streaming API URL",
"to get your OpenAI API key.": "para conseguir tu clave API de OpenAI",
"OpenAI Model": "Modelo AI de OpenAI",
"View API Usage Metrics": "Ver métricas de uso de la API",
"Bot": "Bot",
"Auto-connect to Last Server": "Auto-conectarse con el último servidor",
"View hidden API keys": "Ver claves API ocultas",
"Advanced Formatting": "Formateo avanzado",
"AutoFormat Overrides": "Autoformateo de overrides",
"Samplers Order": "Orden de Samplers",
"Samplers will be applied in a top-down order. Use with caution.": "Los Samplers serán aplicados de orden superior a inferior. \nUsa con precaución",
"Load koboldcpp order": "Cargar el orden de koboldcpp",
"Unlocked Context Size": "Desbloquear Tamaño Del Contexto",
"Unrestricted maximum value for the context slider":"Desbloquea el Tamaño máximo del contexto. Solo habilita esto si sabes lo que estás haciendo.",
"Quick Edit": "Editor Rápido de Prompts",
"Main": "Principal",
"Assistant Prefill": "Prefijo del Asistente",
"Start Claude's answer with...": "Inicia la respuesta de Claude con...",
"Utility Prompts": "Indicaciones Útiles",
"World Info Format Template": "Plantilla para formato de World Info",
"NSFW avoidance prompt": "Prompt para evitar NSFW",
"Prompt that is used when the NSFW toggle is O": "Prompt utilizado para evitar NSFW cuando \"Alentar NSFW\" está deshabilitado",
"Wraps activated World Info entries before inserting into the prompt.": "Envuelve las entradas activadas de World Info antes de insertarlas en el prompt.",
"New Chat": "Chat Nuevo",
"Set at the beginning of the chat history to indicate that a new chat is about to start.": "Colocado al inicio del historial de chat para indicar que un nuevo chat va a comenzar.",
"New Group Chat": "Nuevo Chat Grupal",
"Set at the beginning of the chat history to indicate that a new group chat is about to start.":"Colocado al inicio del historial de chat para indicarle a la IA que un nuevo Chat Grupal va a comenzar",
"New Example Chat": "Nuevo Ejemplo De Chat",
"Add character names": "Incluír nombre del personaje",
"Send names in the ChatML objects.": "Envía los mensajes al objeto ChatML. Ayuda a la IA a asociar mensajes con nombres en un chat grupal.",
"Proxy Password": "Contraseña del Proxy",
"Will be used as a password for the proxy instead of API key.": "Será utilizado como contraseña del proxy en vez de la clave API.",
"Chat Completion Source": "Fuente de Chat",
"Use Proxy password field instead. This input will be ignored.": "Utiliza el campo de Contraseña del Proxy. Lo que pongas aquí será ignorado.",
"Show External models (provided by API)": "Mostrar modelos externos (Proveídos por la API)",
"Connect": "Conectarse",
"[title]Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "Verifica que tu conexión con la API enviando un mensaje corto. ¡Ten en cuenta que se te cobrará por ello!",
"Continue nudge": "Empujuón para continuar",
"Replace empty message": "Reemplazar mensaje vacío",
"Send this text instead of nothing when the text box is empty.": "Envía este mensaje en vez de nada cuando la barra de chat está vacía",
"No connection...": "Sin conexión...",
"Avoid sending sensitive information to the Horde.": "No envíes información personal a Horde.",
"Review the Privacy statement": "Revisa el aviso de privacidad",
"Learn how to contribute your idle GPU cycles to the Horde": "Aprende como contribuír a Horde con tu GPU.",
"Trusted workers only": "Solo trabajadores de confianza",
"API Key": "Clave API",
"Get it here:": "Consíguela aquí:",
"View my Kudos": "Ver mis Kudos",
"Models": "Modelos IA"
}
}

67
public/img/palm.svg Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Standard_product_icon__x28_1:1_x29_"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="192px" height="192px" viewBox="0 0 192 192" enable-background="new 0 0 192 192" xml:space="preserve">
<symbol id="material_x5F_product_x5F_standard_x5F_icon_x5F_keylines_00000077318920148093339210000006245950728745084294_" viewBox="-96 -96 192 192">
<g opacity="0.4">
<defs>
<path id="SVGID_1_" opacity="0.4" d="M-96,96V-96H96V96H-96z"/>
</defs>
<clipPath id="SVGID_00000071517564283228984050000017848131202901217410_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)">
<g>
<path d="M95.75,95.75v-191.5h-191.5v191.5H95.75 M96,96H-96V-96H96V96L96,96z"/>
</g>
<circle fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" cx="0" cy="0" r="64"/>
</g>
<circle clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" cx="0" cy="0" r="88"/>
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
M64,76H-64c-6.6,0-12-5.4-12-12V-64c0-6.6,5.4-12,12-12H64c6.6,0,12,5.4,12,12V64C76,70.6,70.6,76,64,76z"/>
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
M52,88H-52c-6.6,0-12-5.4-12-12V-76c0-6.6,5.4-12,12-12H52c6.6,0,12,5.4,12,12V76C64,82.6,58.6,88,52,88z"/>
<path clip-path="url(#SVGID_00000071517564283228984050000017848131202901217410_)" fill="none" stroke="#000000" stroke-width="0.25" stroke-miterlimit="10" d="
M76,64H-76c-6.6,0-12-5.4-12-12V-52c0-6.6,5.4-12,12-12H76c6.6,0,12,5.4,12,12V52C88,58.6,82.6,64,76,64z"/>
</g>
</symbol>
<rect id="bounding_box_1_" display="none" fill="none" width="192" height="192"/>
<g id="art_layer">
<g>
<path d="M96,181.92L96,181.92c6.63,0,12-5.37,12-12v-104H84v104C84,176.55,89.37,181.92,96,181.92z"/>
<g>
<path d="M143.81,103.87C130.87,90.94,111.54,88.32,96,96l51.37,51.37c2.12,2.12,5.77,1.28,6.67-1.57
C158.56,131.49,155.15,115.22,143.81,103.87z"/>
</g>
<g>
<path d="M48.19,103.87C61.13,90.94,80.46,88.32,96,96l-51.37,51.37c-2.12,2.12-5.77,1.28-6.67-1.57
C33.44,131.49,36.85,115.22,48.19,103.87z"/>
</g>
<g>
<path d="M140,64c-20.44,0-37.79,13.4-44,32h81.24c3.33,0,5.55-3.52,4.04-6.49C173.56,74.36,157.98,64,140,64z"/>
</g>
<g>
<path d="M104.49,42.26C90.03,56.72,87.24,78.45,96,96l57.45-57.45c2.36-2.36,1.44-6.42-1.73-7.45
C135.54,25.85,117.2,29.55,104.49,42.26z"/>
</g>
<g>
<path d="M87.51,42.26C101.97,56.72,104.76,78.45,96,96L38.55,38.55c-2.36-2.36-1.44-6.42,1.73-7.45
C56.46,25.85,74.8,29.55,87.51,42.26z"/>
</g>
<g>
<g>
<path d="M52,64c20.44,0,37.79,13.4,44,32H14.76c-3.33,0-5.55-3.52-4.04-6.49C18.44,74.36,34.02,64,52,64z"/>
</g>
</g>
</g>
</g>
<g id="keylines" display="none">
<use xlink:href="#material_x5F_product_x5F_standard_x5F_icon_x5F_keylines_00000077318920148093339210000006245950728745084294_" width="192" height="192" id="material_x5F_product_x5F_standard_x5F_icon_x5F_keylines" x="-96" y="-96" transform="matrix(1 0 0 -1 96 96)" display="inline" overflow="visible"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -127,7 +127,6 @@
<span class="note-link-span">?</span>
</a>
</h3>
<div class="preset_buttons">
<select id="settings_perset" data-preset-manager-for="kobold">
<option value="gui" data-i18n="guikoboldaisettings">GUI KoboldAI Settings</option>
@ -250,8 +249,8 @@
<span data-i18n="unlocked">Unlocked</span>
</label>
<div id="max_context_unlocked_warning" class="toggle-description justifyLeft widthUnset">
<span data-i18n="only select modls support context sizes greater than 2048 tokens. proceed only is you know you're doing">
Only select models support context sizes greater than 2048 tokens.
<span data-i18n="Only select models support context sizes greater than 4096 tokens. Increase only if you know what you're doing.">
Only select models support context sizes greater than 4096 tokens.
Increase only if you know what you're doing.
</span>
</div>
@ -308,7 +307,7 @@
</div>
</div>
</div>
<div data-newbie-hidden class="range-block">
<div class="range-block">
<div class="range-block-title" data-i18n="rep.pen range">
Repetition Penalty Range
</div>
@ -323,6 +322,21 @@
</div>
</div>
</div>
<div data-newbie-hidden class="range-block">
<div class="range-block-title" data-i18n="Rep. Pen. Slope">
Repetition Penalty Slope
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="rep_pen_slope" name="volume" min="0" max="10" step="0.1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="rep_pen_slope" id="rep_pen_slope_counter">
select
</div>
</div>
</div>
</div>
</div>
<div id="range_block_novel">
<div class="range-block">
@ -518,7 +532,7 @@
</div>
<div data-newbie-hidden class="range-block">
<div class="range-block-title" data-i18n="Encoder Rep. Pen.">
Encoder Rep. Pen.
Encoder Repetition Penalty
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
@ -617,7 +631,7 @@
complete.</span>
</div>
</div>
<div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale">
<div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,palm">
<div class="range-block-title" data-i18n="Temperature">
Temperature
</div>
@ -677,7 +691,7 @@
</div>
</div>
</div>
<div data-newbie-hidden class="range-block" data-source="claude,openrouter,ai21">
<div data-newbie-hidden class="range-block" data-source="claude,openrouter,ai21,palm">
<div class="range-block-title" data-i18n="Top K">
Top K
</div>
@ -692,7 +706,7 @@
</div>
</div>
</div>
<div data-newbie-hidden class="range-block" data-source="openai,claude,openrouter,ai21,scale">
<div data-newbie-hidden class="range-block" data-source="openai,claude,openrouter,ai21,scale,palm">
<div class="range-block-title" data-i18n="Top-p">
Top P
</div>
@ -985,26 +999,16 @@
</div>
</div>
</div>
<div class="range-block">
<div class="range-block-title" data-i18n="Rep. Pen. Slope">
Rep. Pen. Slope
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="rep_pen_slope" name="volume" min="0" max="10" step="0.1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="rep_pen_slope" id="rep_pen_slope_counter">
select
</div>
</div>
</div>
</div>
<div class="range-block">
<label class="checkbox_label" for="single_line">
<input id="single_line" type="checkbox" /><span data-i18n="Single-line mode">
Single-line mode</span>
</label>
<div class="toggle-description justifyLeft">
<span data-i18n="Generate only one line per request (KoboldAI only, ignored by KoboldCpp).">
Generate only one line per request (KoboldAI only, ignored by KoboldCpp).
</span>
</div>
</div>
<div class="range-block">
<label class="checkbox_label" for="use_default_badwordsids">
@ -1013,6 +1017,13 @@
Ban EOS Token
</span>
</label>
<div class="toggle-description justifyLeft">
<span data-i18n="Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).">
Ban the End-of-Sequence (EOS) token (with KoboldCpp, and possibly also other tokens with KoboldAI).</span><br>
<span data-i18n="Good for story writing, but should not be used for chat and instruct mode.">
Good for story writing, but should not be used for chat and instruct mode.
</span>
</div>
</div>
<hr>
<h4 data-i18n="Mirostat">Mirostat</h4>
@ -1020,6 +1031,10 @@
<div class="range-block-title" data-i18n="Mirostat Mode">
Mirostat Mode
</div>
<div class="toggle-description width100p" data-i18n="Mirostat Mode">
A value of 0 disables Mirostat entirely.
<br>1 is for Mirostat 1.0, and 2 is for Mirostat 2.0
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="mirostat_mode_kobold" name="volume" min="0" max="2" step="1" />
@ -1035,6 +1050,9 @@
<div class="range-block-title" data-i18n="Mirostat Tau">
Mirostat Tau
</div>
<div class="toggle-description width100p" data-i18n="Mirostat Tau">
Controls variability of Mirostat outputs
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="mirostat_tau_kobold" name="volume" min="0" max="20" step="0.01" />
@ -1050,6 +1068,9 @@
<div class="range-block-title" data-i18n="Mirostat Eta">
Mirostat Eta
</div>
<div class="toggle-description width100p" data-i18n="Mirostat Eta">
Controls learning rate of Mirostat
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="mirostat_eta_kobold" name="volume" min="0" max="1" step="0.01" />
@ -1138,10 +1159,10 @@
<span data-i18n="Banned Tokens">Banned Tokens</span>
</div>
<div class="toggle-description justifyLeft" data-i18n="Sequences you don't want to appear in the output. One per line.">
Sequences you don't want to appear in the output. One per line.
Sequences you don't want to appear in the output. One per line. Text or [token ids].
</div>
<div class="wide100p">
<textarea id="nai_banned_tokens" class="text_pole textarea_compact" name="nai_banned_tokens" rows="2" placeholder=""></textarea>
<textarea id="nai_banned_tokens" class="text_pole textarea_compact" name="nai_banned_tokens" rows="3" placeholder="Example:&#10;some text&#10;[42, 69, 1337]"></textarea>
</div>
</div>
<div class="range-block">
@ -1483,6 +1504,26 @@
</label>
</div>
<hr>
<div class="range-block">
<h4 class="range-block-title justifyLeft">
<span data-i18n="Banned Tokens">Banned Tokens</span>
<span data-i18n="LLaMA models">(LLaMA models)</span>
</h4>
<div class="toggle-description justifyLeft" data-i18n="Sequences you don't want to appear in the output. One per line.">
Sequences you don't want to appear in the output. One per line. Text or [token ids].
</div>
<div class="wide100p">
<textarea id="banned_tokens_textgenerationwebui" class="text_pole textarea_compact" name="banned_tokens_textgenerationwebui" rows="3" placeholder="Example:&#10;some text&#10;[42, 69, 1337]"></textarea>
</div>
<small>
<i class="fa-solid fa-lightbulb"></i>
&nbsp;
<span data-i18n="Most tokens have a leading space.">
Most tokens have a leading space.
</span>
</small>
</div>
<hr>
<div class="range-block">
<h4 class="range-block-title justifyLeft" data-i18n="CFG Scale">
CFG Scale
@ -1503,12 +1544,12 @@
<span data-i18n="Negative Prompt">Negative Prompt</span>
</div>
<div class="wide100p">
<textarea id="negative_prompt_textgenerationwebui" class="text_pole textarea_compact" name="negative_prompt" rows="2" data-i18n="[placeholder]Add text here that would make the AI generate things you don't want in your outputs." placeholder="Add text here that would make the AI generate things you don't want in your outputs."></textarea>
<textarea id="negative_prompt_textgenerationwebui" class="text_pole textarea_compact" name="negative_prompt" rows="3" data-i18n="[placeholder]Add text here that would make the AI generate things you don't want in your outputs." placeholder="Add text here that would make the AI generate things you don't want in your outputs."></textarea>
</div>
<small data-i18n="Used if CFG Scale is unset globally, per chat or character">
Used if CFG Scale is unset globally, per chat or character
</small>
</div>
<small class="margin-bot-10px" data-i18n="Used if CFG Scale is unset globally, per chat or character">
Used if CFG Scale is unset globally, per chat or character
</small>
<hr>
<h4><span data-i18n="Beam search">Beam search</span></h4>
<div class="range-block">
@ -1612,6 +1653,18 @@
</div>
</div>
<hr>
<div id="grammar_block_ooba">
<h4 data-i18n="Grammar">Grammar</h4>
<div class="range-block">
<textarea id="grammar_string_textgenerationwebui" rows="2" class="text_pole textarea_compact monospace"></textarea>
<div class="toggle-description justifyLeft">
<span data-i18n="Type in the desired custom grammar (GBNF).">
Type in the desired custom grammar (<a href="https://github.com/ggerganov/llama.cpp/blob/master/grammars/README.md" target="_blank">GBNF</a>).
</span>
</div>
</div>
</div>
<hr>
<div class="range-block">
<div class="range-block-title" data-i18n="Seed">
Seed
@ -1710,7 +1763,7 @@
<option value="koboldhorde"><span data-i18n="KoboldAI Horde">KoboldAI Horde</span></option>
<option value="textgenerationwebui"><span data-i18n="Text Gen WebUI (ooba/Mancer)">Text Gen WebUI (ooba/Mancer)</span></option>
<option value="novel"><span data-i18n="NovelAI">NovelAI</span></option>
<option value="openai"><span data-i18n="Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale, AI21)">Chat Completion (OpenAI, Claude, Window, OpenRouter, Scale, AI21)</span></option>
<option value="openai"><span data-i18n="Chat Completion (OpenAI, Claude, Window/OpenRouter, Scale, AI21)">Chat Completion (OpenAI, Claude, Window, OpenRouter, Scale, AI21, PaLM)</span></option>
</select>
</div>
<div id="kobold_horde" style="position: relative;"> <!-- shows the kobold settings -->
@ -1833,60 +1886,80 @@
</div>
<div id="textgenerationwebui_api" style="display: none;position: relative;">
<form action="javascript:void(null);" method="post" enctype="multipart/form-data">
<span data-i18n="If you are using:"> If you are using:</span>
<div class="flex-container indent20p">
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
oobabooga/text-generation-webui
</a>
<span data-i18n="Make sure you run it with">
Make sure you run it with <tt>--api</tt> flag
</span>
</div>
<div class="flex-container indent20p">
<a href="https://mancer.tech/" target="_blank">
Mancer AI
</a>
<label class="checkbox_label" for="use-mancer-api-checkbox">
<span data-i18n="Use API key (Only required for Mancer)">
Click this box (and add your API key!):
</span>
<input id="use-mancer-api-checkbox" type="checkbox" />
</label>
</div>
<div>
<div id="mancer_api_subpanel" class="flex-container flexFlowColumn" style="display:none;">
<h4 data-i18n="Mancer API key">Mancer API key</h4>
<div class="flex-container">
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
</div>
</div>
<div data-for="api_key_mancer" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
For privacy reasons, your API key will be hidden after you reload the page.
</div>
<div class="flex1">
<h4>Mancer Model</h4>
<select id="mancer_model"></select>
<h4 data-i18n="Mancer API url">Mancer API URL</h4>
<small data-i18n="Example: https://neuro.mancer.tech/webui/MODEL/api">Example: https://neuro.mancer.tech/webui/MODEL/api</small>
<input id="mancer_api_url_text" name="mancer_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div>
</div>
<div id="tgwebui_api_subpanel" class="flex-container flexFlowColumn">
<div class="flex1">
<h4 data-i18n="Blocking API url">Blocking API URL</h4>
<small data-i18n="Example: http://127.0.0.1:5000/api ">Example: http://127.0.0.1:5000/api </small>
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_blocking">
</div>
<div class="flex1">
<h4 data-i18n="Streaming API url">Streaming API URL</h4>
<small data-i18n="Example: ws://127.0.0.1:5005/api/v1/stream">Example: ws://127.0.0.1:5005/api/v1/stream </small>
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_streaming">
</div>
</div>
<div id="api_button_textgenerationwebui" class="menu_button" type="submit" data-i18n="Connect" data-server-connect="ooba_blocking,ooba_streaming">Connect</div>
<div id="api_loading_textgenerationwebui" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
<h4>API Type</h4>
<select id="textgen_type">
<option value="ooba">Default (oobabooga)</option>
<option value="mancer">Mancer</option>
<option value="aphrodite">Aphrodite</option>
</select>
</div>
<div data-tg-type="mancer" class="flex-container flexFlowColumn">
<div class="flex-container flexFlowColumn">
<a href="https://mancer.tech/" target="_blank">
Mancer AI
</a>
</div>
<h4 data-i18n="Mancer API key">Mancer API key</h4>
<div class="flex-container">
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
</div>
</div>
<div data-for="api_key_mancer" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
For privacy reasons, your API key will be hidden after you reload the page.
</div>
<div class="flex1">
<h4>Mancer Model</h4>
<select id="mancer_model"></select>
<h4 data-i18n="Mancer API url">Mancer API URL</h4>
<small data-i18n="Example: https://neuro.mancer.tech/webui/MODEL/api">Example: https://neuro.mancer.tech/webui/MODEL/api</small>
<input id="mancer_api_url_text" name="mancer_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div>
</div>
<div data-tg-type="ooba" class="flex-container flexFlowColumn">
<div class="flex-container flexFlowColumn">
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
oobabooga/text-generation-webui
</a>
<span data-i18n="Make sure you run it with">
Make sure you run it with <tt>--api</tt> flag
</span>
</div>
<div class="flex1">
<h4 data-i18n="Blocking API url">Blocking API URL</h4>
<small data-i18n="Example: http://127.0.0.1:5000/api ">Example: http://127.0.0.1:5000/api </small>
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_blocking">
</div>
<div class="flex1">
<h4 data-i18n="Streaming API url">Streaming API URL</h4>
<small data-i18n="Example: ws://127.0.0.1:5005/api/v1/stream">Example: ws://127.0.0.1:5005/api/v1/stream </small>
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_streaming">
</div>
</div>
<div data-tg-type="aphrodite">
<div class="flex-container flexFlowColumn">
<a href="https://github.com/PygmalionAI/aphrodite-engine" target="_blank">
PygmalionAI/aphrodite-engine
</a>
</div>
<h4 data-i18n="Aphrodite API key">Aphrodite API key</h4>
<div class="flex-container">
<input id="api_key_aphrodite" name="api_key_aphrodite" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_aphrodite">
</div>
</div>
<div data-for="api_key_aphrodite" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
For privacy reasons, your API key will be hidden after you reload the page.
</div>
<div class="flex1">
<h4 data-i18n="API url">API URL</h4>
<small data-i18n="Example: http://127.0.0.1:5000/api ">Example: http://127.0.0.1:5000/api </small>
<input id="aphrodite_api_url_text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="aphrodite">
</div>
</div>
<div id="api_button_textgenerationwebui" class="menu_button" type="submit" data-i18n="Connect" data-server-connect="ooba_blocking,ooba_streaming,aphrodite">Connect</div>
<div id="api_loading_textgenerationwebui" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
</form>
<div class="online_status4">
<div class="online_status_indicator4"></div>
@ -1904,6 +1977,7 @@
<option value="claude">Claude</option>
<option value="scale">Scale</option>
<option value="ai21">AI21</option>
<option value="palm">Google PaLM 2</option>
</select>
<form id="openai_form" data-source="openai" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<h4><span data-i18n="OpenAI API key">OpenAI API key</span></h4>
@ -1955,7 +2029,7 @@
<option value="gpt-4-0613">gpt-4-0613</option>
<option value="gpt-4-0314">gpt-4-0314</option>
<option value="gpt-4-32k">gpt-4-32k</option>
<option value="gpt-4-32k-0301">gpt-4-32k-0301</option>
<option value="gpt-4-32k-0314">gpt-4-32k-0314</option>
<option value="gpt-4-32k-0613">gpt-4-32k-0613</option>
</optgroup>
<optgroup label="Other">
@ -2124,6 +2198,19 @@
</div>
</form>
<form id="palm_form" data-source="palm" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<h4 data-i18n="PaLM API Key">PaLM API Key</h4>
<div class="flex-container">
<input id="api_key_palm" name="api_key_palm" class="text_pole flex1" maxlength="500" value="" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_palm"></div>
</div>
<div data-for="api_key_palm" class="neutral_warning">
For privacy reasons, your API key will be hidden after you reload the page.
</div>
<!-- Its only purpose is to trigger max context size check -->
<select id="model_palm_select" class="displayNone"></select>
</form>
<div class="flex-container flex">
<div id="api_button_openai" class="menu_button menu_button_icon" type="submit" data-i18n="Connect">Connect</div>
<div data-source="openrouter" id="openrouter_authorize" class="menu_button menu_button_icon" title="Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai" data-i18n="[title]Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai">Authorize</div>
@ -2577,7 +2664,7 @@
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range paddingLeftRight5">
<input type="range" id="world_info_depth" name="volume" min="0" max="10" step="1">
<input type="range" id="world_info_depth" name="volume" min="0" max="100" step="1">
</div>
<div class="range-block-counter margin0">
<div contenteditable="true" data-for="world_info_depth" id="world_info_depth_counter">
@ -2624,41 +2711,43 @@
</div>
</div>
<div data-newbie-hidden class="alignitemsflexstart flex1 range-block flex-container flexFlowColumn">
<label title="Entries can activate other entries by mentioning their keywords" data-i18n="[title]Entries can activate other entries by mentioning their keywords" class="checkbox_label">
<div id="worldInfoScanningCheckboxes" data-newbie-hidden class="alignitemsflexstart flex1 flex-container flexFlowColumn">
<label title="Entries can activate other entries by mentioning their keywords" data-i18n="[title]Entries can activate other entries by mentioning their keywords" class="checkbox_label flex1">
<input id="world_info_recursive" type="checkbox" />
<small data-i18n="Recursive Scan">
<small data-i18n="Recursive Scan" class="whitespacenowrap flex1">
Recursive Scan
</small>
</label>
<label title="Lookup for the entry keys in the context will respect the case" data-i18n="[title]Lookup for the entry keys in the context will respect the case" class="checkbox_label">
<label title="Lookup for the entry keys in the context will respect the case" data-i18n="[title]Lookup for the entry keys in the context will respect the case" class="checkbox_label flex1">
<input id="world_info_case_sensitive" type="checkbox" />
<small data-i18n="Case Sensitive">
<small data-i18n="Case Sensitive" class="whitespacenowrap flex1">
Case-sensitive
</small>
</label>
<label title="If the entry key consists of only one word, it would not be matched as part of other words" data-i18n="[title]If the entry key consists of only one word, it would not be matched as part of other words" class="checkbox_label">
<label title="If the entry key consists of only one word, it would not be matched as part of other words" data-i18n="[title]If the entry key consists of only one word, it would not be matched as part of other words" class="checkbox_label flex1">
<input id="world_info_match_whole_words" type="checkbox" />
<small data-i18n="Match whole words">
<small data-i18n="Match whole words" class="whitespacenowrap flex1">
Match whole words
</small>
</label>
<label title="Alert if your world info is greater than the allocated budget." data-i18n="[title]Alert if your world info is greater than the allocated budget." class="checkbox_label">
<label title="Alert if your world info is greater than the allocated budget." data-i18n="[title]Alert if your world info is greater than the allocated budget." class="checkbox_label flex1">
<input id="world_info_overflow_alert" type="checkbox" />
<small data-i18n="Alert On Overflow">
<small data-i18n="Alert On Overflow" class="whitespacenowrap flex1">
Alert On Overflow
</small>
</label>
<div id="WIInputWidthReference" style="display:none; height:1px;">10000</div>
</div>
</div>
<div id="world_popup">
<hr>
<div class="flex-container alignitemscenter">
<div class="flex-container alignitemscenter gap3px">
<input type="file" id="world_import_file" accept=".json,.lorebook,.png" name="avatar" hidden>
<div id="world_create_button" class="menu_button menu_button_icon">
<i class="fa-solid fa-globe"></i>
<span data-i18n="Create">Create</span>
<span data-i18n="New">New</span>
</div>
<small data-i18n="or">or</small>
<select id="world_editor_select" class="margin0">
@ -2668,10 +2757,27 @@
<div id="OpenAllWIEntries" class="menu_button fa-solid fa-expand" title="Open all Entries" data-i18n="[title]Open all Entries"></div>
<div id="CloseAllWIEntries" class="menu_button fa-solid fa-compress" title="Close all Entries" data-i18n="[title]Close all Entries"></div>
<div id="world_popup_new" class="menu_button fa-solid fa-plus" title="New Entry" data-i18n="[title]New Entry"></div>
<div id="world_backfill_memos" class="menu_button fa-solid fa-notes-medical" title="Fill empty Memo/Titles with Keywords" data-i18n="[title]Fill empty Memo/Titles with Keywords"></div>
<div id="world_import_button" class="menu_button fa-solid fa-file-import" title="Import World Info" data-i18n="[title]Import World Info"></div>
<div id="world_popup_export" class="menu_button fa-solid fa-file-export" title="Export World Info" data-i18n="[title]Export World Info"></div>
<div id="world_popup_delete" class="menu_button fa-solid fa-trash-can redWarningBG" title="Delete World Info" data-i18n="[title]Delete World Info"></div>
<input type="search" class="text_pole textarea_compact" data-i18n="[placeholder]Search..." id="world_info_search" placeholder="Search...">
<select id="world_info_sort_order" class="margin0">
<option data-rule="priority" value="0">Priority</option>
<option data-order="asc" data-field="comment" value="1">Title A-Z</option>
<option data-order="desc" data-field="comment" value="2">Title Z-A</option>
<option data-order="asc" data-field="content" data-rule="length" value="3">Tokens ↗</option>
<option data-order="desc" data-field="content" data-rule="length" value="4">Tokens ↘</option>
<option data-order="asc" data-field="depth" value="5">Depth ↗</option>
<option data-order="desc" data-field="depth" value="6">Depth ↘</option>
<option data-order="asc" data-field="order" value="7">Order ↗</option>
<option data-order="desc" data-field="order" value="8">Order ↘</option>
<option data-order="asc" data-field="uid" value="9">UID ↗</option>
<option data-order="desc" data-field="uid" value="10">UID ↘</option>
<option data-order="asc" data-field="probability" value="11">Trigger% ↗</option>
<option data-order="desc" data-field="probability" value="12">Trigger% ↘</option>
</select>
<div id="world_refresh" class="menu_button fa-solid fa-arrows-rotate" title="Refresh" data-i18n="[title]Refresh"></div>
<div id="world_info_pagination"></div>
</div>
@ -2807,7 +2913,7 @@
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="font_scale" name="font_scale" min="0.8" max="1.2" step="0.02">
<input type="range" id="font_scale" name="font_scale" min="0.8" max="1.2" step="0.01">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="font_scale" id="font_scale_counter">
@ -2964,7 +3070,7 @@
</label>
<label data-newbie-hidden for="prefer_character_jailbreak" title="If checked and the character card contains a jailbreak override (Post History Instruction), use that instead." data-i18n="[title]If checked and the character card contains a jailbreak override (Post History Instruction), use that instead." class="checkbox_label">
<input id="prefer_character_jailbreak" type="checkbox" />
<span data-i18n="Prefer Character Card Jailbreak">Prefer Char. JB</span>
<span data-i18n="Prefer Character Card Jailbreak">Prefer Char. Jailbreak</span>
</label>
<label data-newbie-hidden class="checkbox_label" for="never_resize_avatars">
<input id="never_resize_avatars" type="checkbox" />
@ -3668,6 +3774,28 @@
</div>
</div>
<div id="depth_prompt_div" class="flex-container">
<div class="flex1">
<h4>
<span data-i18n="Character's Note">
Character's Note
</span>
</h4>
<textarea id="depth_prompt_prompt" name="depth_prompt_prompt" class="text_pole" rows="2" maxlength="20000" autocomplete="off" form="form_create" placeholder="(Text to be inserted in-chat @ designated depth)"></textarea>
</div>
<div>
<h4>
<span data-i18n="@ Depth">
@ Depth
</span>
</h4>
<input id="depth_prompt_depth" name="depth_prompt_depth" class="text_pole widthUnset m-t-0" type="number" min="0" max="999" value="4" form="form_create" />
<div class="extension_token_counter">
Tokens: <span data-token-counter="depth_prompt_prompt" data-token-permanent="true">counting...</span>
</div>
</div>
</div>
<div id="talkativeness_div">
<h4><span data-i18n="Talkativeness">Talkativeness</span></h4>
<h5 data-i18n="How often the character speaks in group chats!">How often the character speaks in &nbsp;<span class="warning">group chats!</span>
@ -3826,67 +3954,145 @@
<div id="entry_edit_template" class="template_element">
<div class="world_entry">
<form class="world_entry_form">
<div class="inline-drawer wide100p">
<div class="inline-drawer-toggle inline-drawer-header gap5px">
<span class="drag-handle">&#9776;</span>
<div class="gap5px world_entry_thin_controls wide100p">
<div class="world_entry_form_control flex1">
<label for="key">
<small>
<span data-i18n="Keywords">
Keywords
</span>
<span>(UID:&nbsp;
<span class="world_entry_form_uid_value"></span>
)
</span>
</small>
<small class="displayNone">
<span data-i18n="Comma separated (required)">
Comma separated (required)
</span>
</small>
</label>
<div class="world_entry">
<form class="world_entry_form wi-card-entry">
<div class="inline-drawer wide100p">
<div class="inline-drawer-toggle inline-drawer-header gap5px padding0">
<!-- <span class="drag-handle">&#9776;</span> -->
<div class="gap5px world_entry_thin_controls wide100p alignitemscenter">
<div class="fa-fw fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
<span class="flex-container alignitemscenter wide100p">
<div class="WIEntryTitleAndStatus flex-container flex1 alignitemscenter">
<div class="flex-container flex1">
<textarea class="text_pole" name="comment" maxlength="2000" data-i18n="[placeholder]Entry Title/Memo" placeholder="Entry Title/Memo"></textarea>
</div>
<!-- <span class="world_entry_form_position_value"></span> -->
<select title="WI Entry Status:&#13;🔵 Constant&#13;🟢 Normal&#13;❌ Disabled" name="entryStateSelector" class="widthNatural margin0">
<option title="WI Entry Status:&#13;🔵 Constant&#13;🟢 Normal&#13;❌ Disabled" value="constant">🔵</option>
<option title="WI Entry Status:&#13;🔵 Constant&#13;🟢 Normal&#13;❌ Disabled" value="normal">🟢</option>
<option title="WI Entry Status:&#13;🔵 Constant&#13;🟢 Normal&#13;❌ Disabled" value="disabled"></option>
</select>
</div>
<div class="WIEnteryHeaderControls flex-container">
<div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text">
<label for="position" class="WIEntryHeaderTitleMobile" data-i18n="Position:">Position:</label>
<select name="position" class="widthNatural margin0" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">
<option value="0" data-i18n="Before Char Defs" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">↑Char</option>
<option value="1" data-i18n="After Char Defs" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">↓Char</option>
<option value="2" data-i18n="Before AN" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">↑AN</option>
<option value="3" data-i18n="After AN" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">↓AN</option>
<option value="4" data-i18n="at Depth" title="↑Char: Before Character Definitions&#13;↓Char: After Character Definitions&#13;↑AN: Before Author's Note&#13;↓AN: After Author's Note&#13;@D: at Depth&#13;">@D</option>
</select>
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap">
<label for="depth" class="WIEntryHeaderTitleMobile" data-i18n="Depth:">Depth:</label>
<input title="Depth" class="text_pole wideMax100px margin0" type="number" name="depth" placeholder="" min="0" max="999" />
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap">
<label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Order:">Order:</label>
<input title="Order" class="text_pole wideMax100px margin0" type="number" name="order" placeholder="" min="0" max="999" />
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer">
<label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Order:">Trigger %:</label>
<input title="Probability" class="text_pole wideMax100px margin0" type="number" name="probability" placeholder="" min="0" max="100" />
</div>
<!-- <div class="flex-container flex1">
<textarea class="text_pole" name="comment" maxlength="2000" data-i18n="[placeholder]Entry Title/Memo" placeholder="Entry Title/Memo"></textarea>
</div> -->
</div>
</span>
<!-- <div class="world_entry_form_control flex1">
<small class="displayNone">
<span data-i18n="Comma separated (required)">
Comma separated (required)
</span>
</small>
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" data-i18n="[placeholder]Comma separated (required)" placeholder="Comma separated (required)" maxlength="1000"></textarea>
</div>
<div class="flex-container widthFitContent alignItemsFlexEnd">
<select name="entryLogicType" class="height32px widthFitContent margin0">
<select name="entryLogicType" class="widthFitContent margin0">
<option value="0">AND</option>
<option value="1">NOT</option>
</select>
</div>
<div class="world_entry_form_control keysecondary flex1">
<label for="keysecondary">
<small>
<span data-i18n="Secondary Required Keywords">
Optional Filter
</span>
</small>
<small class="displayNone">
<span data-i18n="Comma seperated (ignored if empty)">
Comma seperated (ignored if empty)
</span>
</small>
</label>
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated (ignored if empty)" placeholder="Comma separated (ignored if empty)" maxlength="1000"></textarea>
</div>
<small class="displayNone">
<span data-i18n="(ignored if empty)">
(ignored if empty)
</span>
</small>
<div class="flex-container flexFlowRow alignitemscenter">
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated (ignored if empty)" placeholder="Comma separated list" maxlength="1000"></textarea>
<i class="menu_button delete_entry_button fa-solid fa-trash-can" type="submit" data-i18n="" value="" /></i>
</div>
</div> -->
</div>
<div class="fa-fw fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
<i class="menu_button delete_entry_button fa-solid fa-trash-can" type="submit" data-i18n="" value="" /></i>
</div>
<div class="inline-drawer-content flex-container">
<div class="WIEntryContentAndMemo flex-container">
<div class="world_entry_thin_controls flex2">
<div class="inline-drawer-content flex-container paddingBottom5px wide100p">
<div class="flex-container wide100p alignitemscenter">
<div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter">
<div class="world_entry_form_control flex1">
<small class="displayNone">
<span data-i18n="Comma separated (required)">
Comma separated (required)
</span>
</small>
<small class="textAlignCenter">Primary Keywords</small>
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" data-i18n="[placeholder]Comma separated (required)" placeholder="Comma separated (required)" maxlength="1000"></textarea>
</div>
<div class="world_entry_form_control">
<small class="textAlignCenter">Logic</small>
<select name="entryLogicType" class="widthFitContent margin0">
<option value="0">AND</option>
<option value="1">NOT</option>
</select>
</div>
<div class="world_entry_form_control keysecondary flex1">
<small class="displayNone">
<span data-i18n="(ignored if empty)">
(ignored if empty)
</span>
</small>
<small class="textAlignCenter">Optional Filter</small>
<div class="flex-container flexFlowRow alignitemscenter">
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated (ignored if empty)" placeholder="Comma separated list" maxlength="1000"></textarea>
</div>
</div>
</div>
<div name="contentAndCharFilterBlock" class="world_entry_thin_controls flex2">
<div class="world_entry_form_control flex1">
<label for="content ">
<small>
<span data-i18n="Content">
Content
<span>(Tokens:&nbsp; <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)
<span data-i18n="Content" class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween">
<span class="alignitemscenter flex-container flexNoGap">
Content
</span>
<span>
(Tokens:&nbsp; <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)&nbsp;
<span class="world_entry_form_uid_value" data-first-run="true"></span>
</span>
<div>
<label class="checkbox flex-container alignitemscenter flexNoGap">
<input type="checkbox" name="exclude_recursion" />
<span data-i18n="Exclude from recursion">
Non-recursable
</span>
</label>
</div>
</span>
</small>
<small class="displayNone">
@ -3897,9 +4103,10 @@
</label>
<textarea class="text_pole" name="content" rows="4" data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim" placeholder="What this keyword should mean to the AI, sent verbatim"></textarea>
</div>
</div>
<div class="world_entry_thin_controls commentContainer">
<div class="world_entry_form_control flex1">
<!-- <div class="world_entry_form_control flex1">
<label for="comment">
<small>
<span data-i18n="Memo/Note">
@ -3913,11 +4120,48 @@
</small>
</label>
<textarea class="text_pole" rows="4" name="comment" maxlength="2000" data-i18n="[placeholder]Not sent to the AI" placeholder="Not sent to AI"></textarea>
</div>
</div> -->
</div>
</div>
<div class="flex-container flexFlowColumn flexNoGap wide100p">
<div class="flex-container justifySpaceBetween">
<label for="characterFilter" class="">
<small data-i18n="Filter to Character(s)">Filter to Character(s)</small>
</label>
<label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="character_exclusion" />
<span data-i18n="Character Exclusion">
<small>Character Exclusion</small>
</span>
</label>
</div>
<!-- PLACEHOLDER HTML FOR CHAR FILTER EXCLUDE CONVERSION TO SELECT INSTEAD OF CHECKBOX-->
<!--
<div name="WICharFilterLabel" class="flex-container alignitemscenter marginBot5">
<small data-i18n="Filter Entry">Filter Entry</small>
<div>
<select name="character_exclusion" class="widthFitContent margin0">
<option value="only">to Only</option>
<option value="except">to Exclude</option>
</select>
</div>
<small>the following Characters:</small>
</div>
-->
<div class="range-block-range">
<select name="characterFilter" multiple>
<option value="">
<span data-i18n="-- Characters not found --">-- Characters not found --</span>
</option>
</select>
</div>
</div>
<div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
<!--
<label class="checkbox flex-container">
<input type="checkbox" name="constant" />
<span data-i18n="Constant">Constant</span>
@ -3926,6 +4170,7 @@
<input type="checkbox" name="disable" />
<span data-i18n="Disable">Disable</span>
</label>
-->
<label class="checkbox flex-container">
<input type="checkbox" name="selective" />
<span data-i18n="Selective">Selective</span>
@ -3938,12 +4183,18 @@
<input type="checkbox" name="addMemo">
<span data-i18n="Add Memo">Add Memo</span>
</label>
<label class="checkbox flex-container alignitemscenter">
<!-- <label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="exclude_recursion" />
<span data-i18n="Exclude from recursion">
Non-recursable
</span>
</label>
</label> -->
<!-- <label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="character_exclusion" />
<span data-i18n="Character Exclusion">
Character Exclusion
</span>
</label> -->
</div>
<!--
@ -3959,7 +4210,7 @@
</div>
-->
<div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<!-- <div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<label for="position" data-i18n="Position:">Position:</label>
<small>
<select name="position">
@ -3972,28 +4223,23 @@
</small>
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
<label for="depth" data-i18n="Depth:">Depth:</label>
<input class="text_pole wideMax100px margin0" type="number" name="depth" placeholder="" min="0" max="999" />
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
<label for="order" data-i18n="Order:">Order:</label>
<input class="text_pole wideMax100px margin0" type="number" name="order" placeholder="" min="0" max="10000" />
</div>
</div> -->
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer">
<!-- <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer">
<label for="probability" data-i18n="Probability:"></label>Probability:</label>
<input class="text_pole wideMax100px margin0" type="number" name="probability" placeholder="" min="0" max="100" />
</div>
</div> -->
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
</div>
<input class="menu_button delete_entry_button" type="submit" data-i18n="Delete Entry" value="Delete Entry" />
</div>
<div class="wide100p">
<hr>
</div>
</div>
@ -4320,7 +4566,7 @@
</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" />
In-chat @ Depth <input id="extension_floating_depth" class="text_pole widthUnset" type="number" min="0" max="999" />
</label>
</div>
<!--<label for="extension_floating_interval">In-Chat Insertion Depth</label>-->
@ -4336,7 +4582,14 @@
<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="flex-container flexFlowColumn">
<b data-i18n="Character Author's Note (Private)">
Character Author's Note (Private)
</b>
<small data-i18n="Won't be shared with the character card on export.">
Won't be shared with the character card on export.
</small>
</div>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
@ -4388,7 +4641,7 @@
</label>
<label>
<input type="radio" name="extension_default_position" value="1" />
In-chat @ Depth <input id="extension_default_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
In-chat @ Depth <input id="extension_default_depth" class="text_pole widthUnset" type="number" min="0" max="999" />
</label>
</div>
<label for="extension_default_interval">Insertion Frequency</label>

View File

@ -0,0 +1,18 @@
{
"system_prompt": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]",
"input_sequence": "",
"output_sequence": "",
"last_output_sequence": "",
"system_sequence": "",
"stop_sequence": "",
"separator_sequence": "",
"wrap": true,
"macro": true,
"names": false,
"names_force_groups": false,
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",
"first_output_sequence": "",
"name": "Adventure"
}

View File

@ -0,0 +1,17 @@
{
"wrap": false,
"names": true,
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.",
"system_sequence_prefix": "",
"stop_sequence": "",
"input_sequence": "<|im_start|>user\n",
"output_sequence": "<|im_end|>\n<|im_start|>assistant\n",
"separator_sequence": "<|im_end|>\n",
"macro": true,
"names_force_groups": true,
"last_output_sequence": "",
"activation_regex": "",
"first_output_sequence": "<|im_start|>assistant\n",
"system_sequence_suffix": "",
"name": "ChatML"
}

View File

@ -0,0 +1,17 @@
{
"wrap": true,
"names": true,
"system_prompt": "Avoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.",
"system_sequence_prefix": "",
"stop_sequence": "",
"input_sequence": "",
"output_sequence": "",
"separator_sequence": "",
"macro": true,
"names_force_groups": true,
"last_output_sequence": "\n### Response:",
"activation_regex": "",
"first_output_sequence": "",
"system_sequence_suffix": "",
"name": "Libra-32B"
}

View File

@ -0,0 +1,18 @@
{
"wrap": true,
"names": false,
"system_prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nTake the role of {{char}} in a play that leaves a lasting impression on {{user}}. Write {{char}}'s next reply.\nNever skip or gloss over {{char}}s actions. Progress the scene at a naturally slow pace.\n\n",
"system_sequence": "",
"stop_sequence": "",
"input_sequence": "### Instruction:",
"output_sequence": "### Response: (length = unlimited)",
"separator_sequence": "",
"macro": true,
"names_force_groups": true,
"last_output_sequence": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",
"first_output_sequence": "",
"activation_regex": "",
"name": "Lightning 1.1"
}

View File

@ -0,0 +1,17 @@
{
"wrap": false,
"names": true,
"system_prompt": "Write {{char}}'s next reply in this fictional roleplay with {{user}}.",
"system_sequence_prefix": "",
"stop_sequence": "",
"input_sequence": "[INST] ",
"output_sequence": " [/INST]\n",
"separator_sequence": "\n",
"macro": true,
"names_force_groups": true,
"last_output_sequence": "",
"activation_regex": "",
"first_output_sequence": "\n",
"system_sequence_suffix": "",
"name": "Mistral"
}

View File

@ -0,0 +1,18 @@
{
"system_prompt": "",
"input_sequence": "",
"output_sequence": "",
"last_output_sequence": "",
"system_sequence": "",
"stop_sequence": "",
"separator_sequence": "",
"wrap": true,
"macro": true,
"names": false,
"names_force_groups": false,
"activation_regex": "",
"system_sequence_prefix": "",
"system_sequence_suffix": "",
"first_output_sequence": "",
"name": "Story"
}

View File

@ -0,0 +1,17 @@
{
"wrap": false,
"names": false,
"system_prompt": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation.",
"system_sequence_prefix": "SYSTEM: ",
"stop_sequence": "",
"input_sequence": "USER: ",
"output_sequence": "\nASSISTANT: ",
"separator_sequence": "\n",
"macro": true,
"names_force_groups": true,
"last_output_sequence": "",
"activation_regex": "",
"first_output_sequence": "ASSISTANT: ",
"system_sequence_suffix": "",
"name": "Synthia"
}

View File

@ -16,6 +16,11 @@ import {
generateTextGenWithStreaming,
getTextGenGenerationData,
formatTextGenURL,
getTextGenUrlSourceId,
isMancer,
isAphrodite,
textgen_types,
textgenerationwebui_banned_in_macros,
} from "./scripts/textgen-settings.js";
import {
@ -178,7 +183,6 @@ import {
import { applyLocale } from "./scripts/i18n.js";
import { getTokenCount, getTokenizerModel, saveTokenCache } from "./scripts/tokenizers.js";
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
import { loadMancerModels } from "./scripts/mancer-settings.js";
//exporting functions and vars for mods
export {
@ -390,6 +394,8 @@ const extension_prompt_types = {
BEFORE_PROMPT: 2
};
export const MAX_INJECTION_DEPTH = 1000;
let system_messages = {};
function getSystemMessages() {
@ -589,6 +595,8 @@ function getCurrentChatId() {
}
const talkativeness_default = 0.5;
const depth_prompt_depth_default = 4;
const per_page_default = 50;
var is_advanced_char_open = false;
@ -611,7 +619,9 @@ let create_save = {
mes_example: "",
world: "",
talkativeness: talkativeness_default,
alternate_greetings: []
alternate_greetings: [],
depth_prompt_prompt: '',
depth_prompt_depth: depth_prompt_depth_default,
};
//animation right menu
@ -630,7 +640,6 @@ let is_get_status = false;
let is_get_status_novel = false;
let is_api_button_press = false;
let is_api_button_press_novel = false;
let api_use_mancer_webui = false;
let is_send_press = false; //Send generation
@ -769,7 +778,8 @@ async function getStatus() {
data: JSON.stringify({
api_server: main_api == "kobold" ? api_server : api_server_textgenerationwebui,
main_api: main_api,
use_mancer: main_api == "textgenerationwebui" ? api_use_mancer_webui : false,
use_mancer: main_api == "textgenerationwebui" ? isMancer() : false,
use_aphrodite: main_api == "textgenerationwebui" ? isAphrodite() : false,
}),
beforeSend: function () { },
cache: false,
@ -913,7 +923,7 @@ async function printCharacters(fullRefresh = false) {
const storageKey = 'Characters_PerPage';
$("#rm_print_characters_pagination").pagination({
dataSource: getEntitiesList({ doFilter: true }),
pageSize: Number(localStorage.getItem(storageKey)) || 50,
pageSize: Number(localStorage.getItem(storageKey)) || per_page_default,
sizeChangerOptions: [10, 25, 50, 100, 250, 500, 1000],
pageRange: 1,
pageNumber: saveCharactersPage || 1,
@ -1741,6 +1751,13 @@ function substituteParams(content, _name1, _name2, _original, _group) {
content = content.replace(/{{time}}/gi, moment().format('LT'));
content = content.replace(/{{date}}/gi, moment().format('LL'));
content = content.replace(/{{weekday}}/gi, moment().format('dddd'));
content = content.replace(/{{isotime}}/gi, moment().format('HH:mm'));
content = content.replace(/{{isodate}}/gi, moment().format('YYYY-MM-DD'));
content = content.replace(/{{datetimeformat +([^}]*)}}/gi, (_, format) => {
const formattedTime = moment().format(format);
return formattedTime;
});
content = content.replace(/{{idle_duration}}/gi, () => getTimeSinceLastMessage());
content = content.replace(/{{time_UTC([-+]\d+)}}/gi, (_, offset) => {
const utcOffset = parseInt(offset, 10);
@ -1749,9 +1766,37 @@ function substituteParams(content, _name1, _name2, _original, _group) {
});
content = randomReplace(content);
content = diceRollReplace(content);
content = bannedWordsReplace(content);
return content;
}
/**
* Replaces banned words in macros with an empty string.
* Adds them to textgenerationwebui ban list.
* @param {string} inText Text to replace banned words in
* @returns {string} Text without the "banned" macro
*/
function bannedWordsReplace(inText) {
if (!inText) {
return '';
}
const banPattern = /{{banned "(.*)"}}/gi;
if (main_api == 'textgenerationwebui') {
const bans = inText.matchAll(banPattern);
if (bans) {
for (const banCase of bans) {
console.log("Found banned words in macros: " + banCase[1]);
textgenerationwebui_banned_in_macros.push(banCase[1]);
}
}
}
inText = inText.replaceAll(banPattern, "");
return inText;
}
function getTimeSinceLastMessage() {
const now = moment();
@ -2002,6 +2047,7 @@ function addPersonaDescriptionExtensionPrompt() {
const ANWithDesc = power_user.persona_description_position === persona_description_positions.TOP_AN
? `${power_user.persona_description}\n${originalAN}`
: `${originalAN}\n${power_user.persona_description}`;
setExtensionPrompt(NOTE_MODULE_NAME, ANWithDesc, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]);
}
}
@ -2049,7 +2095,8 @@ function baseChatReplace(value, name1, name2) {
}
function isStreamingEnabled() {
return ((main_api == 'openai' && oai_settings.stream_openai && oai_settings.chat_completion_source !== chat_completion_sources.SCALE && oai_settings.chat_completion_source !== chat_completion_sources.AI21)
const noStreamSources = [chat_completion_sources.SCALE, chat_completion_sources.AI21, chat_completion_sources.PALM];
return ((main_api == 'openai' && oai_settings.stream_openai && !noStreamSources.includes(oai_settings.chat_completion_source))
|| (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming)
|| (main_api == 'novel' && nai_settings.streaming_novel)
|| (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming));
@ -2319,7 +2366,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
return;
}
if (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming && !textgenerationwebui_settings.streaming_url) {
if (
main_api == 'textgenerationwebui' &&
textgenerationwebui_settings.streaming &&
textgenerationwebui_settings.type === textgen_types.OOBA &&
!textgenerationwebui_settings.streaming_url) {
toastr.error('Streaming URL is not set. Look it up in the console window when starting TextGen Web UI');
is_send_press = false;
return;
@ -2464,6 +2515,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
systemPrompt = formatInstructModeSystemPrompt(substituteParams(systemPrompt, name1, name2, power_user.instruct.system_prompt));
}
// Depth prompt (character-specific A/N)
const depthPromptText = baseChatReplace(characters[this_chid].data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2) || '';
const depthPromptDepth = characters[this_chid].data?.extensions?.depth_prompt?.depth ?? depth_prompt_depth_default;
setExtensionPrompt('DEPTH_PROMPT', depthPromptText, extension_prompt_types.IN_CHAT, depthPromptDepth);
// Parse example messages
if (!mesExamples.startsWith('<START>')) {
mesExamples = '<START>\n' + mesExamples.trim();
@ -2563,7 +2619,16 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
// Set non-WI AN
setFloatingPrompt();
// Add WI to prompt (and also inject WI to AN value via hijack)
let { worldInfoString, worldInfoBefore, worldInfoAfter } = await getWorldInfoPrompt(chat2, this_max_context);
let { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoDepth } = await getWorldInfoPrompt(chat2, this_max_context);
// Add all depth WI entries to prompt
if (Array.isArray(worldInfoDepth)) {
worldInfoDepth.forEach((e) => {
const joinedEntries = e.entries.join("\n");
setExtensionPrompt(`customDepthWI-${e.depth}`, joinedEntries, extension_prompt_types.IN_CHAT, e.depth)
});
}
// Add persona description to prompt
addPersonaDescriptionExtensionPrompt();
// Call combined AN into Generate
@ -2873,7 +2938,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
// TODO: Rewrite getExtensionPrompt to not require multiple for loops
// Set all extension prompts where insertion depth > mesSend length
if (finalMesSend.length) {
for (let upperDepth = 100; upperDepth >= finalMesSend.length; upperDepth--) {
for (let upperDepth = MAX_INJECTION_DEPTH; upperDepth >= finalMesSend.length; upperDepth--) {
const upperAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, upperDepth);
if (upperAnchor && upperAnchor.length) {
finalMesSend[0].extensionPrompts.push(upperAnchor);
@ -2997,7 +3062,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
}
else if (main_api == 'textgenerationwebui') {
generate_data = getTextGenGenerationData(finalPrompt, this_amount_gen, isImpersonate, cfgValues);
generate_data.use_mancer = api_use_mancer_webui;
generate_data.use_mancer = isMancer();
generate_data.use_aphrodite = isAphrodite();
}
else if (main_api == 'novel') {
const this_settings = novelai_settings[novelai_setting_names[nai_settings.preset_settings_novel]];
@ -3233,7 +3299,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
//console.log('runGenerate calling showSwipeBtns');
showSwipeButtons();
if (main_api == 'textgenerationwebui' && api_use_mancer_webui) {
if (main_api == 'textgenerationwebui' && isMancer()) {
const errorText = `<h3>Inferencer endpoint is unhappy!</h3>
Returned status <tt>${data.status}</tt> with the reason:<br/>
${data.response}`;
@ -4633,6 +4699,7 @@ function changeMainAPI() {
case chat_completion_sources.CLAUDE:
case chat_completion_sources.OPENAI:
case chat_completion_sources.AI21:
case chat_completion_sources.PALM:
default:
setupChatCompletionPromptManager(oai_settings);
break;
@ -4965,9 +5032,7 @@ async function getSettings(type) {
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
$("#textgenerationwebui_api_url_text").val(api_server_textgenerationwebui);
$("#mancer_api_url_text").val(api_server_textgenerationwebui);
api_use_mancer_webui = settings.api_use_mancer_webui
$('#use-mancer-api-checkbox').prop("checked", api_use_mancer_webui);
$('#use-mancer-api-checkbox').trigger("change");
$("#aphrodite_api_url_text").val(api_server_textgenerationwebui);
selected_button = settings.selected_button;
@ -5003,7 +5068,6 @@ async function saveSettings(type) {
active_group: active_group,
api_server: api_server,
api_server_textgenerationwebui: api_server_textgenerationwebui,
api_use_mancer_webui: api_use_mancer_webui,
preset_settings: preset_settings,
user_avatar: user_avatar,
amount_gen: amount_gen,
@ -5431,7 +5495,7 @@ function select_rm_info(type, charId, previousCharId = null) {
}
try {
const perPage = Number(localStorage.getItem('Characters_PerPage'));
const perPage = Number(localStorage.getItem('Characters_PerPage')) || per_page_default;
const page = Math.floor(charIndex / perPage) + 1;
const selector = `#rm_print_characters_block [title^="${charId}"]`;
$('#rm_print_characters_pagination').pagination('go', page);
@ -5466,7 +5530,7 @@ function select_rm_info(type, charId, previousCharId = null) {
return;
}
const perPage = Number(localStorage.getItem('Characters_PerPage'));
const perPage = Number(localStorage.getItem('Characters_PerPage')) || per_page_default;
const page = Math.floor(charIndex / perPage) + 1;
$('#rm_print_characters_pagination').pagination('go', page);
const selector = `#rm_print_characters_block [grid="${charId}"]`;
@ -5535,6 +5599,8 @@ export function select_selected_character(chid) {
$("#personality_textarea").val(characters[chid].personality);
$("#firstmessage_textarea").val(characters[chid].first_mes);
$("#scenario_pole").val(characters[chid].scenario);
$("#depth_prompt_prompt").val(characters[chid].data?.extensions?.depth_prompt?.prompt ?? '');
$("#depth_prompt_depth").val(characters[chid].data?.extensions?.depth_prompt?.depth ?? depth_prompt_depth_default);
$("#talkativeness_slider").val(characters[chid].talkativeness || talkativeness_default);
$("#mes_example_textarea").val(characters[chid].mes_example);
$("#selected_chat_pole").val(characters[chid].chat);
@ -5602,6 +5668,8 @@ function select_rm_create() {
$("#firstmessage_textarea").val(create_save.first_message);
$("#talkativeness_slider").val(create_save.talkativeness);
$("#scenario_pole").val(create_save.scenario);
$("#depth_prompt_prompt").val(create_save.depth_prompt_prompt);
$("#depth_prompt_depth").val(create_save.depth_prompt_depth);
$("#mes_example_textarea").val(create_save.mes_example.trim().length === 0 ? '<START>' : create_save.mes_example);
$('#character_json_data').val('');
$("#avatar_div").css("display", "flex");
@ -5630,7 +5698,7 @@ function select_rm_characters() {
* @param {string} key Prompt injection id.
* @param {string} value Prompt injection value.
* @param {number} position Insertion position. 0 is after story string, 1 is in-chat with custom depth.
* @param {number} depth Insertion depth. 0 represets the last message in context. Expected values up to 100.
* @param {number} depth Insertion depth. 0 represets the last message in context. Expected values up to MAX_INJECTION_DEPTH.
*/
export function setExtensionPrompt(key, value, position, depth) {
extension_prompts[key] = { value: String(value), position: Number(position), depth: Number(depth) };
@ -6254,6 +6322,8 @@ async function createOrEditCharacter(e) {
{ id: '#firstmessage_textarea', callback: value => create_save.first_message = value },
{ id: '#talkativeness_slider', callback: value => create_save.talkativeness = value, defaultValue: talkativeness_default },
{ id: '#scenario_pole', callback: value => create_save.scenario = value },
{ id: '#depth_prompt_prompt', callback: value => create_save.depth_prompt_prompt = value },
{ id: '#depth_prompt_depth', callback: value => create_save.depth_prompt_depth = value, defaultValue: depth_prompt_depth_default },
{ id: '#mes_example_textarea', callback: value => create_save.mes_example = value },
{ id: '#character_json_data', callback: () => { } },
{ id: '#alternate_greetings_template', callback: value => create_save.alternate_greetings = value, defaultValue: [] },
@ -6758,11 +6828,21 @@ function connectAPISlash(_, text) {
source: 'openrouter',
button: '#api_button_openai',
},
'scale': {
selected: 'openai',
source: 'scale',
button: '#api_button_openai',
},
'ai21': {
selected: 'openai',
source: 'ai21',
button: '#api_button_openai',
}
},
'palm': {
selected: 'openai',
source: 'palm',
button: '#api_button_openai',
},
};
const apiConfig = apiMap[text];
@ -6995,11 +7075,11 @@ jQuery(async function () {
}
registerSlashCommand('dupe', DupeChar, [], " duplicates the currently selected character", true, true);
registerSlashCommand('api', connectAPISlash, [], "(kobold, horde, novel, ooba, oai, claude, windowai, ai21) 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);
registerSlashCommand('closechat', doCloseChat, [], "- closes the current chat", true, true);
registerSlashCommand('panels', doTogglePanels, ['togglepanels'], "- toggle UI panels on/off", true, true);
registerSlashCommand('api', connectAPISlash, [], '<span class="monospace">(kobold, horde, novel, ooba, oai, claude, windowai, openrouter, scale, ai21, palm)</span> 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);
registerSlashCommand('closechat', doCloseChat, [], " closes the current chat", true, true);
registerSlashCommand('panels', doTogglePanels, ['togglepanels'], " toggle UI panels on/off", true, true);
setTimeout(function () {
$("#groupControlsToggle").trigger('click');
@ -7420,23 +7500,25 @@ jQuery(async function () {
$("#character_name_pole").on("input", function () {
if (menu_type == "create") {
create_save.name = $("#character_name_pole").val();
create_save.name = String($("#character_name_pole").val());
}
});
const elementsToUpdate = {
'#description_textarea': function () { create_save.description = $("#description_textarea").val(); },
'#creator_notes_textarea': function () { create_save.creator_notes = $("#creator_notes_textarea").val(); },
'#character_version_textarea': function () { create_save.character_version = $("#character_version_textarea").val(); },
'#system_prompt_textarea': function () { create_save.system_prompt = $("#system_prompt_textarea").val(); },
'#post_history_instructions_textarea': function () { create_save.post_history_instructions = $("#post_history_instructions_textarea").val(); },
'#creator_textarea': function () { create_save.creator = $("#creator_textarea").val(); },
'#tags_textarea': function () { create_save.tags = $("#tags_textarea").val(); },
'#personality_textarea': function () { create_save.personality = $("#personality_textarea").val(); },
'#scenario_pole': function () { create_save.scenario = $("#scenario_pole").val(); },
'#mes_example_textarea': function () { create_save.mes_example = $("#mes_example_textarea").val(); },
'#firstmessage_textarea': function () { create_save.first_message = $("#firstmessage_textarea").val(); },
'#talkativeness_slider': function () { create_save.talkativeness = $("#talkativeness_slider").val(); },
'#description_textarea': function () { create_save.description = String($("#description_textarea").val()); },
'#creator_notes_textarea': function () { create_save.creator_notes = String($("#creator_notes_textarea").val()); },
'#character_version_textarea': function () { create_save.character_version = String($("#character_version_textarea").val()); },
'#system_prompt_textarea': function () { create_save.system_prompt = String($("#system_prompt_textarea").val()); },
'#post_history_instructions_textarea': function () { create_save.post_history_instructions = String($("#post_history_instructions_textarea").val()); },
'#creator_textarea': function () { create_save.creator = String($("#creator_textarea").val()); },
'#tags_textarea': function () { create_save.tags = String($("#tags_textarea").val()); },
'#personality_textarea': function () { create_save.personality = String($("#personality_textarea").val()); },
'#scenario_pole': function () { create_save.scenario = String($("#scenario_pole").val()); },
'#mes_example_textarea': function () { create_save.mes_example = String($("#mes_example_textarea").val()); },
'#firstmessage_textarea': function () { create_save.first_message = String($("#firstmessage_textarea").val()); },
'#talkativeness_slider': function () { create_save.talkativeness = Number($("#talkativeness_slider").val()); },
'#depth_prompt_prompt': function () { create_save.depth_prompt_prompt = String($("#depth_prompt_prompt").val()); },
'#depth_prompt_depth': function () { create_save.depth_prompt_depth = Number($("#depth_prompt_depth").val()); },
};
Object.keys(elementsToUpdate).forEach(function (id) {
@ -7587,41 +7669,30 @@ jQuery(async function () {
}
});
$("#use-mancer-api-checkbox").on("change", function (e) {
const enabled = $("#use-mancer-api-checkbox").prop("checked");
$("#mancer_api_subpanel").toggle(enabled);
$("#tgwebui_api_subpanel").toggle(!enabled);
$("#api_button_textgenerationwebui").on('click', async function (e) {
const urlSourceId = getTextGenUrlSourceId();
api_use_mancer_webui = enabled;
saveSettingsDebounced();
getStatus();
if (enabled) {
loadMancerModels();
}
});
$("#api_button_textgenerationwebui").click(async function (e) {
const url_source = api_use_mancer_webui ? "#mancer_api_url_text" : "#textgenerationwebui_api_url_text";
if ($(url_source).val() != "") {
let value = formatTextGenURL(String($(url_source).val()).trim(), api_use_mancer_webui);
if ($(urlSourceId).val() != "") {
let value = formatTextGenURL(String($(urlSourceId).val()).trim(), isMancer());
if (!value) {
callPopup("Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt><br/>Enable 'Relaxed API URLs' to allow other paths.", 'text');
return;
}
const mancer_key = String($("#api_key_mancer").val()).trim();
if (mancer_key.length) {
await writeSecret(SECRET_KEYS.MANCER, mancer_key);
const mancerKey = String($("#api_key_mancer").val()).trim();
if (mancerKey.length) {
await writeSecret(SECRET_KEYS.MANCER, mancerKey);
}
$(url_source).val(value);
const aphroditeKey = String($("#api_key_aphrodite").val()).trim();
if (aphroditeKey.length) {
await writeSecret(SECRET_KEYS.APHRODITE, aphroditeKey);
}
$(urlSourceId).val(value);
$("#api_loading_textgenerationwebui").css("display", "inline-block");
$("#api_button_textgenerationwebui").css("display", "none");
if (api_use_mancer_webui) {
textgenerationwebui_settings.streaming_url = value.replace("http", "ws") + "/v1/stream";
}
api_server_textgenerationwebui = value;
main_api = "textgenerationwebui";
saveSettingsDebounced();
@ -7699,6 +7770,7 @@ jQuery(async function () {
}
else if (id == "option_regenerate") {
closeMessageEditor();
if (is_send_press == false) {
//hideSwipeButtons();

View File

@ -415,6 +415,7 @@ function RA_autoconnect(PrevApi) {
|| (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI)
|| (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER)
|| (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21)
|| (secret_state[SECRET_KEYS.PALM] && oai_settings.chat_completion_source == chat_completion_sources.PALM)
) {
$("#api_button_openai").click();
}

View File

@ -5,31 +5,12 @@
.audio-mixer-div {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 5px;
background-color: rgba(38, 38, 38, 0.5);
border: 1px rgb(75, 75, 75) solid;
border-radius: 10px;
}
.audio-mixer-element {
height: 60px;
float: left;
margin-right: 10px;
label {
text-align: top;
}
input {
margin-top: 15px;
}
select {
margin-top: 5px;
padding: 5px;
width: 100%;
}
}
.audio-label {
display: block;
text-align: center;
@ -43,19 +24,16 @@
}
.audio-lock-button {
padding: 1rem;
width: 100%;
height: 2em;
}
.audio-random-button {
padding: 1rem;
width: 100%;
height: 2em;
}
.audio-mute-button {
padding: 1rem;
width: 100%;
height: 2em;
}
@ -78,18 +56,37 @@
width: 10%;
}
.audio-mixer-volume {
width: 25%;
}
.audio-mixer-playlist {
width: 45%;
}
.audio-mixer-lock {
width: 10%;
}
.audio-mixer-random {
width: 10%;
}
}
.audio-container {
display: flex;
gap: 10px;
align-items: center;
}
.audio-container>.vol {
width: 100px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.audio-container>.vol>input {
width: 100%;
}
.audio-container>.playlist {
flex-grow: 1;
}
.audio-container>.playlist>select {
height: 100%;
margin: 0 !important;
}

View File

@ -16,14 +16,6 @@
<small>Enable expression BGM switch (req. character expression)</small>
</label>
</div>
<!--
<div id="audio_ambient_dynamic_enable_div">
<label class="checkbox_label" for="audio_dynamic_ambient_enabled">
<input type="checkbox" id="audio_dynamic_ambient_enabled" name="audio_dynamic_ambient_enabled">
<small>Enable ambient background switch (req. chat background)</small>
</label>
</div>
-->
<div id="audio_debug_div">
<label class="checkbox_label" for="audio_debug">
<input type="checkbox" id="audio_debug" name="audio_debug">
@ -40,32 +32,27 @@
<div>
<div class="audio-ui-block">
<label for="audio_bgm_volume_slider">Music</label>
<div class="audio-mixer-div">
<div class="audio-mixer-div audio-container">
<div class="audio-mixer-element audio-mixer-mute">
<label for="audio_bgm_lock" class="audio-label">Mute</label>
<div id="audio_bgm_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_bgm_mute_icon"></i>
<i class="fa-solid fa-volume-high fa-lg fa-fw" id="audio_bgm_mute_icon"></i>
</div>
</div>
<div class="audio-mixer-element audio-mixer-volume">
<label for="audio_bgm_lock" class="audio-label">Vol <span id="audio_bgm_volume"></span></label>
<div class="audio-mixer-element vol audio-mixer-volume">
<input type="range" class ="audio-slider" id ="audio_bgm_volume_slider" value = "0" maxlength ="100">
</div>
<div class="audio-mixer-element audio-mixer-playlist">
<label for="audio_bgm_lock" class="audio-label">Playlist</label>
<div class="audio-mixer-element playlist audio-mixer-playlist">
<select id="audio_bgm_select">
</select>
</div>
<div class="audio-mixer-element audio-mixer-lock">
<label for="audio_bgm_lock" class="audio-label">Loop</label>
<div id="audio_bgm_lock" class="menu_button audio-lock-button">
<i class="fa-solid fa-repeat fa-lg" id="audio_bgm_lock_icon"></i>
<i class="fa-solid fa-repeat fa-lg fa-fw" id="audio_bgm_lock_icon"></i>
</div>
</div>
<div class="audio-mixer-element audio-mixer-random">
<label for="audio_bgm_random" class="audio-label">Roll</label>
<div id="audio_bgm_random" class="menu_button audio-random-button">
<i class="fa-solid fa-random fa-lg" id="audio_bgm_random_icon"></i>
<i class="fa-solid fa-random fa-lg fa-fw" id="audio_bgm_random_icon"></i>
</div>
</div>
</div>
@ -73,26 +60,22 @@
</div>
<div>
<label for="audio_ambient_volume_slider">Ambient</label>
<div class="audio-mixer-div">
<div class="audio-mixer-div audio-container">
<div class="audio-mixer-element audio-mixer-mute">
<label for="audio_ambient_lock" class="audio-label">Mute</label>
<div id="audio_ambient_mute" class="menu_button audio-mute-button">
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
<i class="fa-solid fa-volume-high fa-lg fa-fw" id="audio_ambient_mute_icon"></i>
</div>
</div>
<div class="audio-mixer-element audio-mixer-volume">
<label for="audio_ambient_lock" class="audio-label">Vol <span id="audio_ambient_volume"></span></label>
<div class="audio-mixer-element vol audio-mixer-volume">
<input type="range" class ="audio-slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
</div>
<div class="audio-mixer-element audio-mixer-playlist">
<label for="audio_ambient_lock" class="audio-label">Playlist</label>
<div class="audio-mixer-element playlist audio-mixer-playlist">
<select id="audio_ambient_select">
</select>
</div>
<div class="audio-mixer-element">
<label for="audio_ambient_lock audio-mixer-lock" class="audio-label">Lock</label>
<div id="audio_ambient_lock" class="menu_button audio-lock-button">
<i class="fa-solid fa-lock-open fa-lg" id="audio_ambient_lock_icon"></i>
<i class="fa-solid fa-lock-open fa-lg fa-fw" id="audio_ambient_lock_icon"></i>
</div>
</div>
</div>
@ -112,9 +95,9 @@
Create a folder name <b>bgm</b> inside of it.
Put bgm music with expressions there. File names should follow the pattern:
<it>[expression_label]_[number].mp3</it>
By default one of the <it>neutral_[number].mp3</it> will play if classify module is not active.
By default one of the <it>neutral_[number].mp3</it> will play if classify module is not active.
</i>
</div>
</div>
</div>
</div>
</div>

View File

@ -170,9 +170,9 @@ $(document).ready(function () {
}
addSettings();
registerSlashCommand('lockbg', onLockBackgroundClick, ['bglock'], " locks a background for the currently selected chat", true, true);
registerSlashCommand('unlockbg', onUnlockBackgroundClick, ['bgunlock'], ' unlocks a background for the currently selected chat', true, true);
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' automatically changes the background based on the chat context using the AI request prompt', true, true);
registerSlashCommand('lockbg', onLockBackgroundClick, ['bglock'], " locks a background for the currently selected chat", true, true);
registerSlashCommand('unlockbg', onUnlockBackgroundClick, ['bgunlock'], ' unlocks a background for the currently selected chat', true, true);
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' automatically changes the background based on the chat context using the AI request prompt', true, true);
eventSource.on(event_types.FORCE_SET_BACKGROUND, forceSetBackground);
eventSource.on(event_types.CHAT_CHANGED, moduleWorker);
});

View File

@ -563,6 +563,11 @@ async function moduleWorker() {
await forceUpdateVisualNovelMode();
}
if (context.groupId && !Array.isArray(spriteCache[spriteFolderName])) {
await validateImages(spriteFolderName, true);
await forceUpdateVisualNovelMode();
}
offlineMode.css('display', 'none');
}
@ -584,7 +589,7 @@ async function moduleWorker() {
}
// Throttle classification requests during streaming
if (context.streamingProcessor && !context.streamingProcessor.isFinished) {
if (!context.groupId && context.streamingProcessor && !context.streamingProcessor.isFinished) {
const now = Date.now();
const timeSinceLastServerResponse = now - lastServerResponseTime;
@ -1495,6 +1500,6 @@ function setExpressionOverrideHtml(forceClear = false) {
});
eventSource.on(event_types.MOVABLE_PANELS_RESET, updateVisualNovelModeDebounced);
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
registerSlashCommand('sprite', setSpriteSlashCommand, ['emote'], '<span class="monospace">spriteId</span> force sets the sprite for the current character', true, true);
registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '<span class="monospace">folder</span> sets an override sprite folder for the current character. If the name starts with a slash or a backslash, selects a sub-folder in the character-named folder. Empty value to reset to default.', true, true);
registerSlashCommand('sprite', setSpriteSlashCommand, ['emote'], '<span class="monospace">(spriteId)</span> force sets the sprite for the current character', true, true);
registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '<span class="monospace">(optional folder)</span> sets an override sprite folder for the current character. If the name starts with a slash or a backslash, selects a sub-folder in the character-named folder. Empty value to reset to default.', true, true);
})();

View File

@ -404,7 +404,7 @@ function viewWithDragbox(items) {
// Registers a simple command for opening the char gallery.
registerSlashCommand("show-gallery", showGalleryCommand, ["sg"], "Shows the gallery", true, true);
registerSlashCommand("show-gallery", showGalleryCommand, ["sg"], " shows the gallery", true, true);
function showGalleryCommand(args) {
showCharGallery();

View File

@ -325,5 +325,5 @@ jQuery(async () => {
if ($('#idle_random_time').prop('checked')) {
$('#idle_timer_min').parent().show();
}
registerSlashCommand('idle', toggleIdle, [], ' toggles idle mode', true, true);
registerSlashCommand('idle', toggleIdle, [], ' toggles idle mode', true, true);
});

View File

@ -584,7 +584,7 @@ jQuery(function () {
</label>
<label>
<input type="radio" name="memory_position" value="1" />
In-chat @ Depth <input id="memory_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
In-chat @ Depth <input id="memory_depth" class="text_pole widthUnset" type="number" min="0" max="999" />
</label>
</div>
<div data-source="main" class="memory_contents_controls">
@ -650,5 +650,5 @@ jQuery(function () {
eventSource.on(event_types.MESSAGE_EDITED, onChatEvent);
eventSource.on(event_types.MESSAGE_SWIPED, onChatEvent);
eventSource.on(event_types.CHAT_CHANGED, onChatEvent);
registerSlashCommand('summarize', forceSummarizeChat, [], ' forces the summarization of the current chat using the Main API', true, true);
registerSlashCommand('summarize', forceSummarizeChat, [], ' forces the summarization of the current chat using the Main API', true, true);
});

View File

@ -23,26 +23,9 @@ let lastMessageWasSwipe = false
const defaultPrompts = {
"createTask": `Pause your roleplay and generate a list of tasks to complete an objective. Your next response must be formatted as a numbered list of plain text entries. Do not include anything but the numbered list. The list must be prioritized in the order that tasks must be completed.
The objective that you must make a numbered task list for is: [{{objective}}].
The tasks created should take into account the character traits of {{char}}. These tasks may or may not involve {{user}} directly. Be sure to include the objective as the final task.
Given an example objective of 'Make me a four course dinner', here is an example output:
1. Determine what the courses will be
2. Find recipes for each course
3. Go shopping for supplies with {{user}}
4. Cook the food
5. Get {{user}} to set the table
6. Serve the food
7. Enjoy eating the meal with {{user}}
`,
"checkTaskCompleted": `Pause your roleplay. Determine if this task is completed: [{{task}}].
To do this, examine the most recent messages. Your response must only contain either true or false, nothing other words.
Example output:
true
`,
'currentTask':`Your current task is [{{task}}]. Balance existing roleplay with completing this task.`
"createTask": `Pause your roleplay. Please generate a numbered list of plain text tasks to complete an objective. The objective that you must make a numbered task list for is: "{{objective}}". The tasks created should take into account the character traits of {{char}}. These tasks may or may not involve {{user}} directly. Include the objective as the final task.`,
"checkTaskCompleted": `Pause your roleplay. Determine if this task is completed: [{{task}}]. To do this, examine the most recent messages. Your response must only contain either true or false, and nothing else. Example output: true`,
'currentTask':`Your current task is [{{task}}]. Balance existing roleplay with completing this task.`,
}
let objectivePrompts = defaultPrompts
@ -824,5 +807,5 @@ jQuery(() => {
$('#objective-counter').text(checkCounter)
});
registerSlashCommand('taskcheck', checkTaskCompleted, [], ' checks if the current task is completed', true, true);
registerSlashCommand('taskcheck', checkTaskCompleted, [], ' checks if the current task is completed', true, true);
});

View File

@ -345,16 +345,16 @@ jQuery(async () => {
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">
<div class="flex-container ">
<label class="checkbox_label marginBot10 wide100p flexnowrap">
<div>
<label class="checkbox_label">
<input id="quickReplyEnabled" type="checkbox" />
Enable Quick Replies
</label>
<label class="checkbox_label marginBot10 wide100p flexnowrap">
<label class="checkbox_label">
<input id="quickActionEnabled" type="checkbox" />
Disable Send / Insert In User Input
</label>
<label class="checkbox_label marginBot10 wide100p flexnowrap">
<label class="checkbox_label marginBot10">
<input id="placeBeforePromptEnabled" type="checkbox" />
Place Quick-reply before the Prompt
</label>
@ -401,7 +401,7 @@ jQuery(async () => {
});
$(document).ready(() => {
registerSlashCommand('qr', doQR, [], "- requires number argument, activates the specified QuickReply", true, true);
registerSlashCommand('qrset', doQRPresetSwitch, [], "- arg: QuickReply Preset Name, swaps to that QR preset", true, true);
registerSlashCommand('qr', doQR, [], '<span class="monospace">(number)</span> activates the specified Quick Reply', true, true);
registerSlashCommand('qrset', doQRPresetSwitch, [], '<span class="monospace">(name)</span> swaps to the specified Quick Reply Preset', true, true);
})

View File

@ -35,6 +35,7 @@ const sources = {
horde: 'horde',
auto: 'auto',
novel: 'novel',
vlad: 'vlad',
}
const generationMode = {
@ -165,6 +166,9 @@ const defaultSettings = {
auto_url: 'http://localhost:7860',
auto_auth: '',
vlad_url: 'http://localhost:7860',
vlad_auth: '',
hr_upscaler: 'Latent',
hr_scale: 2.0,
hr_scale_min: 1.0,
@ -187,12 +191,21 @@ const defaultSettings = {
novel_anlas_guard: false,
}
const getAutoRequestBody = () => ({ url: extension_settings.sd.auto_url, auth: extension_settings.sd.auto_auth });
function getSdRequestBody() {
switch (extension_settings.sd.source) {
case sources.vlad:
return { url: extension_settings.sd.vlad_url, auth: extension_settings.sd.vlad_auth };
case sources.auto:
return { url: extension_settings.sd.auto_url, auth: extension_settings.sd.auto_auth };
default:
throw new Error('Invalid SD source.');
}
}
function toggleSourceControls() {
$('.sd_settings [data-sd-source]').each(function () {
const source = $(this).data('sd-source');
$(this).toggle(source === extension_settings.sd.source);
const source = $(this).data('sd-source').split(',');
$(this).toggle(source.includes(extension_settings.sd.source));
});
}
@ -244,6 +257,8 @@ async function loadSettings() {
$('#sd_refine_mode').prop('checked', extension_settings.sd.refine_mode);
$('#sd_auto_url').val(extension_settings.sd.auto_url);
$('#sd_auto_auth').val(extension_settings.sd.auto_auth);
$('#sd_vlad_url').val(extension_settings.sd.vlad_url);
$('#sd_vlad_auth').val(extension_settings.sd.vlad_auth);
toggleSourceControls();
addPromptTemplates();
@ -285,7 +300,7 @@ function addPromptTemplates() {
async function refinePrompt(prompt) {
if (extension_settings.sd.refine_mode) {
const refinedPrompt = await callPopup('<h3>Review and edit the prompt:</h3>Press "Cancel" to abort the image generation.', 'input', prompt, { rows: 5, okButton: 'Generate' });
const refinedPrompt = await callPopup('<h3>Review and edit the prompt:</h3>Press "Cancel" to abort the image generation.', 'input', prompt.trim(), { rows: 5, okButton: 'Generate' });
if (refinedPrompt) {
return refinedPrompt;
@ -316,7 +331,7 @@ function onCharacterPromptInput() {
}
function getCharacterPrefix() {
if (selected_group) {
if (!this_chid || selected_group) {
return '';
}
@ -454,6 +469,16 @@ function onAutoAuthInput() {
saveSettingsDebounced();
}
function onVladUrlInput() {
extension_settings.sd.vlad_url = $('#sd_vlad_url').val();
saveSettingsDebounced();
}
function onVladAuthInput() {
extension_settings.sd.vlad_auth = $('#sd_vlad_auth').val();
saveSettingsDebounced();
}
function onHrUpscalerChange() {
extension_settings.sd.hr_upscaler = $('#sd_hr_upscaler').find(':selected').val();
saveSettingsDebounced();
@ -486,7 +511,7 @@ async function validateAutoUrl() {
const result = await fetch('/api/sd/ping', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getAutoRequestBody()),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
@ -501,6 +526,30 @@ async function validateAutoUrl() {
}
}
async function validateVladUrl() {
try {
if (!extension_settings.sd.vlad_url) {
throw new Error('URL is not set.');
}
const result = await fetch('/api/sd/ping', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
throw new Error('SD.Next returned an error.');
}
await loadSamplers();
await loadModels();
toastr.success('SD.Next API connected.');
} catch (error) {
toastr.error(`Could not validate SD.Next API: ${error.message}`);
}
}
async function onModelChange() {
extension_settings.sd.model = $('#sd_model').find(':selected').val();
saveSettingsDebounced();
@ -515,7 +564,7 @@ async function onModelChange() {
if (extension_settings.sd.source === sources.extras) {
await updateExtrasRemoteModel();
}
if (extension_settings.sd.source === sources.auto) {
if (extension_settings.sd.source === sources.auto || extension_settings.sd.source === sources.vlad) {
await updateAutoRemoteModel();
}
toastr.success('Model successfully loaded!', 'Stable Diffusion');
@ -526,7 +575,7 @@ async function getAutoRemoteModel() {
const result = await fetch('/api/sd/get-model', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getAutoRequestBody()),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
@ -546,7 +595,7 @@ async function getAutoRemoteUpscalers() {
const result = await fetch('/api/sd/upscalers', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getAutoRequestBody()),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
@ -561,12 +610,32 @@ async function getAutoRemoteUpscalers() {
}
}
async function getVladRemoteUpscalers() {
try {
const result = await fetch('/api/sd-next/upscalers', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
throw new Error('SD.Next returned an error.');
}
const data = await result.json();
return data;
} catch (error) {
console.error(error);
return [extension_settings.sd.hr_upscaler];
}
}
async function updateAutoRemoteModel() {
try {
const result = await fetch('/api/sd/set-model', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ ...getAutoRequestBody(), model: extension_settings.sd.model }),
body: JSON.stringify({ ...getSdRequestBody(), model: extension_settings.sd.model }),
});
if (!result.ok) {
@ -610,6 +679,9 @@ async function loadSamplers() {
case sources.novel:
samplers = await loadNovelSamplers();
break;
case sources.vlad:
samplers = await loadVladSamplers();
break;
}
for (const sampler of samplers) {
@ -661,7 +733,7 @@ async function loadAutoSamplers() {
const result = await fetch('/api/sd/samplers', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getAutoRequestBody()),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
@ -675,6 +747,29 @@ async function loadAutoSamplers() {
}
}
async function loadVladSamplers() {
if (!extension_settings.sd.vlad_url) {
return [];
}
try {
const result = await fetch('/api/sd/samplers', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
throw new Error('SD.Next returned an error.');
}
const data = await result.json();
return data;
} catch (error) {
return [];
}
}
async function loadNovelSamplers() {
if (!secret_state[SECRET_KEYS.NOVEL]) {
console.debug('NovelAI API key is not set.');
@ -709,6 +804,9 @@ async function loadModels() {
case sources.novel:
models = await loadNovelModels();
break;
case sources.vlad:
models = await loadVladModels();
break;
}
for (const model of models) {
@ -778,7 +876,7 @@ async function loadAutoModels() {
const result = await fetch('/api/sd/models', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getAutoRequestBody()),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
@ -806,6 +904,49 @@ async function loadAutoModels() {
}
}
async function loadVladModels() {
if (!extension_settings.sd.vlad_url) {
return [];
}
try {
const currentModel = await getAutoRemoteModel();
if (currentModel) {
extension_settings.sd.model = currentModel;
}
const result = await fetch('/api/sd/models', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(getSdRequestBody()),
});
if (!result.ok) {
throw new Error('SD WebUI returned an error.');
}
const upscalers = await getVladRemoteUpscalers();
if (Array.isArray(upscalers) && upscalers.length > 0) {
$('#sd_hr_upscaler').empty();
for (const upscaler of upscalers) {
const option = document.createElement('option');
option.innerText = upscaler;
option.value = upscaler;
option.selected = upscaler === extension_settings.sd.hr_upscaler;
$('#sd_hr_upscaler').append(option);
}
}
const data = await result.json();
return data;
} catch (error) {
return [];
}
}
async function loadNovelModels() {
if (!secret_state[SECRET_KEYS.NOVEL]) {
console.debug('NovelAI API key is not set.');
@ -913,7 +1054,7 @@ async function generatePicture(_, trigger, message, callback) {
// if context.characterId is not null, then we get context.characters[context.characterId].avatar, else we get groupId and context.groups[groupId].id
// sadly, groups is not an array, but is a dict with keys being index numbers, so we have to filter it
const characterName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]].id.toString();
const characterName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString();
const prevSDHeight = extension_settings.sd.height;
const prevSDWidth = extension_settings.sd.width;
@ -988,7 +1129,7 @@ async function getPrompt(generationType, message, trigger, quiet_prompt) {
}
async function generatePrompt(quiet_prompt) {
const reply = await generateQuietPrompt(quiet_prompt);
const reply = await generateQuietPrompt(quiet_prompt, false);
return processReply(reply);
}
@ -1010,6 +1151,9 @@ async function sendGenerationRequest(generationType, prompt, characterName = nul
case sources.horde:
result = await generateHordeImage(prefixedPrompt);
break;
case sources.vlad:
result = await generateAutoImage(prefixedPrompt);
break;
case sources.auto:
result = await generateAutoImage(prefixedPrompt);
break;
@ -1121,7 +1265,7 @@ async function generateAutoImage(prompt) {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
...getAutoRequestBody(),
...getSdRequestBody(),
prompt: prompt,
negative_prompt: extension_settings.sd.negative_prompt,
sampler_name: extension_settings.sd.sampler,
@ -1325,6 +1469,8 @@ function isValidState() {
return true;
case sources.auto:
return !!extension_settings.sd.auto_url;
case sources.vlad:
return !!extension_settings.sd.vlad_url;
case sources.novel:
return secret_state[SECRET_KEYS.NOVEL];
}
@ -1357,7 +1503,7 @@ async function sdMessageButton(e) {
const message_id = $mes.attr('mesid');
const message = context.chat[message_id];
const characterName = message?.name || context.name2;
const characterFileName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]].id.toString();
const characterFileName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString();
const messageText = message?.mes;
const hasSavedImage = message?.extra?.image && message?.extra?.title;
@ -1445,6 +1591,9 @@ jQuery(async () => {
$('#sd_auto_validate').on('click', validateAutoUrl);
$('#sd_auto_url').on('input', onAutoUrlInput);
$('#sd_auto_auth').on('input', onAutoAuthInput);
$('#sd_vlad_validate').on('click', validateVladUrl);
$('#sd_vlad_url').on('input', onVladUrlInput);
$('#sd_vlad_auth').on('input', onVladAuthInput);
$('#sd_hr_upscaler').on('change', onHrUpscalerChange);
$('#sd_hr_scale').on('input', onHrScaleInput);
$('#sd_denoising_strength').on('input', onDenoisingStrengthInput);

View File

@ -17,6 +17,7 @@
<option value="extras">Extras API (local / remote)</option>
<option value="horde">Stable Horde</option>
<option value="auto">Stable Diffusion Web UI (AUTOMATIC1111)</option>
<option value="vlad">SD.Next (vladmandic)</option>
<option value="novel">NovelAI Diffusion</option>
</select>
<div data-sd-source="auto">
@ -34,6 +35,21 @@
<input id="sd_auto_auth" type="text" class="text_pole" placeholder="Example: username:password" value="" />
<i><b>Important:</b> run SD Web UI with the <tt>--api</tt> flag! The server must be accessible from the SillyTavern host machine.</i>
</div>
<div data-sd-source="vlad">
<label for="sd_vlad_url">SD.Next API URL</label>
<div class="flex-container flexnowrap">
<input id="sd_vlad_url" type="text" class="text_pole" placeholder="Example: {{vlad_url}}" value="{{vlad_url}}" />
<div id="sd_vlad_validate" class="menu_button menu_button_icon">
<i class="fa-solid fa-check"></i>
<span data-i18n="Connect">
Connect
</span>
</div>
</div>
<label for="sd_vlad_auth">Authentication (optional)</label>
<input id="sd_vlad_auth" type="text" class="text_pole" placeholder="Example: username:password" value="" />
<i>The server must be accessible from the SillyTavern host machine.</i>
</div>
<div data-sd-source="horde">
<i>Hint: Save an API key in Horde KoboldAI API settings to use it here.</i>
<label for="sd_horde_nsfw" class="checkbox_label">
@ -86,7 +102,7 @@
Hires. Fix
</label>
</div>
<div data-sd-source="auto">
<div data-sd-source="auto,vlad">
<label for="sd_hr_upscaler">Upscaler</label>
<select id="sd_hr_upscaler"></select>
<label for="sd_hr_scale">Upscale by (<span id="sd_hr_scale_value"></span>)</label>
@ -94,7 +110,7 @@
<label for="sd_denoising_strength">Denoising strength (<span id="sd_denoising_strength_value"></span>)</label>
<input id="sd_denoising_strength" type="range" min="{{denoising_strength_min}}" max="{{denoising_strength_max}}" step="{{denoising_strength_step}}" value="{{denoising_strength}}" />
<label for="sd_hr_second_pass_steps">Hires steps (2nd pass) (<span id="sd_hr_second_pass_steps_value"></span>)</label>
<input id="sd_hr_second_pass_steps" type="range" min="{{hr_second_pass_steps_min}}" max="{{hr_second_pass_steps_max}}" step="{{hr_second_pass_steps_max}}" value="{{hr_second_pass_steps}}" />
<input id="sd_hr_second_pass_steps" type="range" min="{{hr_second_pass_steps_min}}" max="{{hr_second_pass_steps_max}}" step="{{hr_second_pass_steps_step}}" value="{{hr_second_pass_steps}}" />
</div>
<div data-sd-source="novel">
<label for="sd_novel_upscale_ratio">Upscale by (<span id="sd_novel_upscale_ratio_value"></span>)</label>

View File

@ -292,6 +292,27 @@ async function translateProviderDeepLX(text, lang) {
throw new Error(response.statusText);
}
/**
* Translates text using the Bing API
* @param {string} text Text to translate
* @param {string} lang Target language code
* @returns {Promise<string>} Translated text
*/
async function translateProviderBing(text, lang) {
const response = await fetch('/api/translate/bing', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({ text: text, lang: lang }),
});
if (response.ok) {
const result = await response.text();
return result;
}
throw new Error(response.statusText);
}
/**
* Translates text using the selected translation provider
* @param {string} text Text to translate
@ -315,6 +336,8 @@ async function translate(text, lang) {
return await translateProviderDeepLX(text, lang);
case 'oneringtranslator':
return await translateProviderOneRing(text, lang);
case 'bing':
return await translateProviderBing(text, lang);
default:
console.error('Unknown translation provider', extension_settings.translate.provider);
return text;
@ -461,6 +484,7 @@ jQuery(() => {
<option value="google">Google</option>
<option value="deepl">DeepL</option>
<option value="deeplx">DeepLX</option>
<option value="bing">Bing</option>
<option value="oneringtranslator">OneRingTranslator</option>
<select>
<div id="translate_key_button" class="menu_button fa-solid fa-key margin0"></div>

View File

@ -1,6 +1,7 @@
import { eventSource, event_types, extension_prompt_types, getCurrentChatId, getRequestHeaders, is_send_press, saveSettingsDebounced, setExtensionPrompt, substituteParams } from "../../../script.js";
import { ModuleWorkerWrapper, extension_settings, getContext, renderExtensionTemplate } from "../../extensions.js";
import { collapseNewlines, power_user, ui_mode } from "../../power-user.js";
import { SECRET_KEYS, secret_state } from "../../secrets.js";
import { debounce, getStringHash as calculateHash, waitUntilCondition, onlyUnique } from "../../utils.js";
const MODULE_NAME = 'vectors';
@ -116,8 +117,9 @@ async function synchronizeChat(batchSize = 5) {
return newVectorItems.length - batchSize;
} catch (error) {
toastr.error('Check server console for more details', 'Vectorization failed');
console.error('Vectors: Failed to synchronize chat', error);
const message = error.cause === 'api_key_missing' ? 'API key missing. Save it in the "API Connections" panel.' : 'Check server console for more details';
toastr.error(message, 'Vectorization failed');
return -1;
} finally {
syncBlocked = false;
@ -287,6 +289,11 @@ async function getSavedHashes(collectionId) {
* @returns {Promise<void>}
*/
async function insertVectorItems(collectionId, items) {
if (settings.source === 'openai' && !secret_state[SECRET_KEYS.OPENAI] ||
settings.source === 'palm' && !secret_state[SECRET_KEYS.PALM]) {
throw new Error('Vectors: API key missing', { cause: 'api_key_missing' });
}
const response = await fetch('/api/vector/insert', {
method: 'POST',
headers: getRequestHeaders(),

View File

@ -15,6 +15,7 @@
<select id="vectors_source" class="select">
<option value="transformers">Local (Transformers)</option>
<option value="openai">OpenAI</option>
<option value="palm">Google MakerSuite (PaLM)</option>
</select>
<div id="vectors_advanced_settings" data-newbie-hidden>
<label for="vectors_template">
@ -34,7 +35,7 @@
</label>
<label>
<input type="radio" name="vectors_position" value="1" />
In-chat @ Depth <input id="vectors_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
In-chat @ Depth <input id="vectors_depth" class="text_pole widthUnset" type="number" min="0" max="999" />
</label>
</div>
<div class="flex-container">

View File

@ -9,6 +9,7 @@ import {
saveBase64AsFile,
PAGINATION_TEMPLATE,
waitUntilCondition,
getBase64Async,
} from './utils.js';
import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap, getMessageTimeStamp } from "./RossAscends-mods.js";
import { loadMovingUIState, sortEntitiesList } from './power-user.js';
@ -1146,36 +1147,29 @@ async function uploadGroupAvatar(event) {
return;
}
const e = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = resolve;
reader.onerror = reject;
reader.readAsDataURL(file);
});
const result = await getBase64Async(file);
$('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
const croppedImage = await callPopup(getCropPopup(e.target.result), 'avatarToCrop');
const croppedImage = await callPopup(getCropPopup(result), 'avatarToCrop');
if (!croppedImage) {
return;
}
let thumbnail = await createThumbnail(croppedImage, 96, 144);
let thumbnail = await createThumbnail(croppedImage, 200, 300);
//remove data:image/whatever;base64
thumbnail = thumbnail.replace(/^data:image\/[a-z]+;base64,/, "");
let _thisGroup = groups.find((x) => x.id == openGroupId);
// filename should be group id + human readable timestamp
const filename = `${_thisGroup.id}_${humanizedDateTime()}`;
let thumbnailUrl = await saveBase64AsFile(thumbnail, openGroupId.toString(), filename, 'jpg');
const filename = _thisGroup ? `${_thisGroup.id}_${humanizedDateTime()}` : humanizedDateTime();
let thumbnailUrl = await saveBase64AsFile(thumbnail, String(openGroupId ?? ''), filename, 'jpg');
if (!openGroupId) {
$('#group_avatar_preview img').attr('src', thumbnailUrl);
$('#rm_group_restore_avatar').show();
return;
}
_thisGroup.avatar_url = thumbnailUrl;
$("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
$("#rm_group_restore_avatar").show();

View File

@ -338,6 +338,26 @@ export function formatInstructModePrompt(name, isImpersonate, promptBias, name1,
return text.trimEnd() + (includeNames ? '' : separator);
}
/**
* Select context template matching instruct preset.
* @param {string} name Preset name.
*/
function selectMatchingContextTemplate(name) {
let foundMatch = false;
for (const context_preset of context_presets) {
// If context template matches the instruct preset
if (context_preset.name === name) {
foundMatch = true;
selectContextPreset(context_preset.name);
break;
}
}
if (!foundMatch) {
// If no match was found, select default context preset
selectContextPreset(power_user.default_context);
}
}
jQuery(() => {
$('#instruct_set_default').on('click', function () {
if (power_user.instruct.preset === power_user.default_instruct) {
@ -356,7 +376,7 @@ jQuery(() => {
$('#instruct_enabled').on('change', function () {
// When instruct mode gets enabled, select context template matching selected instruct preset
if (power_user.instruct.enabled) {
$('#instruct_presets').trigger('change');
selectMatchingContextTemplate(power_user.instruct.preset);
// When instruct mode gets disabled, select default context preset
} else {
selectContextPreset(power_user.default_context);
@ -364,7 +384,7 @@ jQuery(() => {
});
$('#instruct_presets').on('change', function () {
const name = $(this).find(':selected').val();
const name = String($(this).find(':selected').val());
const preset = instruct_presets.find(x => x.name === name);
if (!preset) {
@ -386,19 +406,7 @@ jQuery(() => {
});
// Select matching context template
let foundMatch = false;
for (const context_preset of context_presets) {
// If context template matches the instruct preset
if (context_preset.name === name) {
foundMatch = true;
selectContextPreset(context_preset.name);
break;
}
}
if (!foundMatch) {
// If no match was found, select default context preset
selectContextPreset(power_user.default_context);
}
selectMatchingContextTemplate(name);
highlightDefaultPreset();
});

View File

@ -2,6 +2,7 @@ import {
getRequestHeaders,
saveSettingsDebounced,
getStoppingStrings,
substituteParams,
} from "../script.js";
import {
@ -25,7 +26,7 @@ export const kai_settings = {
mirostat: 0,
mirostat_tau: 5.0,
mirostat_eta: 0.1,
use_default_badwordsids: true,
use_default_badwordsids: false,
grammar: "",
};
@ -123,7 +124,7 @@ export function getKoboldGenerationData(finalPrompt, this_settings, this_amount_
mirostat_tau: kai_flags.can_use_mirostat ? kai_settings.mirostat_tau : undefined,
mirostat_eta: kai_flags.can_use_mirostat ? kai_settings.mirostat_eta : undefined,
use_default_badwordsids: kai_flags.can_use_default_badwordsids ? kai_settings.use_default_badwordsids : undefined,
grammar: kai_flags.can_use_grammar ? kai_settings.grammar : undefined,
grammar: kai_flags.can_use_grammar ? substituteParams(kai_settings.grammar) : undefined,
};
return generate_data;
}

View File

@ -24,6 +24,7 @@ import {
eventSource,
event_types,
substituteParams,
MAX_INJECTION_DEPTH,
} from "../script.js";
import { groups, selected_group } from "./group-chats.js";
@ -45,7 +46,6 @@ import {
} from "./secrets.js";
import {
deepClone,
delay,
download,
getFileText, getSortableDelay,
@ -161,6 +161,7 @@ export const chat_completion_sources = {
SCALE: 'scale',
OPENROUTER: 'openrouter',
AI21: 'ai21',
PALM: 'palm',
};
const prefixMap = selected_group ? {
@ -322,7 +323,7 @@ function setOpenAIMessages(chat) {
}
// Add chat injections, 100 = maximum depth of injection. (Why would you ever need more?)
for (let i = 100; i >= 0; i--) {
for (let i = MAX_INJECTION_DEPTH; i >= 0; i--) {
const anchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, i);
if (anchor && anchor.length) {
@ -381,7 +382,7 @@ function setupChatCompletionPromptManager(openAiSettings) {
promptManager.tryGenerate = () => {
if (characters[this_chid]) {
return Generate('normal', {}, true);
} else{
} else {
return Promise.resolve();
}
}
@ -488,7 +489,7 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
// Reserve budget for group nudge
let groupNudgeMessage = null;
if (selected_group) {
const groupNudgeMessage = Message.fromPrompt(prompts.get('groupNudge'));
groupNudgeMessage = Message.fromPrompt(prompts.get('groupNudge'));
chatCompletion.reserveBudget(groupNudgeMessage);
}
@ -671,7 +672,7 @@ function populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, ty
// Authors Note
if (prompts.has('authorsNote')) {
const authorsNote = prompts.get('authorsNote') ;
const authorsNote = prompts.get('authorsNote');
if (authorsNote.position) {
chatCompletion.insert(Message.fromPrompt(authorsNote), 'main', authorsNote.position);
@ -726,7 +727,7 @@ function populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, ty
* @param {string} personaDescription
* @returns {Object} prompts - The prepared and merged system and user-defined prompts.
*/
function preparePromptsForChatCompletion({Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride, personaDescription} = {}) {
function preparePromptsForChatCompletion({ Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride, personaDescription } = {}) {
const scenarioText = Scenario ? `[Circumstances and context of the dialogue: ${Scenario}]` : '';
const charPersonalityText = charPersonality ? `[${name2}'s personality: ${charPersonality}]` : ''
const groupNudge = `[Write the next reply only as ${name2}]`;
@ -882,7 +883,8 @@ function prepareOpenAIMessages({
extensionPrompts,
systemPromptOverride,
jailbreakPromptOverride,
personaDescription});
personaDescription
});
// Fill the chat completion with as much context as the budget allows
populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, type, cyclePrompt });
@ -1055,6 +1057,8 @@ function getChatCompletionModel() {
return oai_settings.windowai_model;
case chat_completion_sources.SCALE:
return '';
case chat_completion_sources.PALM:
return '';
case chat_completion_sources.OPENROUTER:
return oai_settings.openrouter_model !== openrouter_website_model ? oai_settings.openrouter_model : null;
case chat_completion_sources.AI21:
@ -1182,16 +1186,18 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER;
const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE;
const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21;
const isPalm = oai_settings.chat_completion_source == chat_completion_sources.PALM;
const isTextCompletion = oai_settings.chat_completion_source == chat_completion_sources.OPENAI && textCompletionModels.includes(oai_settings.openai_model);
const isQuiet = type === 'quiet';
const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21;
const isImpersonate = type === 'impersonate';
const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21 && !isPalm;
if (isAI21) {
if (isAI21 || isPalm) {
const joinedMsgs = openai_msgs_tosend.reduce((acc, obj) => {
const prefix = prefixMap[obj.role];
return acc + (prefix ? (selected_group ? "\n" : prefix + " ") : "") + obj.content + "\n";
}, "");
openai_msgs_tosend = substituteParams(joinedMsgs);
openai_msgs_tosend = substituteParams(joinedMsgs) + (isImpersonate ? `${name1}:` : `${name2}:`);
}
// If we're using the window.ai extension, use that instead
@ -1256,6 +1262,14 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
generate_data['api_url_scale'] = oai_settings.api_url_scale;
}
if (isPalm) {
const nameStopString = isImpersonate ? `\n${name2}:` : `\n${name1}:`;
const stopStringsLimit = 3; // 5 - 2 (nameStopString and new_chat_prompt)
generate_data['use_palm'] = true;
generate_data['top_k'] = Number(oai_settings.top_k_openai);
generate_data['stop'] = [nameStopString, oai_settings.new_chat_prompt, ...getCustomStoppingStrings(stopStringsLimit)];
}
if (isAI21) {
generate_data['use_ai21'] = true;
generate_data['top_k'] = Number(oai_settings.top_k_openai);
@ -2052,7 +2066,8 @@ async function getStatusOpen() {
return resultCheckStatusOpen();
}
if (oai_settings.chat_completion_source == chat_completion_sources.SCALE || oai_settings.chat_completion_source == chat_completion_sources.CLAUDE || oai_settings.chat_completion_source == chat_completion_sources.AI21) {
const noValidateSources = [chat_completion_sources.SCALE, chat_completion_sources.CLAUDE, chat_completion_sources.AI21, chat_completion_sources.PALM];
if (noValidateSources.includes(oai_settings.chat_completion_source)) {
let status = 'Unable to verify key; press "Test Message" to validate.';
setOnlineStatus(status);
return resultCheckStatusOpen();
@ -2382,7 +2397,7 @@ async function onExportPresetClick() {
return;
}
const preset = deepClone(openai_settings[openai_setting_names[oai_settings.preset_settings_openai]]);
const preset = structuredClone(openai_settings[openai_setting_names[oai_settings.preset_settings_openai]]);
delete preset.reverse_proxy;
delete preset.proxy_password;
@ -2676,6 +2691,17 @@ async function onModelChange() {
$('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
}
if (oai_settings.chat_completion_source == chat_completion_sources.PALM) {
if (oai_settings.max_context_unlocked) {
$('#openai_max_context').attr('max', unlocked_max);
} else {
$('#openai_max_context').attr('max', palm2_max);
}
oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context);
$('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
}
if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) {
if (oai_settings.max_context_unlocked) {
$('#openai_max_context').attr('max', unlocked_max);
@ -2856,7 +2882,19 @@ async function onConnectButtonClick(e) {
console.log("No cookie set for Scale");
return;
}
}
if (oai_settings.chat_completion_source == chat_completion_sources.PALM) {
const api_key_palm = String($('#api_key_palm').val()).trim();
if (api_key_palm.length) {
await writeSecret(SECRET_KEYS.PALM, api_key_palm);
}
if (!secret_state[SECRET_KEYS.PALM]) {
console.log('No secret key saved for PALM');
return;
}
}
if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) {
@ -2924,6 +2962,9 @@ function toggleChatCompletionForms() {
else if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) {
$('#model_scale_select').trigger('change');
}
else if (oai_settings.chat_completion_source == chat_completion_sources.PALM) {
$('#model_palm_select').trigger('change');
}
else if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) {
$('#model_openrouter_select').trigger('change');
}
@ -3226,6 +3267,7 @@ $(document).ready(async function () {
$("#model_claude_select").on("change", onModelChange);
$("#model_windowai_select").on("change", onModelChange);
$("#model_scale_select").on("change", onModelChange);
$("#model_palm_select").on("change", onModelChange);
$("#model_openrouter_select").on("change", onModelChange);
$("#model_ai21_select").on("change", onModelChange);
$("#settings_perset_openai").on("change", onSettingsPresetChange);

View File

@ -408,7 +408,10 @@ function switchUiMode() {
if (power_user.fast_ui_mode) {
$("#blur-strength-block").css('opacity', '0.2')
$("#blur_strength").prop('disabled', true)
} else { $("#blur-strength-block").css('opacity', '1') }
} else {
$("#blur-strength-block").css('opacity', '1')
$("#blur_strength").prop('disabled', false)
}
}
function toggleWaifu() {
@ -467,7 +470,10 @@ function noShadows() {
if (power_user.noShadows) {
$("#shadow-width-block").css('opacity', '0.2')
$("#shadow_width").prop('disabled', true)
} else { $("#shadow-width-block").css('opacity', '1') }
} else {
$("#shadow-width-block").css('opacity', '1')
$("#shadow_width").prop('disabled', false)
}
scrollChatToBottom();
}
@ -520,8 +526,12 @@ function applyChatWidth(type) {
//document.documentElement.style.setProperty('--sheldWidth', power_user.chat_width);
} else {
//this is to prevent the slider from updating page in real time
$("#chat_width_slider").off('mouseup touchend').on('mouseup touchend', () => {
$("#chat_width_slider").off('mouseup touchend').on('mouseup touchend', async () => {
// This is a hack for Firefox to let it render before applying the block width.
// Otherwise it takes the incorrect slider position with the new value AFTER the resizing.
await delay(1);
document.documentElement.style.setProperty('--sheldWidth', `${power_user.chat_width}vw`);
await delay(1);
})
}
@ -2368,11 +2378,11 @@ $(document).ready(() => {
browser_has_focus = false;
});
registerSlashCommand('vn', toggleWaifu, [], ' swaps Visual Novel Mode On/Off', false, true);
registerSlashCommand('newchat', doNewChat, ['newchat'], ' start a new chat with current character', true, true);
registerSlashCommand('random', doRandomChat, ['random'], ' start a new chat with a random character', true, true);
registerSlashCommand('vn', toggleWaifu, [], ' swaps Visual Novel Mode On/Off', false, true);
registerSlashCommand('newchat', doNewChat, [], ' start a new chat with current character', true, true);
registerSlashCommand('random', doRandomChat, [], ' start a new chat with a random character', true, true);
registerSlashCommand('delmode', doDelMode, ['del'], '<span class="monospace">(optional number)</span> enter message deletion mode, and auto-deletes N messages if numeric argument is provided', true, true);
registerSlashCommand('cut', doMesCut, [], ' <span class="monospace">(requred number)</span> cuts the specified message from the chat', true, true);
registerSlashCommand('resetpanels', doResetPanels, ['resetui'], ' resets UI panels to original state.', true, true);
registerSlashCommand('bgcol', setAvgBG, [], ' WIP test of auto-bg avg coloring', true, true);
registerSlashCommand('cut', doMesCut, [], '<span class="monospace">(number)</span> cuts the specified message from the chat', true, true);
registerSlashCommand('resetpanels', doResetPanels, ['resetui'], ' resets UI panels to original state.', true, true);
registerSlashCommand('bgcol', setAvgBG, [], ' WIP test of auto-bg avg coloring', true, true);
});

View File

@ -24,7 +24,7 @@ import {
textgenerationwebui_presets,
textgenerationwebui_settings,
} from "./textgen-settings.js";
import { deepClone, download, parseJsonFile, waitUntilCondition } from "./utils.js";
import { download, parseJsonFile, waitUntilCondition } from "./utils.js";
const presetManagers = {};
@ -236,11 +236,11 @@ class PresetManager {
case "textgenerationwebui":
return textgenerationwebui_settings;
case "context":
const context_preset = deepClone(power_user.context);
const context_preset = structuredClone(power_user.context);
context_preset['name'] = name || power_user.context.preset;
return context_preset;
case "instruct":
const instruct_preset = deepClone(power_user.instruct);
const instruct_preset = structuredClone(power_user.instruct);
instruct_preset['name'] = name || power_user.instruct.preset;
return instruct_preset;
default:
@ -253,13 +253,13 @@ class PresetManager {
'preset',
'streaming_url',
'stopping_strings',
'use_stop_sequence',
'can_use_tokenization',
'can_use_streaming',
'preset_settings_novel',
'streaming_novel',
'nai_preamble',
'model_novel',
'streaming_kobold',
"enabled",
];
const settings = Object.assign({}, getSettingsByApiId(this.apiId));

View File

@ -3,6 +3,7 @@ import { callPopup, getRequestHeaders } from "../script.js";
export const SECRET_KEYS = {
HORDE: 'api_key_horde',
MANCER: 'api_key_mancer',
APHRODITE: 'api_key_aphrodite',
OPENAI: 'api_key_openai',
NOVEL: 'api_key_novel',
CLAUDE: 'api_key_claude',
@ -10,6 +11,7 @@ export const SECRET_KEYS = {
SCALE: 'api_key_scale',
AI21: 'api_key_ai21',
SCALE_COOKIE: 'scale_cookie',
PALM: 'api_key_palm',
}
const INPUT_MAP = {
@ -22,6 +24,8 @@ const INPUT_MAP = {
[SECRET_KEYS.SCALE]: '#api_key_scale',
[SECRET_KEYS.AI21]: '#api_key_ai21',
[SECRET_KEYS.SCALE_COOKIE]: '#scale_cookie',
[SECRET_KEYS.PALM]: '#api_key_palm',
[SECRET_KEYS.APHRODITE]: '#api_key_aphrodite',
}
async function clearSecret() {

View File

@ -57,7 +57,7 @@ class SlashCommandParser {
let stringBuilder = `<span class="monospace">/${command}</span> ${helpString} `;
if (Array.isArray(aliases) && aliases.length) {
let aliasesString = `(aliases: ${aliases.map(x => `<span class="monospace">/${x}</span>`).join(', ')})`;
let aliasesString = `(alias: ${aliases.map(x => `<span class="monospace">/${x}</span>`).join(', ')})`;
stringBuilder += aliasesString;
}
this.helpStrings.push(stringBuilder);
@ -118,8 +118,8 @@ parser.addCommand('name', setNameCallback, ['persona'], '<span class="monospace"
parser.addCommand('sync', syncCallback, [], ' syncs user name in user-attributed messages in the current chat', true, true);
parser.addCommand('lock', bindCallback, ['bind'], ' locks/unlocks a persona (name and avatar) to the current chat', true, true);
parser.addCommand('bg', setBackgroundCallback, ['background'], '<span class="monospace">(filename)</span> sets a background according to filename, partial names allowed, will set the first one alphabetically if multiple files begin with the provided argument string', false, true);
parser.addCommand('sendas', sendMessageAs, [], ` sends message as a specific character.<br>Example:<br><pre><code>/sendas Chloe\nHello, guys!</code></pre>will send "Hello, guys!" from "Chloe".<br>Uses character avatar if it exists in the characters list.`, true, true);
parser.addCommand('sys', sendNarratorMessage, [], '<span class="monospace">(text)</span> sends message as a system narrator', false, true);
parser.addCommand('sendas', sendMessageAs, [], ` sends message as a specific character. Uses character avatar if it exists in the characters list. Example that will send "Hello, guys!" from "Chloe": <pre><code>/sendas Chloe&#10;Hello, guys!</code></pre>`, true, true);
parser.addCommand('sys', sendNarratorMessage, ['nar'], '<span class="monospace">(text)</span> sends message as a system narrator', false, true);
parser.addCommand('sysname', setNarratorName, [], '<span class="monospace">(name)</span> sets a name for future system narrator messages in this chat (display only). Default: System. Leave empty to reset.', true, true);
parser.addCommand('comment', sendCommentMessage, [], '<span class="monospace">(text)</span> adds a note/comment message not part of the chat', false, true);
parser.addCommand('single', setStoryModeCallback, ['story'], ' sets the message style to single document mode without names or avatars visible', true, true);

View File

@ -5,6 +5,12 @@ System-wide Replacement Macros:
<li><tt>&lcub;&lcub;input&rcub;&rcub;</tt> - the user input</li>
<li><tt>&lcub;&lcub;time&rcub;&rcub;</tt> - the current time</li>
<li><tt>&lcub;&lcub;date&rcub;&rcub;</tt> - the current date</li>
<li><tt>&lcub;&lcub;weekday&rcub;&rcub;</tt> - the current weekday</li>
<li><tt>&lcub;&lcub;isotime&rcub;&rcub;</tt> - the current ISO date (YYYY-MM-DD)</li>
<li><tt>&lcub;&lcub;isodate&rcub;&rcub;</tt> - the current ISO time (24-hour clock)</li>
<li><tt>&lcub;&lcub;datetimeformat &hellip;&rcub;&rcub;</tt> - the current date/time in the specified format, e. g. for German date/time: <tt>&lcub;&lcub;datetimeformat DD.MM.YYYY HH:mm&rcub;&rcub;</tt></li>
<li><tt>&lcub;&lcub;bias "text here"&rcub;&rcub;</tt> - sets a behavioral bias for the AI until the next user input. Quotes around the text are important.</li>
<li><tt>&lcub;&lcub;banned "text here"&rcub;&rcub;</tt> - dynamically add text in the quotes to banned words sequences, if Text Generation WebUI backend used. Do nothing for others backends. Can be used anywhere (Character description, WI, AN, etc.) Quotes around the text are important.</li>
<li><tt>&lcub;&lcub;idle_duration&rcub;&rcub;</tt> - the time since the last user message was sent</li>
<li><tt>&lcub;&lcub;random:(args)&rcub;&rcub;</tt> - returns a random item from the list. (ex: &lcub;&lcub;random:1,2,3,4&rcub;&rcub; will return 1 of the 4 numbers at random. Works with text lists too.</li>
<li><tt>&lcub;&lcub;roll:(formula)&rcub;&rcub;</tt> - rolls a dice. (ex: &lcub;&lcub;roll:1d6&rcub;&rcub; will roll a 6-sided dice and return a number between 1 and 6)</li>

View File

@ -1,14 +1,18 @@
import {
api_server_textgenerationwebui,
getRequestHeaders,
getStoppingStrings,
max_context,
saveSettingsDebounced,
setGenerationParamsFromPreset,
} from "../script.js";
import { loadMancerModels } from "./mancer-settings.js";
import {
power_user,
} from "./power-user.js";
import { getTextTokens, tokenizers } from "./tokenizers.js";
import { delay, onlyUnique } from "./utils.js";
export {
textgenerationwebui_settings,
@ -17,6 +21,12 @@ export {
formatTextGenURL,
}
export const textgen_types = {
OOBA: 'ooba',
MANCER: 'mancer',
APHRODITE: 'aphrodite',
};
const textgenerationwebui_settings = {
temp: 0.7,
top_p: 0.5,
@ -50,8 +60,13 @@ const textgenerationwebui_settings = {
mirostat_eta: 0.1,
guidance_scale: 1,
negative_prompt: '',
grammar_string: '',
banned_tokens: '',
type: textgen_types.OOBA,
};
export let textgenerationwebui_banned_in_macros = [];
export let textgenerationwebui_presets = [];
export let textgenerationwebui_preset_names = [];
@ -85,6 +100,8 @@ const setting_names = [
"mirostat_eta",
"guidance_scale",
"negative_prompt",
"grammar_string",
"banned_tokens",
];
function selectPreset(name) {
@ -121,7 +138,57 @@ function formatTextGenURL(value, use_mancer) {
}
function convertPresets(presets) {
return Array.isArray(presets) ? presets.map(JSON.parse) : [];
return Array.isArray(presets) ? presets.map((p) => JSON.parse(p)) : [];
}
/**
* @returns {string} String with comma-separated banned token IDs
*/
function getCustomTokenBans() {
if (!textgenerationwebui_settings.banned_tokens && !textgenerationwebui_banned_in_macros.length) {
return '';
}
const result = [];
const sequences = textgenerationwebui_settings.banned_tokens
.split('\n')
.concat(textgenerationwebui_banned_in_macros)
.filter(x => x.length > 0)
.filter(onlyUnique);
//debug
if (textgenerationwebui_banned_in_macros.length) {
console.log("=== Found banned word sequences in the macros:", textgenerationwebui_banned_in_macros, "Resulting array of banned sequences (will be used this generation turn):", sequences);
}
//clean old temporary bans found in macros before, for the next generation turn.
textgenerationwebui_banned_in_macros = [];
for (const line of sequences) {
// Raw token ids, JSON serialized
if (line.startsWith('[') && line.endsWith(']')) {
try {
const tokens = JSON.parse(line);
if (Array.isArray(tokens) && tokens.every(t => Number.isInteger(t))) {
result.push(...tokens);
} else {
throw new Error('Not an array of integers');
}
} catch (err) {
console.log(`Failed to parse bad word token list: ${line}`, err);
}
} else {
try {
const tokens = getTextTokens(tokenizers.LLAMA, line);
result.push(...tokens);
} catch {
console.log(`Could not tokenize raw text: ${line}`);
}
}
}
return result.filter(onlyUnique).map(x => String(x)).join(',');
}
function loadTextGenSettings(data, settings) {
@ -129,6 +196,10 @@ function loadTextGenSettings(data, settings) {
textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? [];
Object.assign(textgenerationwebui_settings, settings.textgenerationwebui_settings ?? {});
if (settings.api_use_mancer_webui) {
textgenerationwebui_settings.type = textgen_types.MANCER;
}
for (const name of textgenerationwebui_preset_names) {
const option = document.createElement('option');
option.value = name;
@ -144,10 +215,52 @@ function loadTextGenSettings(data, settings) {
const value = textgenerationwebui_settings[i];
setSettingByName(i, value);
}
$('#textgen_type').val(textgenerationwebui_settings.type).trigger('change');
}
$(document).ready(function () {
$('#settings_preset_textgenerationwebui').on('change', function() {
export function isMancer() {
return textgenerationwebui_settings.type === textgen_types.MANCER;
}
export function isAphrodite() {
return textgenerationwebui_settings.type === textgen_types.APHRODITE;
}
export function getTextGenUrlSourceId() {
switch (textgenerationwebui_settings.type) {
case textgen_types.MANCER:
return "#mancer_api_url_text";
case textgen_types.OOBA:
return "#textgenerationwebui_api_url_text";
case textgen_types.APHRODITE:
return "#aphrodite_api_url_text";
}
}
jQuery(function () {
$('#textgen_type').on('change', function () {
const type = String($(this).val());
textgenerationwebui_settings.type = type;
$('[data-tg-type]').each(function () {
const tgType = $(this).attr('data-tg-type');
if (tgType == type) {
$(this).show();
} else {
$(this).hide();
}
});
if (isMancer()) {
loadMancerModels();
}
saveSettingsDebounced();
$('#api_button_textgenerationwebui').trigger('click');
});
$('#settings_preset_textgenerationwebui').on('change', function () {
const presetName = $(this).val();
selectPreset(presetName);
});
@ -204,11 +317,21 @@ function setSettingByName(i, value, trigger) {
}
async function generateTextGenWithStreaming(generate_data, signal) {
let streamingUrl = textgenerationwebui_settings.streaming_url;
if (isMancer()) {
streamingUrl = api_server_textgenerationwebui.replace("http", "ws") + "/v1/stream";
}
if (isAphrodite()) {
streamingUrl = api_server_textgenerationwebui;
}
const response = await fetch('/generate_textgenerationwebui', {
headers: {
...getRequestHeaders(),
'X-Response-Streaming': String(true),
'X-Streaming-URL': textgenerationwebui_settings.streaming_url,
'X-Streaming-URL': streamingUrl,
},
body: JSON.stringify(generate_data),
method: 'POST',
@ -222,13 +345,43 @@ async function generateTextGenWithStreaming(generate_data, signal) {
while (true) {
const { done, value } = await reader.read();
let response = decoder.decode(value);
getMessage += response;
if (done) {
return;
if (isAphrodite()) {
const events = response.split('\n\n');
for (const event of events) {
if (event.length == 0) {
continue;
}
try {
const { results } = JSON.parse(event);
if (Array.isArray(results) && results.length > 0) {
getMessage = results[0].text;
yield getMessage;
// unhang UI thread
await delay(1);
}
} catch {
// Ignore
}
}
if (done) {
return;
}
} else {
getMessage += response;
if (done) {
return;
}
yield getMessage;
}
yield getMessage;
}
}
}
@ -266,5 +419,7 @@ export function getTextGenGenerationData(finalPrompt, this_amount_gen, isImperso
'mirostat_mode': textgenerationwebui_settings.mirostat_mode,
'mirostat_tau': textgenerationwebui_settings.mirostat_tau,
'mirostat_eta': textgenerationwebui_settings.mirostat_eta,
'grammar_string': textgenerationwebui_settings.grammar_string,
'custom_token_bans': getCustomTokenBans(),
};
}

View File

@ -12,7 +12,7 @@ export const PAGINATION_TEMPLATE = '<%= rangeStart %>-<%= rangeEnd %> of <%= tot
* Navigation options for pagination.
* @enum {number}
*/
export const navigation_option = { none: 0, previous: 1, last: 2, };
export const navigation_option = { none: -2000, previous: -1000, };
export function escapeHtml(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
@ -988,12 +988,3 @@ export function uuidv4() {
return v.toString(16);
});
}
/**
* Clones an object using JSON serialization.
* @param {any} obj The object to clone.
* @returns {any} A deep clone of the object.
*/
export function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}

View File

@ -1,5 +1,5 @@
import { saveSettings, callPopup, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types } from "../script.js";
import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, deepClone, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option } from "./utils.js";
import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition } from "./utils.js";
import { getContext } from "./extensions.js";
import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from "./authors-note.js";
import { registerSlashCommand } from "./slash-commands.js";
@ -51,6 +51,11 @@ let updateEditor = (navigation) => { navigation; };
// Do not optimize. updateEditor is a function that is updated by the displayWorldEntries with new data.
const worldInfoFilter = new FilterHelper(() => updateEditor());
const SORT_ORDER_KEY = 'world_info_sort_order';
const InputWidthReference = $("#WIInputWidthReference");
const DEFAULT_DEPTH = 4;
export function getWorldInfoSettings() {
return {
@ -72,7 +77,6 @@ const world_info_position = {
ANTop: 2,
ANBottom: 3,
atDepth: 4,
};
const worldInfoCache = {};
@ -85,7 +89,12 @@ async function getWorldInfoPrompt(chat2, maxContext) {
worldInfoAfter = activatedWorldInfo.worldInfoAfter;
worldInfoString = worldInfoBefore + worldInfoAfter;
return { worldInfoString, worldInfoBefore, worldInfoAfter };
return {
worldInfoString,
worldInfoBefore,
worldInfoAfter,
worldInfoDepth: activatedWorldInfo.WIDepthEntries
};
}
function setWorldInfoSettings(settings, data) {
@ -155,6 +164,7 @@ function setWorldInfoSettings(settings, data) {
$("#world_editor_select").append(`<option value='${i}'>${item}</option>`);
});
$('#world_info_sort_order').val(localStorage.getItem(SORT_ORDER_KEY) || '0');
$("#world_editor_select").trigger("change");
}
@ -226,6 +236,67 @@ function getWIElement(name) {
return wiElement;
}
/**
* @param {any[]} data WI entries
* @returns {any[]} Sorted data
*/
function sortEntries(data) {
const option = $('#world_info_sort_order').find(":selected");
const sortField = option.data('field');
const sortOrder = option.data('order');
const sortRule = option.data('rule');
const orderSign = sortOrder === 'asc' ? 1 : -1;
if (sortRule === 'priority') {
// First constant, then normal, then disabled. Then sort by order
data.sort((a, b) => {
const aValue = a.constant ? 0 : a.disable ? 2 : 1;
const bValue = b.constant ? 0 : b.disable ? 2 : 1;
return (aValue - bValue || b.order - a.order);
});
} else {
const primarySort = (a, b) => {
const aValue = a[sortField];
const bValue = b[sortField];
// Sort strings
if (typeof aValue === 'string' && typeof bValue === 'string') {
if (sortRule === 'length') {
// Sort by string length
return orderSign * (aValue.length - bValue.length);
} else {
// Sort by A-Z ordinal
return orderSign * aValue.localeCompare(bValue);
}
}
// Sort numbers
return orderSign * (Number(aValue) - Number(bValue));
};
const secondarySort = (a, b) => a.order - b.order;
const tertiarySort = (a, b) => a.uid - b.uid;
data.sort((a, b) => {
const primary = primarySort(a, b);
if (primary !== 0) {
return primary;
}
const secondary = secondarySort(a, b);
if (secondary !== 0) {
return secondary;
}
return tertiarySort(a, b);
});
}
return data;
}
function nullWorldInfo() {
toastr.info("Create or import a new World Info file first.", "World Info is not set", { timeOut: 10000, preventDuplicates: true });
}
@ -255,8 +326,9 @@ function displayWorldEntries(name, data, navigation = navigation_option.none) {
// Sort the entries array by displayIndex and uid
entriesArray.sort((a, b) => a.displayIndex - b.displayIndex || a.uid - b.uid);
entriesArray = sortEntries(entriesArray);
entriesArray = worldInfoFilter.applyFilters(entriesArray);
callback(entriesArray);
typeof callback === 'function' && callback(entriesArray);
return entriesArray;
}
@ -267,9 +339,10 @@ function displayWorldEntries(name, data, navigation = navigation_option.none) {
}
const storageKey = 'WI_PerPage';
const perPageDefault = 25;
$("#world_info_pagination").pagination({
dataSource: getDataArray,
pageSize: Number(localStorage.getItem(storageKey)) || 25,
pageSize: Number(localStorage.getItem(storageKey)) || perPageDefault,
sizeChangerOptions: [10, 25, 50, 100],
showSizeChanger: true,
pageRange: 1,
@ -282,7 +355,30 @@ function displayWorldEntries(name, data, navigation = navigation_option.none) {
showNavigator: true,
callback: function (page) {
$("#world_popup_entries_list").empty();
const keywordHeaders = `
<div id="WIEntryHeaderTitlesPC" class="flex-container wide100p spaceBetween justifyCenter textAlignCenter" style="padding:0 2.5em;">
<small class="flex1">
Title/Memo
</small>
<small style="width:${InputWidthReference.width() + 5 + 'px'}">
Status
</small>
<small style="width:${InputWidthReference.width() + 20 + 'px'}">
Position
</small>
<small style="width:${InputWidthReference.width() + 15 + 'px'}">
Depth
</small>
<small style="width:${InputWidthReference.width() + 15 + 'px'}">
Order
</small>
<small style="width:${InputWidthReference.width() + 15 + 'px'}">
Trigger %
</small>
</div>`
const blocks = page.map(entry => getWorldEntry(name, data, entry));
$("#world_popup_entries_list").append(keywordHeaders);
$("#world_popup_entries_list").append(blocks);
},
afterSizeSelectorChange: function (e) {
@ -290,8 +386,28 @@ function displayWorldEntries(name, data, navigation = navigation_option.none) {
}
});
if (navigation === navigation_option.last) {
$("#world_info_pagination").pagination('go', $("#world_info_pagination").pagination('getTotalPage'));
if (typeof navigation === 'number' && Number(navigation) >= 0) {
const selector = `#world_popup_entries_list [uid="${navigation}"]`;
const data = getDataArray();
const uidIndex = data.findIndex(x => x.uid === navigation);
const perPage = Number(localStorage.getItem(storageKey)) || perPageDefault;
const page = Math.floor(uidIndex / perPage) + 1;
$("#world_info_pagination").pagination('go', page);
waitUntilCondition(() => document.querySelector(selector) !== null).finally(() => {
const element = $(selector);
if (element.length === 0) {
console.log(`Could not find element for uid ${navigation}`);
return;
}
const elementOffset = element.offset();
const parentOffset = element.parent().offset();
const scrollOffset = elementOffset.top - parentOffset.top;
$('#WorldInfo').scrollTop(scrollOffset);
element.addClass('flash animated');
setTimeout(() => element.removeClass('flash animated'), 2000);
});
}
$("#world_popup_new").off('click').on('click', () => {
@ -302,6 +418,23 @@ function displayWorldEntries(name, data, navigation = navigation_option.none) {
await renameWorldInfo(name, data);
});
$("#world_backfill_memos").off('click').on('click', async () => {
let counter = 0;
for (const entry of Object.values(data.entries)) {
if (!entry.comment && Array.isArray(entry.key) && entry.key.length > 0) {
entry.comment = entry.key[0];
setOriginalDataValue(data, entry.uid, "comment", entry.comment);
counter++;
}
}
if (counter > 0) {
toastr.info(`Backfilled ${counter} titles`);
await saveWorldInfo(name, data, true);
updateEditor(navigation_option.previous);
}
});
$("#world_popup_export").off('click').on('click', () => {
if (name && data) {
const jsonValue = JSON.stringify(data);
@ -407,6 +540,7 @@ function deleteOriginalDataValue(data, uid) {
function getWorldEntry(name, data, entry) {
const template = $("#entry_edit_template .world_entry").clone();
template.data("uid", entry.uid);
template.attr("uid", entry.uid);
// key
const keyInput = template.find('textarea[name="key"]');
@ -429,12 +563,16 @@ function getWorldEntry(name, data, entry) {
saveWorldInfo(name, data);
});
keyInput.val(entry.key.join(",")).trigger("input");
initScrollHeight(keyInput);
//initScrollHeight(keyInput);
// logic AND/NOT
const selectiveLogicDropdown = template.find('select[name="entryLogicType"]');
selectiveLogicDropdown.data("uid", entry.uid);
selectiveLogicDropdown.on("click", function (event) {
event.stopPropagation();
})
selectiveLogicDropdown.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
@ -449,6 +587,86 @@ function getWorldEntry(name, data, entry) {
.prop("selected", true)
.trigger("input");
// Character filter
const characterFilterLabel = template.find(`label[for="characterFilter"] > small`);
characterFilterLabel.text(!!(entry.characterFilter?.isExclude) ? "Exclude Character(s)" : "Filter to Character(s)");
// exclude characters checkbox
const characterExclusionInput = template.find(`input[name="character_exclusion"]`);
characterExclusionInput.data("uid", entry.uid);
characterExclusionInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).prop("checked");
characterFilterLabel.text(value ? "Exclude Character(s)" : "Filter to Character(s)");
if (data.entries[uid].characterFilter) {
if (!value && data.entries[uid].characterFilter.names.length === 0) {
delete data.entries[uid].characterFilter;
} else {
data.entries[uid].characterFilter.isExclude = value
}
} else if (value) {
Object.assign(
data.entries[uid],
{
characterFilter: {
isExclude: true,
names: []
}
}
);
}
setOriginalDataValue(data, uid, "character_filter", data.entries[uid].characterFilter);
saveWorldInfo(name, data);
});
characterExclusionInput.prop("checked", entry.characterFilter?.isExclude ?? false).trigger("input");
const characterFilter = template.find(`select[name="characterFilter"]`);
characterFilter.data("uid", entry.uid)
const deviceInfo = getDeviceInfo();
if (deviceInfo && deviceInfo.device.type === 'desktop') {
$(characterFilter).select2({
width: '100%',
placeholder: 'All characters will pull from this entry.',
allowClear: true,
closeOnSelect: false,
});
}
const characters = getContext().characters;
characters.forEach((character) => {
const option = document.createElement('option');
const name = character.avatar.replace(/\.[^/.]+$/, "") ?? character.name
option.innerText = name
option.selected = entry.characterFilter?.names.includes(name)
characterFilter.append(option)
});
characterFilter.on('mousedown change', async function (e) {
// If there's no world names, don't do anything
if (world_names.length === 0) {
e.preventDefault();
return;
}
const uid = $(this).data("uid");
const value = $(this).val();
if ((!value || value?.length === 0) && !data.entries[uid].characterFilter?.isExclude) {
delete data.entries[uid].characterFilter;
} else {
Object.assign(
data.entries[uid],
{
characterFilter: {
isExclude: data.entries[uid].characterFilter?.isExclude ?? false,
names: value
}
}
);
}
setOriginalDataValue(data, uid, "character_filter", data.entries[uid].characterFilter);
saveWorldInfo(name, data);
});
// keysecondary
const keySecondaryInput = template.find('textarea[name="keysecondary"]');
keySecondaryInput.data("uid", entry.uid);
@ -475,6 +693,7 @@ function getWorldEntry(name, data, entry) {
commentInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).val();
resetScrollHeight(this);
data.entries[uid].comment = value;
setOriginalDataValue(data, uid, "comment", data.entries[uid].comment);
@ -494,6 +713,7 @@ function getWorldEntry(name, data, entry) {
});
commentInput.val(entry.comment).trigger("input");
initScrollHeight(commentInput);
commentToggle.prop("checked", true /* entry.addMemo */).trigger("input");
commentToggle.parent().hide()
@ -566,6 +786,7 @@ function getWorldEntry(name, data, entry) {
// constant
/*
const constantInput = template.find('input[name="constant"]');
constantInput.data("uid", entry.uid);
constantInput.on("input", function () {
@ -576,6 +797,7 @@ function getWorldEntry(name, data, entry) {
saveWorldInfo(name, data);
});
constantInput.prop("checked", entry.constant).trigger("input");
*/
// order
const orderInput = template.find('input[name="order"]');
@ -585,16 +807,39 @@ function getWorldEntry(name, data, entry) {
const value = Number($(this).val());
data.entries[uid].order = !isNaN(value) ? value : 0;
updatePosOrdDisplay(uid)
setOriginalDataValue(data, uid, "insertion_order", data.entries[uid].order);
saveWorldInfo(name, data);
});
orderInput.val(entry.order).trigger("input");
orderInput.width(InputWidthReference.width() + 15 + 'px')
// probability
if (entry.probability === undefined) {
entry.probability = null;
}
// depth
const depthInput = template.find('input[name="depth"]');
depthInput.data("uid", entry.uid);
depthInput.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
data.entries[uid].depth = !isNaN(value) ? value : 0;
updatePosOrdDisplay(uid)
setOriginalDataValue(data, uid, "extensions.depth", data.entries[uid].depth);
saveWorldInfo(name, data);
});
depthInput.val(entry.depth ?? DEFAULT_DEPTH).trigger("input");
depthInput.width(InputWidthReference.width() + 15 + 'px');
// Hide by default unless depth is specified
if (entry.position === world_info_position.atDepth) {
//depthInput.parent().hide();
}
const probabilityInput = template.find('input[name="probability"]');
probabilityInput.data("uid", entry.uid);
probabilityInput.on("input", function () {
@ -616,6 +861,7 @@ function getWorldEntry(name, data, entry) {
saveWorldInfo(name, data);
});
probabilityInput.val(entry.probability).trigger("input");
probabilityInput.width(InputWidthReference.width() + 15 + 'px')
// probability toggle
if (entry.useProbability === undefined) {
@ -654,14 +900,26 @@ function getWorldEntry(name, data, entry) {
}
const positionInput = template.find('select[name="position"]');
initScrollHeight(positionInput);
positionInput.data("uid", entry.uid);
positionInput.on("click", function (event) {
// Prevent closing the drawer on clicking the input
event.stopPropagation();
});
positionInput.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
data.entries[uid].position = !isNaN(value) ? value : 0;
if (value === 4) {
template.find('label[for="order"').text('Depth:')
} else { template.find('label[for="order"').text('Order:') }
if (value === world_info_position.atDepth) {
depthInput.prop('disabled', false);
depthInput.css('visibility', 'visible')
//depthInput.parent().show();
} else {
depthInput.prop('disabled', true);
depthInput.css('visibility', 'hidden')
//depthInput.parent().hide();
}
updatePosOrdDisplay(uid)
// Spec v2 only supports before_char and after_char
setOriginalDataValue(data, uid, "position", data.entries[uid].position == 0 ? 'before_char' : 'after_char');
// Write the original value as extensions field
@ -674,10 +932,11 @@ function getWorldEntry(name, data, entry) {
.prop("selected", true)
.trigger("input");
// display uid
template.find(".world_entry_form_uid_value").text(entry.uid);
//add UID above content box (less important doesn't need to be always visible)
template.find(".world_entry_form_uid_value").text(`(UID: ${entry.uid})`);
// disable
/*
const disableInput = template.find('input[name="disable"]');
disableInput.data("uid", entry.uid);
disableInput.on("input", function () {
@ -688,7 +947,72 @@ function getWorldEntry(name, data, entry) {
saveWorldInfo(name, data);
});
disableInput.prop("checked", entry.disable).trigger("input");
*/
//new tri-state selector for constant/normal/disabled
const entryStateSelector = template.find('select[name="entryStateSelector"]');
entryStateSelector.data("uid", entry.uid);
console.log(entry.uid)
entryStateSelector.on("click", function (event) {
// Prevent closing the drawer on clicking the input
event.stopPropagation();
});
entryStateSelector.on("input", function () {
const uid = entry.uid;
const value = $(this).val();
switch (value) {
case "constant":
data.entries[uid].constant = true;
data.entries[uid].disable = false;
setOriginalDataValue(data, uid, "enabled", true);
setOriginalDataValue(data, uid, "constant", true);
template.removeClass('disabledWIEntry');
console.debug("set to constant")
break
case "normal":
data.entries[uid].constant = false;
data.entries[uid].disable = false;
setOriginalDataValue(data, uid, "enabled", true);
setOriginalDataValue(data, uid, "constant", false);
template.removeClass('disabledWIEntry');
console.debug("set to normal")
break
case "disabled":
data.entries[uid].constant = false;
data.entries[uid].disable = true;
setOriginalDataValue(data, uid, "enabled", false);
setOriginalDataValue(data, uid, "constant", false);
template.addClass('disabledWIEntry');
console.debug("set to disabled")
break
}
saveWorldInfo(name, data);
})
const entryState = function () {
console.log(`constant: ${entry.constant}, disabled: ${entry.disable}`)
if (entry.constant === true) {
console.debug('found constant')
return "constant"
} else if (entry.disable === true) {
console.debug('found disabled')
return "disabled"
} else {
console.debug('found normal')
return "normal"
}
}
template
.find(`select[name="entryStateSelector"] option[value=${entryState()}]`)
.prop("selected", true)
.trigger("input");
saveWorldInfo(name, data);
// exclude recursion
const excludeRecursionInput = template.find('input[name="exclude_recursion"]');
excludeRecursionInput.data("uid", entry.uid);
excludeRecursionInput.on("input", function () {
@ -701,7 +1025,7 @@ function getWorldEntry(name, data, entry) {
excludeRecursionInput.prop("checked", entry.excludeRecursion).trigger("input");
// delete button
const deleteButton = template.find("input.delete_entry_button");
const deleteButton = template.find(".delete_entry_button");
deleteButton.data("uid", entry.uid);
deleteButton.on("click", function () {
const uid = $(this).data("uid");
@ -713,6 +1037,30 @@ function getWorldEntry(name, data, entry) {
template.find('.inline-drawer-content').css('display', 'none'); //entries start collapsed
function updatePosOrdDisplay(uid) {
// display position/order info left of keyword box
let entry = data.entries[uid]
let posText = entry.position
switch (entry.position) {
case 0:
posText = '↑CD';
break
case 1:
posText = 'CD↓';
break
case 2:
posText = '↑AN';
break
case 3:
posText = 'AN↓';
break
case 4:
posText = `@D${entry.depth}`;
break
}
template.find(".world_entry_form_position_value").text(`(${posText} ${entry.order})`);
}
return template;
}
@ -755,7 +1103,7 @@ function createWorldInfoEntry(name, data) {
const newEntry = { uid: newUid, ...newEntryTemplate };
data.entries[newUid] = newEntry;
updateEditor(navigation_option.last);
updateEditor(newUid);
}
async function _save(name, data) {
@ -981,7 +1329,7 @@ async function getSortedEntries() {
console.debug(`Sorted ${entries.length} world lore entries using strategy ${world_info_character_strategy}`);
// Need to deep clone the entries to avoid modifying the cached data
return deepClone(entries);
return structuredClone(entries);
}
catch (e) {
console.error(e);
@ -1020,6 +1368,16 @@ async function checkWorldInfo(chat, maxContext) {
let activatedNow = new Set();
for (let entry of sortedEntries) {
// Check if this entry applies to the character or if it's excluded
if (entry.characterFilter && entry.characterFilter?.names.length > 0) {
const nameIncluded = entry.characterFilter.names.includes(getCharaFilename());
const filtered = entry.characterFilter.isExclude ? nameIncluded : !nameIncluded
if (filtered) {
continue;
}
}
if (failedProbabilityChecks.has(entry)) {
continue;
}
@ -1142,6 +1500,7 @@ async function checkWorldInfo(chat, maxContext) {
const WIAfterEntries = [];
const ANTopEntries = [];
const ANBottomEntries = [];
const WIDepthEntries = [];
// Appends from insertion order 999 to 1. Use unshift for this purpose
[...allActivatedEntries].sort(sortFn).forEach((entry) => {
@ -1159,12 +1518,15 @@ async function checkWorldInfo(chat, maxContext) {
ANBottomEntries.unshift(entry.content);
break;
case world_info_position.atDepth:
//inserted one by one, unrelated to any array of items
//must have a unique value for 'key' argument
//uses the order input to specify depth
var randomNumber = Math.floor(Math.random() * 99999) + 1;
context.setExtensionPrompt(`customDepthWI-${entry.keywords}-${entry.uid}-${randomNumber}`, entry.content, 1, entry.order);
break;
const existingDepthIndex = WIDepthEntries.findIndex((e) => e.depth === entry.depth ?? DEFAULT_DEPTH);
if (existingDepthIndex !== -1) {
WIDepthEntries[existingDepthIndex].entries.unshift(entry.content);
} else {
WIDepthEntries.push({
depth: entry.depth,
entries: [entry.content]
});
}
default:
break;
}
@ -1179,7 +1541,7 @@ async function checkWorldInfo(chat, maxContext) {
context.setExtensionPrompt(NOTE_MODULE_NAME, ANWithWI, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]);
}
return { worldInfoBefore, worldInfoAfter };
return { worldInfoBefore, worldInfoAfter, WIDepthEntries };
}
function matchKeys(haystack, needle) {
@ -1313,6 +1675,7 @@ function convertCharacterBook(characterBook) {
displayIndex: entry.extensions?.display_index ?? index,
probability: entry.extensions?.probability ?? null,
useProbability: entry.extensions?.useProbability ?? false,
depth: entry.extensions?.depth ?? DEFAULT_DEPTH,
};
});
@ -1348,12 +1711,19 @@ export function checkEmbeddedWorld(chid) {
const checkKey = `AlertWI_${characters[chid].avatar}`;
const worldName = characters[chid]?.data?.extensions?.world;
if (!localStorage.getItem(checkKey) && (!worldName || !world_names.includes(worldName))) {
toastr.info(
'To import and use it, select "Import Card Lore" in the "More..." dropdown menu on the character panel.',
`${characters[chid].name} has an embedded World/Lorebook`,
{ timeOut: 10000, extendedTimeOut: 20000, positionClass: 'toast-top-center' },
);
localStorage.setItem(checkKey, 1);
callPopup(`<h3>This character has an embedded World/Lorebook.</h3>
<h3>Would you like to import it now?</h3>
<div class="m-b-1">If you want to import it later, select "Import Card Lore" in the "More..." dropdown menu on the character panel.</div>`,
'confirm',
'',
{ okButton: 'Yes', })
.then((result) => {
if (result) {
importEmbeddedWorldInfo(true);
}
});
}
return true;
}
@ -1361,7 +1731,7 @@ export function checkEmbeddedWorld(chid) {
return false;
}
export async function importEmbeddedWorldInfo() {
export async function importEmbeddedWorldInfo(skipPopup = false) {
const chid = $('#import_character_info').data('chid');
if (chid === undefined) {
@ -1371,10 +1741,12 @@ export async function importEmbeddedWorldInfo() {
const bookName = characters[chid]?.data?.character_book?.name || `${characters[chid]?.name}'s Lorebook`;
const confirmationText = (`<h3>Are you sure you want to import "${bookName}"?</h3>`) + (world_names.includes(bookName) ? 'It will overwrite the World/Lorebook with the same name.' : '');
const confirmation = await callPopup(confirmationText, 'confirm');
if (!skipPopup) {
const confirmation = await callPopup(confirmationText, 'confirm');
if (!confirmation) {
return;
if (!confirmation) {
return;
}
}
const convertedBook = convertCharacterBook(characters[chid].data.character_book);
@ -1387,6 +1759,9 @@ export async function importEmbeddedWorldInfo() {
const newIndex = world_names.indexOf(bookName);
if (newIndex >= 0) {
//show&draw the WI panel before..
$("#WIDrawerIcon").trigger('click');
//..auto-opening the new imported WI
$("#world_editor_select").val(newIndex).trigger('change');
}
@ -1509,7 +1884,7 @@ export async function importWorldInfo(file) {
jQuery(() => {
$(document).ready(function () {
registerSlashCommand('world', onWorldInfoChange, [], " sets active World, or unsets if no args provided", true, true);
registerSlashCommand('world', onWorldInfoChange, [], '<span class="monospace">(optional name)</span> sets active World, or unsets if no args provided', true, true);
})
@ -1634,6 +2009,18 @@ jQuery(() => {
worldInfoFilter.setFilterData(FILTER_TYPES.WORLD_INFO_SEARCH, term);
});
$('#world_refresh').on('click', () => {
updateEditor(navigation_option.previous);
});
$('#world_info_sort_order').on('change', function (e) {
if (e.target instanceof HTMLOptionElement) {
localStorage.setItem(SORT_ORDER_KEY, e.target.value);
}
updateEditor(navigation_option.none);
})
// Not needed on mobile
const deviceInfo = getDeviceInfo();
if (deviceInfo && deviceInfo.device.type === 'desktop') {

View File

@ -255,12 +255,10 @@ table.responsiveTable {
.mes_text i,
.mes_text em {
color: var(--SmartThemeEmColor);
font-weight: 500;
}
.mes_text q {
color: var(--SmartThemeQuoteColor);
font-weight: 500;
}
.mes_text rp {
@ -2252,7 +2250,7 @@ input[type="range"] {
background-size: 70% 100%;
background-repeat: no-repeat;
box-shadow: inset 0 0 2px black;
cursor: grab;
cursor: ew-resize;
}
input[type="range"]::-webkit-slider-thumb {
@ -3623,4 +3621,4 @@ a {
height: 100vh;
z-index: 9999;
}
}
}

195
server.js
View File

@ -148,9 +148,14 @@ let color = {
white: (mess) => color.byNum(mess, 37)
};
function get_mancer_headers() {
const api_key_mancer = readSecret(SECRET_KEYS.MANCER);
return api_key_mancer ? { "X-API-KEY": api_key_mancer } : {};
function getMancerHeaders() {
const apiKey = readSecret(SECRET_KEYS.MANCER);
return apiKey ? { "X-API-KEY": apiKey } : {};
}
function getAphroditeHeaders() {
const apiKey = readSecret(SECRET_KEYS.APHRODITE);
return apiKey ? { "X-API-KEY": apiKey } : {};
}
function getOverrideHeaders(urlHost) {
@ -162,6 +167,26 @@ function getOverrideHeaders(urlHost) {
}
}
/**
* Sets additional headers for the request.
* @param {object} request Original request body
* @param {object} args New request arguments
* @param {string|null} server API server for new request
*/
function setAdditionalHeaders(request, args, server) {
let headers = {};
if (request.body.use_mancer) {
headers = getMancerHeaders();
} else if (request.body.use_aphrodite) {
headers = getAphroditeHeaders();
} else {
headers = server ? getOverrideHeaders((new URL(server))?.host) : '';
}
args.headers = Object.assign(args.headers, headers);
}
function humanizedISO8601DateTime(date) {
let baseDate = typeof date === 'number' ? new Date(date) : new Date();
let humanYear = baseDate.getFullYear();
@ -182,7 +207,7 @@ const AVATAR_WIDTH = 400;
const AVATAR_HEIGHT = 600;
const jsonParser = express.json({ limit: '100mb' });
const urlencodedParser = express.urlencoded({ extended: true, limit: '100mb' });
const { DIRECTORIES, UPLOADS_PATH } = require('./src/constants');
const { DIRECTORIES, UPLOADS_PATH, PALM_SAFETY } = require('./src/constants');
// CSRF Protection //
if (cliArguments.disableCsrf === false) {
@ -451,6 +476,52 @@ app.post("/generate", jsonParser, async function (request, response_generate) {
return response_generate.send({ error: true });
});
/**
* @param {string} streamingUrlString Streaming URL
* @param {import('express').Request} request Express request
* @param {import('express').Response} response Express response
* @param {AbortController} controller Abort controller
* @returns
*/
async function sendAphroditeStreamingRequest(streamingUrlString, request, response, controller) {
request.body['stream'] = true;
const args = {
method: 'POST',
body: JSON.stringify(request.body),
headers: { "Content-Type": "application/json" },
signal: controller.signal,
};
setAdditionalHeaders(request, args, streamingUrlString);
try {
const generateResponse = await fetch(streamingUrlString + "/v1/generate", args);
// Pipe remote SSE stream to Express response
generateResponse.body.pipe(response);
request.socket.on('close', function () {
if (generateResponse.body instanceof Readable) generateResponse.body.destroy(); // Close the remote stream
response.end(); // End the Express response
});
generateResponse.body.on('end', function () {
console.log("Streaming request finished");
response.end();
});
} catch (error) {
let value = { error: true, status: error.status, response: error.statusText };
console.log("Aphrodite endpoint error:", error);
if (!response.headersSent) {
return response.send(value);
} else {
return response.end();
}
}
}
//************** Text generation web UI
app.post("/generate_textgenerationwebui", jsonParser, async function (request, response_generate) {
if (!request.body) return response_generate.sendStatus(400);
@ -470,6 +541,10 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
if (streamingUrlHeader === undefined) return response_generate.sendStatus(400);
const streamingUrlString = streamingUrlHeader.replace("localhost", "127.0.0.1");
if (request.body.use_aphrodite) {
return sendAphroditeStreamingRequest(streamingUrlString, request, response_generate, controller);
}
response_generate.writeHead(200, {
'Content-Type': 'text/plain;charset=utf-8',
'Transfer-Encoding': 'chunked',
@ -482,9 +557,20 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
websocket.on('open', async function () {
console.log('WebSocket opened');
let headers = {};
if (request.body.use_mancer) {
headers = getMancerHeaders();
} else if (request.body.use_aphrodite) {
headers = getAphroditeHeaders();
} else {
headers = getOverrideHeaders(streamingUrl?.host);
}
const combined_args = Object.assign(
{},
request.body.use_mancer ? get_mancer_headers() : getOverrideHeaders(streamingUrl?.host),
headers,
request.body
);
console.log(combined_args);
@ -568,11 +654,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
signal: controller.signal,
};
if (request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
} else {
args.headers = Object.assign(args.headers, getOverrideHeaders((new URL(api_server))?.host));
}
setAdditionalHeaders(request, args, api_server);
try {
const data = await postAsync(api_server + "/v1/generate", args);
@ -677,11 +759,7 @@ app.post("/getstatus", jsonParser, async function (request, response) {
headers: { "Content-Type": "application/json" }
};
if (main_api == 'textgenerationwebui' && request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
} else {
args.headers = Object.assign(args.headers, getOverrideHeaders((new URL(api_server))?.host));
}
setAdditionalHeaders(request, args, api_server);
const url = api_server + "/v1/model";
let version = '';
@ -750,6 +828,8 @@ function convertToV2(char) {
fav: char.fav,
creator: char.creator,
tags: char.tags,
depth_prompt_prompt: char.depth_prompt_prompt,
depth_prompt_response: char.depth_prompt_response,
});
result.chat = char.chat ?? humanizedISO8601DateTime();
@ -865,6 +945,12 @@ function charaFormatData(data) {
_.set(char, 'data.extensions.talkativeness', data.talkativeness);
_.set(char, 'data.extensions.fav', data.fav == 'true');
_.set(char, 'data.extensions.world', data.world || '');
// Spec extension: depth prompt
const depth_default = 4;
const depth_value = !isNaN(Number(data.depth_prompt_depth)) ? Number(data.depth_prompt_depth) : depth_default;
_.set(char, 'data.extensions.depth_prompt.prompt', data.depth_prompt_prompt ?? '');
_.set(char, 'data.extensions.depth_prompt.depth', depth_value);
//_.set(char, 'data.extensions.create_date', humanizedISO8601DateTime());
//_.set(char, 'data.extensions.avatar', 'none');
//_.set(char, 'data.extensions.chat', data.ch_name + ' - ' + humanizedISO8601DateTime());
@ -1299,11 +1385,11 @@ app.post("/getstats", jsonParser, function (request, response) {
/**
* Endpoint: POST /recreatestats
*
*
* Triggers the recreation of statistics from chat files.
* - If successful: returns a 200 OK status.
* - On failure: returns a 500 Internal Server Error status.
*
*
* @param {Object} request - Express request object.
* @param {Object} response - Express response object.
*/
@ -1695,7 +1781,8 @@ function convertWorldInfoToCharacterBook(name, entries) {
display_index: entry.displayIndex,
probability: entry.probability ?? null,
useProbability: entry.useProbability ?? false,
}
depth: entry.depth ?? 4,
},
};
result.entries.push(originalEntry);
@ -2926,6 +3013,69 @@ async function sendClaudeRequest(request, response) {
}
}
/**
* @param {express.Request} request
* @param {express.Response} response
*/
async function sendPalmRequest(request, response) {
const api_key_palm = readSecret(SECRET_KEYS.PALM);
if (!api_key_palm) {
return response.status(401).send({ error: true });
}
const body = {
prompt: {
text: request.body.messages,
},
stopSequences: request.body.stop,
safetySettings: PALM_SAFETY,
temperature: request.body.temperature,
topP: request.body.top_p,
topK: request.body.top_k || undefined,
maxOutputTokens: request.body.max_tokens,
candidate_count: 1,
};
console.log('Palm request:', body);
try {
const controller = new AbortController();
request.socket.removeAllListeners('close');
request.socket.on('close', function () {
controller.abort();
});
const generateResponse = await fetch(`https://generativelanguage.googleapis.com/v1beta2/models/text-bison-001:generateText?key=${api_key_palm}`, {
body: JSON.stringify(body),
method: "POST",
headers: {
"Content-Type": "application/json"
},
signal: controller.signal,
timeout: 0,
});
if (!generateResponse.ok) {
console.log(`Palm API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`);
return response.status(generateResponse.status).send({ error: true });
}
const generateResponseJson = await generateResponse.json();
const responseText = generateResponseJson.candidates[0]?.output;
console.log('Palm response:', responseText);
// Wrap it back to OAI format
const reply = { choices: [{ "message": { "content": responseText, } }] };
return response.send(reply);
} catch (error) {
console.log('Error communicating with Palm API: ', error);
if (!response.headersSent) {
return response.status(500).send({ error: true });
}
}
}
app.post("/generate_openai", jsonParser, function (request, response_generate_openai) {
if (!request.body) return response_generate_openai.status(400).send({ error: true });
@ -2941,6 +3091,10 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
return sendAI21Request(request, response_generate_openai);
}
if (request.body.use_palm) {
return sendPalmRequest(request, response_generate_openai);
}
let api_url;
let api_key_openai;
let headers;
@ -3169,9 +3323,8 @@ app.post("/tokenize_via_api", jsonParser, async function (request, response) {
};
if (main_api == 'textgenerationwebui') {
if (request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
}
setAdditionalHeaders(request, args, null);
const data = await postAsync(api_server + "/v1/token-count", args);
return response.send({ count: data['results'][0]['tokens'] });
}

View File

@ -102,10 +102,42 @@ const UNSAFE_EXTENSIONS = [
".ws",
];
const PALM_SAFETY = [
{
category: "HARM_CATEGORY_UNSPECIFIED",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_DEROGATORY",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_TOXICITY",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_VIOLENCE",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_SEXUAL",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_MEDICAL",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_DANGEROUS",
threshold: "BLOCK_NONE"
}
];
const UPLOADS_PATH = './uploads';
module.exports = {
DIRECTORIES,
UNSAFE_EXTENSIONS,
UPLOADS_PATH,
PALM_SAFETY,
}

View File

@ -99,7 +99,7 @@ function registerEndpoints(app, jsonParser) {
const MAX_ATTEMPTS = 200;
const CHECK_INTERVAL = 3000;
const PROMPT_THRESHOLD = 1000;
const PROMPT_THRESHOLD = 5000;
try {
const maxLength = PROMPT_THRESHOLD - String(request.body.negative_prompt).length - 5;

43
src/palm-vectors.js Normal file
View File

@ -0,0 +1,43 @@
const fetch = require('node-fetch').default;
const { SECRET_KEYS, readSecret } = require('./secrets');
/**
* Gets the vector for the given text from PaLM gecko model
* @param {string} text - The text to get the vector for
* @returns {Promise<number[]>} - The vector for the text
*/
async function getPaLMVector(text) {
const key = readSecret(SECRET_KEYS.PALM);
if (!key) {
console.log('No PaLM key found');
throw new Error('No PaLM key found');
}
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta2/models/embedding-gecko-001:embedText?key=${key}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: text,
})
});
if (!response.ok) {
const text = await response.text();
console.log('PaLM request failed', response.statusText, text);
throw new Error('PaLM request failed');
}
const data = await response.json();
// Access the "value" dictionary
const vector = data.embedding.value;
return vector;
}
module.exports = {
getPaLMVector,
};

View File

@ -7,6 +7,7 @@ const SECRETS_FILE = path.join(process.cwd(), './secrets.json');
const SECRET_KEYS = {
HORDE: 'api_key_horde',
MANCER: 'api_key_mancer',
APHRODITE: 'api_key_aphrodite',
OPENAI: 'api_key_openai',
NOVEL: 'api_key_novel',
CLAUDE: 'api_key_claude',
@ -19,6 +20,7 @@ const SECRET_KEYS = {
SCALE_COOKIE: 'scale_cookie',
ONERING_URL: 'oneringtranslator_url',
DEEPLX_URL: 'deeplx_url',
PALM: 'api_key_palm',
}
/**

View File

@ -10,7 +10,7 @@ function registerEndpoints(app, jsonParser) {
app.post('/api/sd/ping', jsonParser, async (request, response) => {
try {
const url = new URL(request.body.url);
url.pathname = '/internal/ping';
url.pathname = '/sdapi/v1/options';
const result = await fetch(url, {
method: 'GET',
@ -243,6 +243,38 @@ function registerEndpoints(app, jsonParser) {
return response.sendStatus(500);
}
});
app.post('/api/sd-next/upscalers', jsonParser, async (request, response) => {
try {
const url = new URL(request.body.url);
url.pathname = '/sdapi/v1/upscalers';
const result = await fetch(url, {
method: 'GET',
headers: {
'Authorization': getBasicAuthHeader(request.body.auth),
},
});
if (!result.ok) {
throw new Error('SD WebUI returned an error.');
}
// Vlad doesn't provide Latent Upscalers in the API, so we have to hardcode them here
const latentUpscalers = ['Latent', 'Latent (antialiased)', 'Latent (bicubic)', 'Latent (bicubic antialiased)', 'Latent (nearest)', 'Latent (nearest-exact)'];
const data = await result.json();
const names = data.map(x => x.name);
// 0 = None, then Latent Upscalers, then Upscalers
names.splice(1, 0, ...latentUpscalers);
return response.send(names);
} catch (error) {
console.log(error);
return response.sendStatus(500);
}
});
}
module.exports = {

View File

@ -1,7 +1,6 @@
const fetch = require('node-fetch').default;
const https = require('https');
const { readSecret, SECRET_KEYS } = require('./secrets');
const { generateRequestUrl, normaliseResponse } = require('google-translate-api-browser');
const DEEPLX_URL_DEFAULT = 'http://127.0.0.1:1188/translate';
const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate';
@ -59,6 +58,7 @@ function registerEndpoints(app, jsonParser) {
});
app.post('/api/translate/google', jsonParser, async (request, response) => {
const { generateRequestUrl, normaliseResponse } = require('google-translate-api-browser');
const text = request.body.text;
const lang = request.body.lang;
@ -241,6 +241,30 @@ function registerEndpoints(app, jsonParser) {
return response.sendStatus(500);
}
});
app.post('/api/translate/bing', jsonParser, async (request, response) => {
const bingTranslateApi = require('bing-translate-api');
const text = request.body.text;
let lang = request.body.lang;
if (request.body.lang === 'zh-CN') {
lang = 'zh-Hans'
}
if (!text || !lang) {
return response.sendStatus(400);
}
console.log('Input text: ' + text);
bingTranslateApi.translate(text, null, lang).then(result => {
console.log('Translated text: ' + result.translation);
return response.send(result.translation);
}).catch(err => {
console.log("Translation error: " + err.message);
return response.sendStatus(500);
});
});
}
module.exports = {

View File

@ -15,6 +15,8 @@ async function getVector(source, text) {
return require('./openai-vectors').getOpenAIVector(text);
case 'transformers':
return require('./embedding').getTransformersVector(text);
case 'palm':
return require('./palm-vectors').getPaLMVector(text);
}
throw new Error(`Unknown vector source ${source}`);