diff --git a/.github/readme.md b/.github/readme.md index 36d387166..e40bc2d47 100644 --- a/.github/readme.md +++ b/.github/readme.md @@ -276,6 +276,46 @@ In order to enable viewing your keys by clicking a button in the API block: 1. Set the value of `allowKeysExposure` to `true` in `config.yaml` file. 2. Restart the SillyTavern server. +## Command-line arguments + +You can pass command-line arguments to SillyTavern server startup to override some settings in `config.yaml`. + +### Examples + +```shell +node server.js --port 8000 --listen false +# or +npm run start -- --port 8000 --listen false +# or (Windows only) +Start.bat --port 8000 --listen false +``` + +### Supported arguments + +| Option | Description | Type | Default | +|-------------------------|------------------------------------------------------------------------------------------------------|----------|------------------------------| +| `--version` | Show version number | boolean | | +| `--enableIPv6` | Enables IPv6. | boolean | false | +| `--enableIPv4` | Enables IPv4. | boolean | true | +| `--port` | Sets the port under which SillyTavern will run. If not provided falls back to yaml config 'port'. | number | 8000 | +| `--dnsPreferIPv6` | Prefers IPv6 for dns. If not provided falls back to yaml config 'preferIPv6'. | boolean | false | +| `--autorun` | Automatically launch SillyTavern in the browser. If not provided falls back to yaml config 'autorun'.| boolean | false | +| `--autorunHostname` | The autorun hostname, probably best left on 'auto'. | string | null | +| `--autorunPortOverride` | Overrides the port for autorun. | string | null | +| `--listen` | SillyTavern is listening on all network interfaces. If not provided falls back to yaml config 'listen'.| boolean | false | +| `--corsProxy` | Enables CORS proxy. If not provided falls back to yaml config 'enableCorsProxy'. | boolean | false | +| `--disableCsrf` | Disables CSRF protection | boolean | null | +| `--ssl` | Enables SSL | boolean | false | +| `--certPath` | Path to your certificate file. | string | "certs/cert.pem" | +| `--keyPath` | Path to your private key file. | string | "certs/privkey.pem" | +| `--whitelist` | Enables whitelist mode | boolean | null | +| `--dataRoot` | Root directory for data storage | string | null | +| `--avoidLocalhost` | Avoids using 'localhost' for autorun in auto mode. | boolean | null | +| `--basicAuthMode` | Enables basic authentication | boolean | null | +| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean | null | +| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string | null | +| `--requestProxyBypass` | Request proxy bypass list (space separated list of hosts) | array | null | + ## Remote connections Most often this is for people who want to use SillyTavern on their mobile phones while their PC runs the ST server on the same wifi network. diff --git a/default/config.yaml b/default/config.yaml index 58db04a49..5f3e0ce9a 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -37,6 +37,16 @@ basicAuthUser: password: "password" # Enables CORS proxy middleware enableCorsProxy: false +# -- REQUEST PROXY CONFIGURATION -- +requestProxy: + # If a proxy is enabled, all outgoing HTTP/HTTPS requests will be routed through it. + enabled: false + # Proxy URL. Possible protocols: http, https, socks, socks5, socks4, pac + url: "socks5://username:password@example.com:1080" + # Proxy bypass list. Requests to these hosts won't be routed through the proxy. + bypass: + - localhost + - 127.0.0.1 # Enable multi-user mode enableUserAccounts: false # Enable discreet login mode: hides user list on the login screen diff --git a/package-lock.json b/package-lock.json index 58e0034e6..ca83e8446 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "cookie-session": "^2.1.0", "cors": "^2.8.5", "csrf-csrf": "^2.2.3", - "express": "^4.19.2", + "express": "^4.20.0", "form-data": "^4.0.0", "google-translate-api-browser": "^3.0.1", "he": "^1.2.0", @@ -40,6 +40,7 @@ "png-chunk-text": "^1.0.0", "png-chunks-encode": "^1.0.0", "png-chunks-extract": "^1.0.0", + "proxy-agent": "^6.4.0", "rate-limiter-flexible": "^5.0.0", "response-time": "^2.3.2", "sanitize-filename": "^1.6.3", @@ -941,6 +942,12 @@ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "license": "MIT" }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -1080,6 +1087,41 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/agentkeepalive": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", @@ -1382,6 +1424,18 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", @@ -1445,6 +1499,15 @@ ], "license": "MIT" }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bing-translate-api": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/bing-translate-api/-/bing-translate-api-2.9.1.tgz", @@ -2250,6 +2313,15 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2316,6 +2388,20 @@ "node": ">=8" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2528,6 +2614,27 @@ "node": ">=0.8.0" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "8.57.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", @@ -2683,6 +2790,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -2713,7 +2833,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -2723,7 +2842,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -3071,6 +3189,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3130,6 +3262,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/get-uri/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/gifwrap": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", @@ -3369,6 +3539,42 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -3382,6 +3588,42 @@ "node": ">=10.19.0" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -3485,6 +3727,19 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/ip-matching": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ip-matching/-/ip-matching-2.1.2.tgz", @@ -3669,6 +3924,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3761,6 +4022,18 @@ "dev": true, "license": "MIT" }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/keygrip": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", @@ -4053,6 +4326,15 @@ "node": ">= 0.6" } }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -4323,6 +4605,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pac-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -4618,6 +4955,57 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -5006,36 +5394,6 @@ "node": ">= 0.8.0" } }, - "node_modules/serve-static/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/serve-static/node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5165,6 +5523,83 @@ "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==", "license": "MIT" }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -5378,6 +5813,12 @@ "utf8-byte-length": "^1.0.1" } }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, "node_modules/tsscmp": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", @@ -5437,6 +5878,15 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index 93c240873..87d7fa508 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "cookie-session": "^2.1.0", "cors": "^2.8.5", "csrf-csrf": "^2.2.3", - "express": "^4.19.2", + "express": "^4.20.0", "form-data": "^4.0.0", "google-translate-api-browser": "^3.0.1", "he": "^1.2.0", @@ -30,6 +30,7 @@ "png-chunk-text": "^1.0.0", "png-chunks-encode": "^1.0.0", "png-chunks-extract": "^1.0.0", + "proxy-agent": "^6.4.0", "rate-limiter-flexible": "^5.0.0", "response-time": "^2.3.2", "sanitize-filename": "^1.6.3", @@ -62,6 +63,9 @@ }, "node-fetch": { "whatwg-url": "^14.0.0" + }, + "express": { + "send": "^0.19.0" } }, "name": "sillytavern", diff --git a/public/index.html b/public/index.html index a3f89daec..939994e29 100644 --- a/public/index.html +++ b/public/index.html @@ -6479,8 +6479,8 @@ + - diff --git a/public/lib/object-hasown.js b/public/lib/object-hasown.js deleted file mode 100644 index 9b7792e88..000000000 --- a/public/lib/object-hasown.js +++ /dev/null @@ -1,4 +0,0 @@ -// Polyfill for old Safari versions -if (!Object.hasOwn) { - Object.hasOwn = function (obj, prop) { return obj.hasOwnProperty(prop); } -} diff --git a/public/lib/polyfill.js b/public/lib/polyfill.js new file mode 100644 index 000000000..cef73b4e5 --- /dev/null +++ b/public/lib/polyfill.js @@ -0,0 +1,19 @@ +// Polyfills for old Safari versions +if (!Object.hasOwn) { + Object.hasOwn = function (obj, prop) { return obj.hasOwnProperty(prop); } +} + +if (!Array.prototype.findLastIndex) { + Array.prototype.findLastIndex = function (callback, thisArg) { + for (let i = this.length - 1; i >= 0; i--) { + if (callback.call(thisArg, this[i], i, this)) return i; + } + return -1; + }; +} + +if (!Array.prototype.toSorted) { + Array.prototype.toSorted = function (compareFunction) { + return this.slice().sort(compareFunction); + }; +} diff --git a/public/script.js b/public/script.js index 9a4178bff..2f82f8d88 100644 --- a/public/script.js +++ b/public/script.js @@ -7472,7 +7472,7 @@ export function showSwipeButtons() { const currentMessage = $('#chat').children().filter(`[mesid="${chat.length - 1}"]`); const swipeId = chat[chat.length - 1].swipe_id; - var swipesCounterHTML = (`${(swipeId + 1)}/${(chat[chat.length - 1].swipes.length)}`); + const swipeCounterText = (`${(swipeId + 1)}\u200B/\u200b${(chat[chat.length - 1].swipes.length)}`); if (swipeId !== undefined && (chat[chat.length - 1].swipes.length > 1 || swipeId > 0)) { currentMessage.children('.swipe_left').css('display', 'flex'); @@ -7489,7 +7489,7 @@ export function showSwipeButtons() { } //console.log(swipesCounterHTML); - $('.swipes-counter').html(swipesCounterHTML); + $('.swipes-counter').text(swipeCounterText); //console.log(swipeId); //console.log(chat[chat.length - 1].swipes.length); @@ -7878,13 +7878,19 @@ async function createOrEditCharacter(e) { formData.set('avatar', convertedFile); } - if ($('#form_create').attr('actiontype') == 'createcharacter') { - if (String($('#character_name_pole').val()).length > 0) { - if (is_group_generating || is_send_press) { - toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted'); - throw new Error('Cannot import character while generating'); - } + const headers = getRequestHeaders(); + delete headers['Content-Type']; + if ($('#form_create').attr('actiontype') == 'createcharacter') { + if (String($('#character_name_pole').val()).length === 0) { + toastr.error('Name is required'); + return; + } + if (is_group_generating || is_send_press) { + toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted'); + return; + } + try { //if the character name text area isn't empty (only posible when creating a new character) let url = '/api/characters/create'; @@ -7899,142 +7905,133 @@ async function createOrEditCharacter(e) { formData.append('extensions', JSON.stringify(create_save.extensions)); - await jQuery.ajax({ - type: 'POST', - url: url, - data: formData, - beforeSend: function () { - $('#create_button').attr('disabled', String(true)); - $('#create_button').attr('value', '⏳'); - }, - cache: false, - contentType: false, - processData: false, - success: async function (html) { - $('#character_cross').trigger('click'); //closes the advanced character editing popup - const fields = [ - { id: '#character_name_pole', callback: value => create_save.name = value }, - { id: '#description_textarea', callback: value => create_save.description = value }, - { id: '#creator_notes_textarea', callback: value => create_save.creator_notes = value }, - { id: '#character_version_textarea', callback: value => create_save.character_version = value }, - { id: '#post_history_instructions_textarea', callback: value => create_save.post_history_instructions = value }, - { id: '#system_prompt_textarea', callback: value => create_save.system_prompt = value }, - { id: '#tags_textarea', callback: value => create_save.tags = value }, - { id: '#creator_textarea', callback: value => create_save.creator = value }, - { id: '#personality_textarea', callback: value => create_save.personality = value }, - { 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: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_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: [] }, - { id: '#character_world', callback: value => create_save.world = value }, - { id: '#_character_extensions_fake', callback: value => create_save.extensions = {} }, - ]; - - fields.forEach(field => { - const fieldValue = field.defaultValue !== undefined ? field.defaultValue : ''; - $(field.id).val(fieldValue); - field.callback && field.callback(fieldValue); - }); - - $('#character_popup-button-h3').text('Create character'); - - create_save.avatar = ''; - - $('#create_button').removeAttr('disabled'); - $('#add_avatar_button').replaceWith( - $('#add_avatar_button').val('').clone(true), - ); - - $('#create_button').attr('value', '✅'); - let oldSelectedChar = null; - if (this_chid !== undefined) { - oldSelectedChar = characters[this_chid].avatar; - } - - console.log(`new avatar id: ${html}`); - createTagMapFromList('#tagList', html); - await getCharacters(); - - select_rm_info('char_create', html, oldSelectedChar); - - crop_data = undefined; - }, - error: function (jqXHR, exception) { - $('#create_button').removeAttr('disabled'); - }, + const fetchResult = await fetch(url, { + method: 'POST', + headers: headers, + body: formData, + cache: 'no-cache', }); - } else { - toastr.error('Name is required'); + + if (!fetchResult.ok) { + throw new Error('Fetch result is not ok'); + } + + const avatarId = await fetchResult.text(); + + $('#character_cross').trigger('click'); //closes the advanced character editing popup + const fields = [ + { id: '#character_name_pole', callback: value => create_save.name = value }, + { id: '#description_textarea', callback: value => create_save.description = value }, + { id: '#creator_notes_textarea', callback: value => create_save.creator_notes = value }, + { id: '#character_version_textarea', callback: value => create_save.character_version = value }, + { id: '#post_history_instructions_textarea', callback: value => create_save.post_history_instructions = value }, + { id: '#system_prompt_textarea', callback: value => create_save.system_prompt = value }, + { id: '#tags_textarea', callback: value => create_save.tags = value }, + { id: '#creator_textarea', callback: value => create_save.creator = value }, + { id: '#personality_textarea', callback: value => create_save.personality = value }, + { 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: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_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: [] }, + { id: '#character_world', callback: value => create_save.world = value }, + { id: '#_character_extensions_fake', callback: value => create_save.extensions = {} }, + ]; + + fields.forEach(field => { + const fieldValue = field.defaultValue !== undefined ? field.defaultValue : ''; + $(field.id).val(fieldValue); + field.callback && field.callback(fieldValue); + }); + + $('#character_popup-button-h3').text('Create character'); + + create_save.avatar = ''; + + $('#add_avatar_button').replaceWith( + $('#add_avatar_button').val('').clone(true), + ); + + let oldSelectedChar = null; + if (this_chid !== undefined) { + oldSelectedChar = characters[this_chid].avatar; + } + + console.log(`new avatar id: ${avatarId}`); + createTagMapFromList('#tagList', avatarId); + await getCharacters(); + + select_rm_info('char_create', avatarId, oldSelectedChar); + + crop_data = undefined; + + } catch (error) { + console.error('Error creating character', error); + toastr.error('Failed to create character'); } } else { - let url = '/api/characters/edit'; + try { + let url = '/api/characters/edit'; - if (crop_data != undefined) { - url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`; - } - - formData.delete('alternate_greetings'); - const chid = $('.open_alternate_greetings').data('chid'); - if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) { - for (const value of characters[chid].data.alternate_greetings) { - formData.append('alternate_greetings', value); + if (crop_data != undefined) { + url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`; } - } - await jQuery.ajax({ - type: 'POST', - url: url, - data: formData, - beforeSend: function () { - $('#create_button').attr('disabled', String(true)); - $('#create_button').attr('value', 'Save'); - }, - cache: false, - contentType: false, - processData: false, - success: async function (html) { - $('#create_button').removeAttr('disabled'); - - await getOneCharacter(formData.get('avatar_url')); - favsToHotswap(); // Update fav state - - $('#add_avatar_button').replaceWith( - $('#add_avatar_button').val('').clone(true), - ); - $('#create_button').attr('value', 'Save'); - crop_data = undefined; - eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } }); - - // Recreate the chat if it hasn't been used at least once (i.e. with continue). - const message = getFirstMessage(); - const shouldRegenerateMessage = - !isNewChat && - message.mes && - !selected_group && - !chat_metadata['tainted'] && - (chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system)); - - if (shouldRegenerateMessage) { - chat.splice(0, chat.length, message); - const messageId = (chat.length - 1); - await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId); - await clearChat(); - await printMessages(); - await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId); - await saveChatConditional(); + formData.delete('alternate_greetings'); + const chid = $('.open_alternate_greetings').data('chid'); + if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) { + for (const value of characters[chid].data.alternate_greetings) { + formData.append('alternate_greetings', value); } - }, - error: function (jqXHR, exception) { - $('#create_button').removeAttr('disabled'); - console.log('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.'); - toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.'); - }, - }); + } + + const fetchResult = await fetch(url, { + method: 'POST', + headers: headers, + body: formData, + cache: 'no-cache', + }); + + if (!fetchResult.ok) { + throw new Error('Fetch result is not ok'); + } + + await getOneCharacter(formData.get('avatar_url')); + favsToHotswap(); // Update fav state + + $('#add_avatar_button').replaceWith( + $('#add_avatar_button').val('').clone(true), + ); + $('#create_button').attr('value', 'Save'); + crop_data = undefined; + await eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } }); + + // Recreate the chat if it hasn't been used at least once (i.e. with continue). + const message = getFirstMessage(); + const shouldRegenerateMessage = + !isNewChat && + message.mes && + !selected_group && + !chat_metadata['tainted'] && + (chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system)); + + if (shouldRegenerateMessage) { + chat.splice(0, chat.length, message); + const messageId = (chat.length - 1); + await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId); + await clearChat(); + await printMessages(); + await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId); + await saveChatConditional(); + } + } catch (error) { + console.log(error); + toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.'); + } } } @@ -8526,7 +8523,7 @@ async function selectContextCallback(args, name) { async function selectInstructCallback(args, name) { if (!name) { - return power_user.instruct.preset; + return power_user.instruct.enabled || isTrueBoolean(args?.forceGet) ? power_user.instruct.preset : ''; } const quiet = isTrueBoolean(args?.quiet); @@ -9227,6 +9224,13 @@ jQuery(async function () { defaultValue: 'false', enumList: commonEnumProviders.boolean('trueFalse')(), }), + SlashCommandNamedArgument.fromProps({ + name: 'forceGet', + description: 'Force getting a name even if instruct mode is disabled', + typeList: [ARGUMENT_TYPE.BOOLEAN], + defaultValue: 'false', + enumList: commonEnumProviders.boolean('trueFalse')(), + }), ], unnamedArgumentList: [ SlashCommandArgument.fromProps({ @@ -9237,7 +9241,8 @@ jQuery(async function () { ], helpString: `
forceGet=true
is passed.