Merge pull request #4041 from SillyTavern/staging Staging
Signed| @@ -13,3 +13,4 @@ access.log | |||
| 13 | /cache | 13 | /cache |
| 14 | .DS_Store | 14 | .DS_Store |
| 15 | /public/scripts/extensions/third-party | 15 | /public/scripts/extensions/third-party |
| 16 | /colab | ||
| @@ -42,7 +42,7 @@ If you're not familiar with using the git CLI or don't understand what a branch | |||
| 42 | 42 | ||
| 43 | ## What do I need other than SillyTavern? | 43 | ## What do I need other than SillyTavern? |
| 44 | 44 | ||
| 45 | Since SillyTavern is only an interface, you will need access to an LLM backend to provide inference. You can use AI Horde for instant out-of-the-box chatting. Aside from that, we support many other local and cloud-based LLM backends: OpenAI-compatible API, KoboldAI, Tabby, and many more. You can read more about our supported APIs in [the FAQ](https://docs.sillytavern.app/usage/api-connections/). | 45 | Since SillyTavern is only an interface, you will need access to an LLM backend to provide inference. You can use AI Horde for instant out-of-the-box chatting. Aside from that, we support many other local and cloud-based LLM backends: OpenAI-compatible API, KoboldAI, Tabby, and many more. You can read more about our supported APIs in [the Docs](https://docs.sillytavern.app/usage/api-connections/). |
| 46 | 46 | ||
| 47 | ### Do I need a powerful PC to run SillyTavern? | 47 | ### Do I need a powerful PC to run SillyTavern? |
| 48 | 48 | ||
| @@ -83,9 +83,7 @@ Or get in touch with the developers directly: | |||
| 83 | 83 | ||
| 84 | SillyTavern is built around the concept of "character cards". A character card is a collection of prompts that set the behavior of the LLM and is required to have persistent conversations in SillyTavern. They function similarly to ChatGPT's GPTs or Poe's bots. The content of a character card can be anything: an abstract scenario, an assistant tailored for a specific task, a famous personality or a fictional character. | 84 | SillyTavern is built around the concept of "character cards". A character card is a collection of prompts that set the behavior of the LLM and is required to have persistent conversations in SillyTavern. They function similarly to ChatGPT's GPTs or Poe's bots. The content of a character card can be anything: an abstract scenario, an assistant tailored for a specific task, a famous personality or a fictional character. |
| 85 | 85 | ||
| 86 | The name field is the only required character card input. To start a neutral conversation with the language model, create a new card simply called "Assistant" and leave the rest of the boxes blank. For a more themed chat, you can provide the language model with various background details, behavior and writing patterns, and a scenario to jump start the chat. | 86 | To have a quick conversation without selecting a character card or to just test the LLM connection, simply type your prompt input into the input bar on the Welcome Screen after opening SillyTavern. This will create an empty "Assistant" character card that you can customize later. |
| 87 | |||
| 88 | To have a quick conversation without selecting a character card or to just test the LLM connection, simply type your prompt input into the input bar on the Welcome Screen after opening SillyTavern. Please note that such chats are temporary and will not be saved. | ||
| 89 | 87 | ||
| 90 | To get a general idea on how to define character cards, see the default character (Seraphina) or download selected community-made cards from the "Download Extensions & Assets" menu. | 88 | To get a general idea on how to define character cards, see the default character (Seraphina) or download selected community-made cards from the "Download Extensions & Assets" menu. |
| 91 | 89 | ||
| @@ -316,18 +314,6 @@ chmod +x launcher.sh && ./launcher.sh | |||
| 316 | 314 | ||
| 317 | **Unsupported platform: android arm LEtime-web.** 32-bit Android requires an external dependency that can't be installed with npm. Use the following command to install it: `pkg install esbuild`. Then run the usual installation steps. | 315 | **Unsupported platform: android arm LEtime-web.** 32-bit Android requires an external dependency that can't be installed with npm. Use the following command to install it: `pkg install esbuild`. Then run the usual installation steps. |
| 318 | 316 | ||
| 319 | ## API keys management | ||
| 320 | |||
| 321 | SillyTavern saves your API keys to a `secrets.json` file in the user data directory (`/data/default-user/secrets.json` is the default path). | ||
| 322 | |||
| 323 | By default, API keys will not be visible from the interface after you have saved them and refreshed the page. | ||
| 324 | |||
| 325 | In order to enable viewing your keys: | ||
| 326 | |||
| 327 | 1. Set the value of `allowKeysExposure` to `true` in `config.yaml` file. | ||
| 328 | 2. Restart the SillyTavern server. | ||
| 329 | 3. Click the 'View hidden API keys' link at the bottom right of the API Connection Panel. | ||
| 330 | |||
| 331 | ## Command-line arguments | 317 | ## Command-line arguments |
| 332 | 318 | ||
| 333 | You can pass command-line arguments to SillyTavern server startup to override some settings in `config.yaml`. | 319 | You can pass command-line arguments to SillyTavern server startup to override some settings in `config.yaml`. |
| @@ -350,6 +336,7 @@ Start.bat --port 8000 --listen false | |||
| 350 | | Option | Description | Type | | 336 | | Option | Description | Type | |
| 351 | |-------------------------|----------------------------------------------------------------------|----------| | 337 | |-------------------------|----------------------------------------------------------------------|----------| |
| 352 | | `--version` | Show version number | boolean | | 338 | | `--version` | Show version number | boolean | |
| 339 | | `--configPath` | Override the path to the config.yaml file | string | | ||
| 353 | | `--dataRoot` | Root directory for data storage | string | | 340 | | `--dataRoot` | Root directory for data storage | string | |
| 354 | | `--port` | Sets the port under which SillyTavern will run | number | | 341 | | `--port` | Sets the port under which SillyTavern will run | number | |
| 355 | | `--listen` | SillyTavern will listen on all network interfaces | boolean | | 342 | | `--listen` | SillyTavern will listen on all network interfaces | boolean | |
| @@ -379,32 +366,7 @@ Most often this is for people who want to use SillyTavern on their mobile phones | |||
| 379 | 366 | ||
| 380 | Read the detailed guide on how to set up remote connections in the [Docs](https://docs.sillytavern.app/usage/remoteconnections/). | 367 | Read the detailed guide on how to set up remote connections in the [Docs](https://docs.sillytavern.app/usage/remoteconnections/). |
| 381 | 368 | ||
| 382 | You may also want to configure SillyTavern user profiles with (optional) password protection: [Users](https://docs.sillytavern.app/installation/st-1.12.0-migration-guide/#users). | 369 | You may also want to configure SillyTavern user profiles with (optional) password protection: [Users](https://docs.sillytavern.app/administration/multi-user/). |
| 383 | |||
| 384 | ## Performance issues? | ||
| 385 | |||
| 386 | ### General tips | ||
| 387 | |||
| 388 | 1. Disable the Blur Effect and enable Reduced Motion on the User Settings panel (UI Theme toggles category). | ||
| 389 | 2. If using response streaming, set the streaming FPS to a lower value (10-15 FPS is recommended). | ||
| 390 | 3. Make sure the browser is enabled to use GPU acceleration for rendering. | ||
| 391 | |||
| 392 | ### Input lag | ||
| 393 | |||
| 394 | Performance degradation, particularly input lag, is most commonly attributed to browser extensions. Known problematic extensions include: | ||
| 395 | |||
| 396 | * iCloud Password Manager | ||
| 397 | * DeepL Translation | ||
| 398 | * AI-based grammar correction tools | ||
| 399 | * Various ad-blocking extensions | ||
| 400 | |||
| 401 | If you experience performance issues and cannot identify the cause, or suspect an issue with SillyTavern itself, please: | ||
| 402 | |||
| 403 | 1. [Record a performance profile](https://developer.chrome.com/docs/devtools/performance/reference) | ||
| 404 | 2. Export the profile as a JSON file | ||
| 405 | 3. Submit it to the development team for analysis | ||
| 406 | |||
| 407 | We recommend first testing with all browser extensions and third-party SillyTavern extensions disabled to isolate the source of the performance degradation. | ||
| 408 | 370 | ||
| 409 | ## License and credits | 371 | ## License and credits |
| 410 | 372 | ||
| @@ -12,3 +12,4 @@ access.log | |||
| 12 | .vscode | 12 | .vscode |
| 13 | .git | 13 | .git |
| 14 | /public/scripts/extensions/third-party | 14 | /public/scripts/extensions/third-party |
| 15 | /colab | ||
| @@ -4,7 +4,7 @@ FROM node:lts-alpine3.19 | |||
| 4 | ARG APP_HOME=/home/node/app | 4 | ARG APP_HOME=/home/node/app |
| 5 | 5 | ||
| 6 | # Install system dependencies | 6 | # Install system dependencies |
| 7 | RUN apk add --no-cache gcompat tini git | 7 | RUN apk add --no-cache gcompat tini git git-lfs |
| 8 | 8 | ||
| 9 | # Create app directory | 9 | # Create app directory |
| 10 | WORKDIR ${APP_HOME} | 10 | WORKDIR ${APP_HOME} |
| @@ -12,15 +12,13 @@ WORKDIR ${APP_HOME} | |||
| 12 | # Set NODE_ENV to production | 12 | # Set NODE_ENV to production |
| 13 | ENV NODE_ENV=production | 13 | ENV NODE_ENV=production |
| 14 | 14 | ||
| 15 | # Install app dependencies | 15 | # Bundle app source |
| 16 | COPY package*.json post-install.js ./ | 16 | COPY . ./ |
| 17 | |||
| 17 | RUN \ | 18 | RUN \ |
| 18 | echo "*** Install npm packages ***" && \ | 19 | echo "*** Install npm packages ***" && \ |
| 19 | npm i --no-audit --no-fund --loglevel=error --no-progress --omit=dev && npm cache clean --force | 20 | npm i --no-audit --no-fund --loglevel=error --no-progress --omit=dev && npm cache clean --force |
| 20 | 21 | ||
| 21 | # Bundle app source | ||
| 22 | COPY . ./ | ||
| 23 | |||
| 24 | # Copy default chats, characters and user avatars to <folder>.default folder | 22 | # Copy default chats, characters and user avatars to <folder>.default folder |
| 25 | RUN \ | 23 | RUN \ |
| 26 | rm -f "config.yaml" || true && \ | 24 | rm -f "config.yaml" || true && \ |
| @@ -234,6 +234,14 @@ claude: | |||
| 234 | # should be ideal for most use cases. | 234 | # should be ideal for most use cases. |
| 235 | # Any value other than a non-negative integer will be ignored and caching at depth will not be enabled. | 235 | # Any value other than a non-negative integer will be ignored and caching at depth will not be enabled. |
| 236 | cachingAtDepth: -1 | 236 | cachingAtDepth: -1 |
| 237 | # Use 1h TTL instead of the default 5m. | ||
| 238 | ## 5m: base price x 1.25 | ||
| 239 | ## 1h: base price x 2 | ||
| 240 | extendedTTL: false | ||
| 241 | # -- GOOGLE GEMINI API CONFIGURATION -- | ||
| 242 | gemini: | ||
| 243 | # API endpoint version ("v1beta" or "v1alpha") | ||
| 244 | apiVersion: 'v1beta' | ||
| 237 | # -- SERVER PLUGIN CONFIGURATION -- | 245 | # -- SERVER PLUGIN CONFIGURATION -- |
| 238 | enableServerPlugins: false | 246 | enableServerPlugins: false |
| 239 | # Attempt to automatically update server plugins on startup | 247 | # Attempt to automatically update server plugins on startup |
| @@ -540,7 +540,7 @@ | |||
| 540 | "type": "context" | 540 | "type": "context" |
| 541 | }, | 541 | }, |
| 542 | { | 542 | { |
| 543 | "filename": "presets/context/Pygmalion.json", | 543 | "filename": "presets/context/Metharme.json", |
| 544 | "type": "context" | 544 | "type": "context" |
| 545 | }, | 545 | }, |
| 546 | { | 546 | { |
| @@ -620,10 +620,6 @@ | |||
| 620 | "type": "instruct" | 620 | "type": "instruct" |
| 621 | }, | 621 | }, |
| 622 | { | 622 | { |
| 623 | "filename": "presets/instruct/Pygmalion.json", | ||
| 624 | "type": "instruct" | ||
| 625 | }, | ||
| 626 | { | ||
| 627 | "filename": "presets/instruct/Story.json", | 623 | "filename": "presets/instruct/Story.json", |
| 628 | "type": "instruct" | 624 | "type": "instruct" |
| 629 | }, | 625 | }, |
| @@ -756,6 +752,10 @@ | |||
| 756 | "type": "sysprompt" | 752 | "type": "sysprompt" |
| 757 | }, | 753 | }, |
| 758 | { | 754 | { |
| 755 | "filename": "presets/sysprompt/Lightning 1.1.json", | ||
| 756 | "type": "sysprompt" | ||
| 757 | }, | ||
| 758 | { | ||
| 759 | "filename": "presets/instruct/Mistral V1.json", | 759 | "filename": "presets/instruct/Mistral V1.json", |
| 760 | "type": "instruct" | 760 | "type": "instruct" |
| 761 | }, | 761 | }, |
| @@ -796,6 +796,14 @@ | |||
| 796 | "type": "context" | 796 | "type": "context" |
| 797 | }, | 797 | }, |
| 798 | { | 798 | { |
| 799 | "filename": "presets/instruct/GLM-4.json", | ||
| 800 | "type": "instruct" | ||
| 801 | }, | ||
| 802 | { | ||
| 803 | "filename": "presets/context/GLM-4.json", | ||
| 804 | "type": "context" | ||
| 805 | }, | ||
| 806 | { | ||
| 799 | "filename": "presets/reasoning/DeepSeek.json", | 807 | "filename": "presets/reasoning/DeepSeek.json", |
| 800 | "type": "reasoning" | 808 | "type": "reasoning" |
| 801 | }, | 809 | }, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": false, | 6 | "always_force_name2": false, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": true, | 8 | "single_line": true, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": false, | 6 | "always_force_name2": false, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>New Roleplay:<|END_OF_TURN_TOKEN|>", | 4 | "chat_start": "<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>New Roleplay:<|END_OF_TURN_TOKEN|>", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "***", | 3 | "example_separator": "***", |
| 4 | "chat_start": "***", | 4 | "chat_start": "***", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": false, | 6 | "always_force_name2": false, |
| 8 | "trim_sentences": true, | 7 | "trim_sentences": true, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nWrite an example narrative / conversation that is not part of the main story.", | 3 | "example_separator": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nWrite an example narrative / conversation that is not part of the main story.", |
| 4 | "chat_start": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nStart the role-play between {{char}} and {{user}}.", | 4 | "chat_start": "<|eot_id|>\n<|start_header_id|>user<|end_header_id|>\n\nStart the role-play between {{char}} and {{user}}.", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": false, | 6 | "always_force_name2": false, |
| 8 | "trim_sentences": true, | 7 | "trim_sentences": true, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -0,0 +1,10 @@ | |||
| 1 | { | ||
| 2 | "story_string": "[gMASK]<sop>{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n", | ||
| 3 | "example_separator": "", | ||
| 4 | "chat_start": "", | ||
| 5 | "use_stop_strings": false, | ||
| 6 | "always_force_name2": true, | ||
| 7 | "trim_sentences": false, | ||
| 8 | "single_line": false, | ||
| 9 | "name": "GLM-4" | ||
| 10 | } | ||
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "### Example:", | 3 | "example_separator": "### Example:", |
| 4 | "chat_start": "### START ROLEPLAY:", | 4 | "chat_start": "### START ROLEPLAY:", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -1,9 +1,8 @@ | |||
| 1 | { | 1 | { |
| 2 | "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}}", | 2 | "story_string": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\n{{system}}\n{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{char}}'s description:{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality:{{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{user}}'s persona: {{persona}}\n{{/if}}\n\n", |
| 3 | "example_separator": "Example of an interaction:", | 3 | "example_separator": "Example of an interaction:\n", |
| 4 | "chat_start": "This is the history of the roleplay:", | 4 | "chat_start": "This is the history of the roleplay:\n", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,9 +3,8 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| 10 | "name": "Pygmalion" | 9 | "name": "Metharme" |
| 11 | } | 10 | } |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "***", | 3 | "example_separator": "***", |
| 4 | "chat_start": "***", | 4 | "chat_start": "***", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "This is how {{char}} should talk", | 3 | "example_separator": "This is how {{char}} should talk", |
| 4 | "chat_start": "\nThen the roleplay chat between {{user}} and {{char}} begins.\n", | 4 | "chat_start": "\nThen the roleplay chat between {{user}} and {{char}} begins.\n", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "", | 3 | "example_separator": "", |
| 4 | "chat_start": "", | 4 | "chat_start": "", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -3,7 +3,6 @@ | |||
| 3 | "example_separator": "### New Roleplay:", | 3 | "example_separator": "### New Roleplay:", |
| 4 | "chat_start": "### New Roleplay:", | 4 | "chat_start": "### New Roleplay:", |
| 5 | "use_stop_strings": false, | 5 | "use_stop_strings": false, |
| 6 | "allow_jailbreak": false, | ||
| 7 | "always_force_name2": true, | 6 | "always_force_name2": true, |
| 8 | "trim_sentences": false, | 7 | "trim_sentences": false, |
| 9 | "single_line": false, | 8 | "single_line": false, |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "<|im_end|>", | 6 | "stop_sequence": "<|im_end|>", |
| 7 | "wrap": true, | 7 | "wrap": true, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -8,7 +8,7 @@ | |||
| 8 | "stop_sequence": "<|END_OF_TURN_TOKEN|>", | 8 | "stop_sequence": "<|END_OF_TURN_TOKEN|>", |
| 9 | "wrap": false, | 9 | "wrap": false, |
| 10 | "macro": true, | 10 | "macro": true, |
| 11 | "names_behavior": "always", | 11 | "names_behavior": "force", |
| 12 | "activation_regex": "", | 12 | "activation_regex": "", |
| 13 | "skip_examples": false, | 13 | "skip_examples": false, |
| 14 | "output_suffix": "<|END_OF_TURN_TOKEN|>", | 14 | "output_suffix": "<|END_OF_TURN_TOKEN|>", |
| @@ -1,22 +1,22 @@ | |||
| 1 | { | 1 | { |
| 2 | "input_sequence": "<|user|>", | 2 | "input_sequence": "<|user|>\n", |
| 3 | "output_sequence": "<|model|>", | 3 | "output_sequence": "<|assistant|>\n", |
| 4 | "first_output_sequence": "", | ||
| 4 | "last_output_sequence": "", | 5 | "last_output_sequence": "", |
| 5 | "system_sequence": "", | 6 | "system_sequence_prefix": "<|system|>\n", |
| 6 | "stop_sequence": "<|user|>", | 7 | "system_sequence_suffix": "", |
| 8 | "stop_sequence": "", | ||
| 7 | "wrap": false, | 9 | "wrap": false, |
| 8 | "macro": true, | 10 | "macro": true, |
| 9 | "names_behavior": "always", | 11 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 12 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "<|system|>", | ||
| 12 | "system_sequence_suffix": "", | ||
| 13 | "first_output_sequence": "", | ||
| 14 | "skip_examples": false, | 13 | "skip_examples": false, |
| 15 | "output_suffix": "", | 14 | "output_suffix": "", |
| 16 | "input_suffix": "", | 15 | "input_suffix": "", |
| 16 | "system_sequence": "", | ||
| 17 | "system_suffix": "", | 17 | "system_suffix": "", |
| 18 | "user_alignment_message": "", | 18 | "user_alignment_message": "", |
| 19 | "system_same_as_user": true, | ||
| 20 | "last_system_sequence": "", | 19 | "last_system_sequence": "", |
| 21 | "name": "Pygmalion" | 20 | "system_same_as_user": true, |
| 21 | "name": "GLM-4" | ||
| 22 | } | 22 | } |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "<end_of_turn>", | 6 | "stop_sequence": "<end_of_turn>", |
| 7 | "wrap": true, | 7 | "wrap": true, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "none", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -1,7 +1,7 @@ | |||
| 1 | { | 1 | { |
| 2 | "input_sequence": "### Instruction:", | 2 | "input_sequence": "### Instruction:", |
| 3 | "output_sequence": "### Response: (length = unlimited)", | 3 | "output_sequence": "### Response:", |
| 4 | "last_output_sequence": "", | 4 | "last_output_sequence": "### Response: (length = unlimited)", |
| 5 | "system_sequence": "", | 5 | "system_sequence": "", |
| 6 | "stop_sequence": "", | 6 | "stop_sequence": "", |
| 7 | "wrap": true, | 7 | "wrap": true, |
| @@ -12,8 +12,8 @@ | |||
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| 13 | "first_output_sequence": "", | 13 | "first_output_sequence": "", |
| 14 | "skip_examples": false, | 14 | "skip_examples": false, |
| 15 | "output_suffix": "", | 15 | "output_suffix": "\n\n", |
| 16 | "input_suffix": "", | 16 | "input_suffix": "\n\n", |
| 17 | "system_suffix": "", | 17 | "system_suffix": "", |
| 18 | "user_alignment_message": "", | 18 | "user_alignment_message": "", |
| 19 | "system_same_as_user": true, | 19 | "system_same_as_user": true, |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "<|eot_id|>", | 6 | "stop_sequence": "<|eot_id|>", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "<|eot|>", | 6 | "stop_sequence": "<|eot|>", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "", | 6 | "stop_sequence": "", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "", | 6 | "stop_sequence": "", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "", | 6 | "stop_sequence": "", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -6,7 +6,7 @@ | |||
| 6 | "stop_sequence": "</s>", | 6 | "stop_sequence": "</s>", |
| 7 | "wrap": false, | 7 | "wrap": false, |
| 8 | "macro": true, | 8 | "macro": true, |
| 9 | "names_behavior": "always", | 9 | "names_behavior": "force", |
| 10 | "activation_regex": "", | 10 | "activation_regex": "", |
| 11 | "system_sequence_prefix": "", | 11 | "system_sequence_prefix": "", |
| 12 | "system_sequence_suffix": "", | 12 | "system_sequence_suffix": "", |
| @@ -8,7 +8,7 @@ | |||
| 8 | "stop_sequence": "<|end|>", | 8 | "stop_sequence": "<|end|>", |
| 9 | "wrap": false, | 9 | "wrap": false, |
| 10 | "macro": true, | 10 | "macro": true, |
| 11 | "names_behavior": "always", | 11 | "names_behavior": "force", |
| 12 | "activation_regex": "", | 12 | "activation_regex": "", |
| 13 | "skip_examples": false, | 13 | "skip_examples": false, |
| 14 | "output_suffix": "<|end|>\n", | 14 | "output_suffix": "<|end|>\n", |
| @@ -8,7 +8,7 @@ | |||
| 8 | "stop_sequence": "<|end_of_text|>", | 8 | "stop_sequence": "<|end_of_text|>", |
| 9 | "wrap": false, | 9 | "wrap": false, |
| 10 | "macro": true, | 10 | "macro": true, |
| 11 | "names_behavior": "always", | 11 | "names_behavior": "force", |
| 12 | "activation_regex": "", | 12 | "activation_regex": "", |
| 13 | "skip_examples": false, | 13 | "skip_examples": false, |
| 14 | "output_suffix": "<|end_of_text|>\n", | 14 | "output_suffix": "<|end_of_text|>\n", |
| @@ -15,6 +15,7 @@ | |||
| 15 | "custom_exclude_body": "", | 15 | "custom_exclude_body": "", |
| 16 | "custom_include_headers": "", | 16 | "custom_include_headers": "", |
| 17 | "google_model": "gemini-pro", | 17 | "google_model": "gemini-pro", |
| 18 | "vertexai_model": "gemini-2.0-flash-001", | ||
| 18 | "temperature": 1, | 19 | "temperature": 1, |
| 19 | "frequency_penalty": 0, | 20 | "frequency_penalty": 0, |
| 20 | "presence_penalty": 0, | 21 | "presence_penalty": 0, |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Actor", | 2 | "name": "Actor", |
| 3 | "content": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}." | 3 | "content": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Assistant - Expert", | 2 | "name": "Assistant - Expert", |
| 3 | "content": "You are a helpful assistant. Please answer truthfully and write out your thinking step by step to be sure you get the right answer. If you make a mistake or encounter an error in your thinking, say so out loud and attempt to correct it. If you don't know or aren't sure about something, say so clearly. You will act as a professional logician, mathematician, and physicist. You will also act as the most appropriate type of expert to answer any particular question or solve the relevant problem; state which expert type your are, if so. Also think of any particular named expert that would be ideal to answer the relevant question or solve the relevant problem; name and act as them, if appropriate." | 3 | "content": "You are a helpful assistant. Please answer truthfully and write out your thinking step by step to be sure you get the right answer. If you make a mistake or encounter an error in your thinking, say so out loud and attempt to correct it. If you don't know or aren't sure about something, say so clearly. You will act as a professional logician, mathematician, and physicist. You will also act as the most appropriate type of expert to answer any particular question or solve the relevant problem; state which expert type your are, if so. Also think of any particular named expert that would be ideal to answer the relevant question or solve the relevant problem; name and act as them, if appropriate.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Assistant - Simple", | 2 | "name": "Assistant - Simple", |
| 3 | "content": "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions." | 3 | "content": "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Blank", | 2 | "name": "Blank", |
| 3 | "content": "" | 3 | "content": "", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Chain of Thought", | 2 | "name": "Chain of Thought", |
| 3 | "content": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation." | 3 | "content": "Elaborate on the topic using a Tree of Thoughts and backtrack when necessary to construct a clear, cohesive Chain of Thought reasoning. Always answer without hesitation.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -0,0 +1,5 @@ | |||
| 1 | { | ||
| 2 | "name": "Lightning 1.1", | ||
| 3 | "content": "Take the role of {{char}} in a play that leaves a lasting impression on {{user}}. Write {{char}}'s next reply.\nNever skip or gloss over {{char}}’s actions. Progress the scene at a naturally slow pace.", | ||
| 4 | "post_history": "" | ||
| 5 | } | ||
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Neutral - Chat", | 2 | "name": "Neutral - Chat", |
| 3 | "content": "Write {{char}}'s next reply in a fictional chat between {{char}} and {{user}}." | 3 | "content": "Write {{char}}'s next reply in a fictional chat between {{char}} and {{user}}.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Roleplay - Detailed", | 2 | "name": "Roleplay - Detailed", |
| 3 | "content": "Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions. Keep the story immersive and engaging." | 3 | "content": "Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions. Keep the story immersive and engaging.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Roleplay - Immersive", | 2 | "name": "Roleplay - Immersive", |
| 3 | "content": "[System note: Write one reply only. Do not decide what {{user}} says or does. Write at least one paragraph, up to four. Be descriptive and immersive, providing vivid details about {{char}}'s actions, emotions, and the environment. Write with a high degree of complexity and burstiness. Do not repeat this message.]" | 3 | "content": "[System note: Write one reply only. Do not decide what {{user}} says or does. Write at least one paragraph, up to four. Be descriptive and immersive, providing vivid details about {{char}}'s actions, emotions, and the environment. Write with a high degree of complexity and burstiness. Do not repeat this message.]", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Roleplay - Simple", | 2 | "name": "Roleplay - Simple", |
| 3 | "content": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}." | 3 | "content": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Text Adventure", | 2 | "name": "Text Adventure", |
| 3 | "content": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]" | 3 | "content": "[Enter Adventure Mode. Narrate the story based on {{user}}'s dialogue and actions after \">\". Describe the surroundings in vivid detail. Be detailed, creative, verbose, and proactive. Move the story forward by introducing fantasy elements and interesting characters.]", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Writer - Creative", | 2 | "name": "Writer - Creative", |
| 3 | "content": "You are an intelligent, skilled, versatile writer.\n\nYour task is to write a role-play based on the information below." | 3 | "content": "You are an intelligent, skilled, versatile writer.\n\nYour task is to write a role-play based on the information below.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "Writer - Realistic", | 2 | "name": "Writer - Realistic", |
| 3 | "content": "Continue writing this story and portray characters realistically." | 3 | "content": "Continue writing this story and portray characters realistically.", |
| 4 | "post_history": "" | ||
| 4 | } | 5 | } |
| @@ -1,12 +1,12 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "sillytavern", | 2 | "name": "sillytavern", |
| 3 | "version": "1.12.14", | 3 | "version": "1.13.0", |
| 4 | "lockfileVersion": 3, | 4 | "lockfileVersion": 3, |
| 5 | "requires": true, | 5 | "requires": true, |
| 6 | "packages": { | 6 | "packages": { |
| 7 | "": { | 7 | "": { |
| 8 | "name": "sillytavern", | 8 | "name": "sillytavern", |
| 9 | "version": "1.12.14", | 9 | "version": "1.13.0", |
| 10 | "hasInstallScript": true, | 10 | "hasInstallScript": true, |
| 11 | "license": "AGPL-3.0", | 11 | "license": "AGPL-3.0", |
| 12 | "dependencies": { | 12 | "dependencies": { |
| @@ -18,6 +18,7 @@ | |||
| 18 | "@jimp/js-bmp": "^1.6.0", | 18 | "@jimp/js-bmp": "^1.6.0", |
| 19 | "@jimp/js-gif": "^1.6.0", | 19 | "@jimp/js-gif": "^1.6.0", |
| 20 | "@jimp/js-tiff": "^1.6.0", | 20 | "@jimp/js-tiff": "^1.6.0", |
| 21 | "@jimp/plugin-blit": "^1.6.0", | ||
| 21 | "@jimp/plugin-circle": "^1.6.0", | 22 | "@jimp/plugin-circle": "^1.6.0", |
| 22 | "@jimp/plugin-color": "^1.6.0", | 23 | "@jimp/plugin-color": "^1.6.0", |
| 23 | "@jimp/plugin-contain": "^1.6.0", | 24 | "@jimp/plugin-contain": "^1.6.0", |
| @@ -28,6 +29,7 @@ | |||
| 28 | "@jimp/plugin-flip": "^1.6.0", | 29 | "@jimp/plugin-flip": "^1.6.0", |
| 29 | "@jimp/plugin-mask": "^1.6.0", | 30 | "@jimp/plugin-mask": "^1.6.0", |
| 30 | "@jimp/plugin-quantize": "^1.6.0", | 31 | "@jimp/plugin-quantize": "^1.6.0", |
| 32 | "@jimp/plugin-resize": "^1.6.0", | ||
| 31 | "@jimp/plugin-rotate": "^1.6.0", | 33 | "@jimp/plugin-rotate": "^1.6.0", |
| 32 | "@jimp/plugin-threshold": "^1.6.0", | 34 | "@jimp/plugin-threshold": "^1.6.0", |
| 33 | "@jimp/wasm-avif": "^1.6.0", | 35 | "@jimp/wasm-avif": "^1.6.0", |
| @@ -8,6 +8,7 @@ | |||
| 8 | "@jimp/js-bmp": "^1.6.0", | 8 | "@jimp/js-bmp": "^1.6.0", |
| 9 | "@jimp/js-gif": "^1.6.0", | 9 | "@jimp/js-gif": "^1.6.0", |
| 10 | "@jimp/js-tiff": "^1.6.0", | 10 | "@jimp/js-tiff": "^1.6.0", |
| 11 | "@jimp/plugin-blit": "^1.6.0", | ||
| 11 | "@jimp/plugin-circle": "^1.6.0", | 12 | "@jimp/plugin-circle": "^1.6.0", |
| 12 | "@jimp/plugin-color": "^1.6.0", | 13 | "@jimp/plugin-color": "^1.6.0", |
| 13 | "@jimp/plugin-contain": "^1.6.0", | 14 | "@jimp/plugin-contain": "^1.6.0", |
| @@ -18,6 +19,7 @@ | |||
| 18 | "@jimp/plugin-flip": "^1.6.0", | 19 | "@jimp/plugin-flip": "^1.6.0", |
| 19 | "@jimp/plugin-mask": "^1.6.0", | 20 | "@jimp/plugin-mask": "^1.6.0", |
| 20 | "@jimp/plugin-quantize": "^1.6.0", | 21 | "@jimp/plugin-quantize": "^1.6.0", |
| 22 | "@jimp/plugin-resize": "^1.6.0", | ||
| 21 | "@jimp/plugin-rotate": "^1.6.0", | 23 | "@jimp/plugin-rotate": "^1.6.0", |
| 22 | "@jimp/plugin-threshold": "^1.6.0", | 24 | "@jimp/plugin-threshold": "^1.6.0", |
| 23 | "@jimp/wasm-avif": "^1.6.0", | 25 | "@jimp/wasm-avif": "^1.6.0", |
| @@ -109,7 +111,7 @@ | |||
| 109 | "type": "git", | 111 | "type": "git", |
| 110 | "url": "https://github.com/SillyTavern/SillyTavern.git" | 112 | "url": "https://github.com/SillyTavern/SillyTavern.git" |
| 111 | }, | 113 | }, |
| 112 | "version": "1.12.14", | 114 | "version": "1.13.0", |
| 113 | "scripts": { | 115 | "scripts": { |
| 114 | "start": "node server.js", | 116 | "start": "node server.js", |
| 115 | "debug": "node --inspect server.js", | 117 | "debug": "node --inspect server.js", |
| @@ -3,133 +3,17 @@ | |||
| 3 | */ | 3 | */ |
| 4 | import fs from 'node:fs'; | 4 | import fs from 'node:fs'; |
| 5 | import path from 'node:path'; | 5 | import path from 'node:path'; |
| 6 | import crypto from 'node:crypto'; | ||
| 7 | import process from 'node:process'; | 6 | import process from 'node:process'; |
| 8 | import yaml from 'yaml'; | 7 | import yaml from 'yaml'; |
| 9 | import _ from 'lodash'; | ||
| 10 | import chalk from 'chalk'; | 8 | import chalk from 'chalk'; |
| 11 | import { createRequire } from 'node:module'; | 9 | import { createRequire } from 'node:module'; |
| 10 | import { addMissingConfigValues } from './src/config-init.js'; | ||
| 12 | 11 | ||
| 13 | /** | 12 | /** |
| 14 | * Colorizes console output. | 13 | * Colorizes console output. |
| 15 | */ | 14 | */ |
| 16 | const color = chalk; | 15 | const color = chalk; |
| 17 | 16 | ||
| 18 | const keyMigrationMap = [ | ||
| 19 | { | ||
| 20 | oldKey: 'disableThumbnails', | ||
| 21 | newKey: 'thumbnails.enabled', | ||
| 22 | migrate: (value) => !value, | ||
| 23 | }, | ||
| 24 | { | ||
| 25 | oldKey: 'thumbnailsQuality', | ||
| 26 | newKey: 'thumbnails.quality', | ||
| 27 | migrate: (value) => value, | ||
| 28 | }, | ||
| 29 | { | ||
| 30 | oldKey: 'avatarThumbnailsPng', | ||
| 31 | newKey: 'thumbnails.format', | ||
| 32 | migrate: (value) => (value ? 'png' : 'jpg'), | ||
| 33 | }, | ||
| 34 | { | ||
| 35 | oldKey: 'disableChatBackup', | ||
| 36 | newKey: 'backups.chat.enabled', | ||
| 37 | migrate: (value) => !value, | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | oldKey: 'numberOfBackups', | ||
| 41 | newKey: 'backups.common.numberOfBackups', | ||
| 42 | migrate: (value) => value, | ||
| 43 | }, | ||
| 44 | { | ||
| 45 | oldKey: 'maxTotalChatBackups', | ||
| 46 | newKey: 'backups.chat.maxTotalBackups', | ||
| 47 | migrate: (value) => value, | ||
| 48 | }, | ||
| 49 | { | ||
| 50 | oldKey: 'chatBackupThrottleInterval', | ||
| 51 | newKey: 'backups.chat.throttleInterval', | ||
| 52 | migrate: (value) => value, | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | oldKey: 'enableExtensions', | ||
| 56 | newKey: 'extensions.enabled', | ||
| 57 | migrate: (value) => value, | ||
| 58 | }, | ||
| 59 | { | ||
| 60 | oldKey: 'enableExtensionsAutoUpdate', | ||
| 61 | newKey: 'extensions.autoUpdate', | ||
| 62 | migrate: (value) => value, | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | oldKey: 'extras.disableAutoDownload', | ||
| 66 | newKey: 'extensions.models.autoDownload', | ||
| 67 | migrate: (value) => !value, | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | oldKey: 'extras.classificationModel', | ||
| 71 | newKey: 'extensions.models.classification', | ||
| 72 | migrate: (value) => value, | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | oldKey: 'extras.captioningModel', | ||
| 76 | newKey: 'extensions.models.captioning', | ||
| 77 | migrate: (value) => value, | ||
| 78 | }, | ||
| 79 | { | ||
| 80 | oldKey: 'extras.embeddingModel', | ||
| 81 | newKey: 'extensions.models.embedding', | ||
| 82 | migrate: (value) => value, | ||
| 83 | }, | ||
| 84 | { | ||
| 85 | oldKey: 'extras.speechToTextModel', | ||
| 86 | newKey: 'extensions.models.speechToText', | ||
| 87 | migrate: (value) => value, | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | oldKey: 'extras.textToSpeechModel', | ||
| 91 | newKey: 'extensions.models.textToSpeech', | ||
| 92 | migrate: (value) => value, | ||
| 93 | }, | ||
| 94 | { | ||
| 95 | oldKey: 'minLogLevel', | ||
| 96 | newKey: 'logging.minLogLevel', | ||
| 97 | migrate: (value) => value, | ||
| 98 | }, | ||
| 99 | { | ||
| 100 | oldKey: 'cardsCacheCapacity', | ||
| 101 | newKey: 'performance.memoryCacheCapacity', | ||
| 102 | migrate: (value) => `${value}mb`, | ||
| 103 | }, | ||
| 104 | { | ||
| 105 | oldKey: 'cookieSecret', | ||
| 106 | newKey: 'cookieSecret', | ||
| 107 | migrate: () => void 0, | ||
| 108 | remove: true, | ||
| 109 | }, | ||
| 110 | ]; | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Gets all keys from an object recursively. | ||
| 114 | * @param {object} obj Object to get all keys from | ||
| 115 | * @param {string} prefix Prefix to prepend to all keys | ||
| 116 | * @returns {string[]} Array of all keys in the object | ||
| 117 | */ | ||
| 118 | function getAllKeys(obj, prefix = '') { | ||
| 119 | if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) { | ||
| 120 | return []; | ||
| 121 | } | ||
| 122 | |||
| 123 | return _.flatMap(Object.keys(obj), key => { | ||
| 124 | const newPrefix = prefix ? `${prefix}.${key}` : key; | ||
| 125 | if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { | ||
| 126 | return getAllKeys(obj[key], newPrefix); | ||
| 127 | } else { | ||
| 128 | return [newPrefix]; | ||
| 129 | } | ||
| 130 | }); | ||
| 131 | } | ||
| 132 | |||
| 133 | /** | 17 | /** |
| 134 | * Converts the old config.conf file to the new config.yaml format. | 18 | * Converts the old config.conf file to the new config.yaml format. |
| 135 | */ | 19 | */ |
| @@ -157,71 +41,6 @@ function convertConfig() { | |||
| 157 | } | 41 | } |
| 158 | 42 | ||
| 159 | /** | 43 | /** |
| 160 | * Compares the current config.yaml with the default config.yaml and adds any missing values. | ||
| 161 | */ | ||
| 162 | function addMissingConfigValues() { | ||
| 163 | try { | ||
| 164 | const defaultConfig = yaml.parse(fs.readFileSync(path.join(process.cwd(), './default/config.yaml'), 'utf8')); | ||
| 165 | let config = yaml.parse(fs.readFileSync(path.join(process.cwd(), './config.yaml'), 'utf8')); | ||
| 166 | |||
| 167 | // Migrate old keys to new keys | ||
| 168 | const migratedKeys = []; | ||
| 169 | for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) { | ||
| 170 | if (_.has(config, oldKey)) { | ||
| 171 | if (remove) { | ||
| 172 | _.unset(config, oldKey); | ||
| 173 | migratedKeys.push({ | ||
| 174 | oldKey, | ||
| 175 | newValue: void 0, | ||
| 176 | }); | ||
| 177 | continue; | ||
| 178 | } | ||
| 179 | |||
| 180 | const oldValue = _.get(config, oldKey); | ||
| 181 | const newValue = migrate(oldValue); | ||
| 182 | _.set(config, newKey, newValue); | ||
| 183 | _.unset(config, oldKey); | ||
| 184 | |||
| 185 | migratedKeys.push({ | ||
| 186 | oldKey, | ||
| 187 | newKey, | ||
| 188 | oldValue, | ||
| 189 | newValue, | ||
| 190 | }); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | // Get all keys from the original config | ||
| 195 | const originalKeys = getAllKeys(config); | ||
| 196 | |||
| 197 | // Use lodash's defaultsDeep function to recursively apply default properties | ||
| 198 | config = _.defaultsDeep(config, defaultConfig); | ||
| 199 | |||
| 200 | // Get all keys from the updated config | ||
| 201 | const updatedKeys = getAllKeys(config); | ||
| 202 | |||
| 203 | // Find the keys that were added | ||
| 204 | const addedKeys = _.difference(updatedKeys, originalKeys); | ||
| 205 | |||
| 206 | if (addedKeys.length === 0 && migratedKeys.length === 0) { | ||
| 207 | return; | ||
| 208 | } | ||
| 209 | |||
| 210 | if (addedKeys.length > 0) { | ||
| 211 | console.log('Adding missing config values to config.yaml:', addedKeys); | ||
| 212 | } | ||
| 213 | |||
| 214 | if (migratedKeys.length > 0) { | ||
| 215 | console.log('Migrating config values in config.yaml:', migratedKeys); | ||
| 216 | } | ||
| 217 | |||
| 218 | fs.writeFileSync('./config.yaml', yaml.stringify(config)); | ||
| 219 | } catch (error) { | ||
| 220 | console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * Creates the default config files if they don't exist yet. | 44 | * Creates the default config files if they don't exist yet. |
| 226 | */ | 45 | */ |
| 227 | function createDefaultFiles() { | 46 | function createDefaultFiles() { |
| @@ -283,58 +102,13 @@ function createDefaultFiles() { | |||
| 283 | } | 102 | } |
| 284 | } | 103 | } |
| 285 | 104 | ||
| 286 | /** | ||
| 287 | * Returns the MD5 hash of the given data. | ||
| 288 | * @param {Buffer} data Input data | ||
| 289 | * @returns {string} MD5 hash of the input data | ||
| 290 | */ | ||
| 291 | function getMd5Hash(data) { | ||
| 292 | return crypto | ||
| 293 | .createHash('md5') | ||
| 294 | .update(new Uint8Array(data)) | ||
| 295 | .digest('hex'); | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * Copies the WASM binaries from the sillytavern-transformers package to the dist folder. | ||
| 300 | */ | ||
| 301 | function copyWasmFiles() { | ||
| 302 | if (!fs.existsSync('./dist')) { | ||
| 303 | fs.mkdirSync('./dist'); | ||
| 304 | } | ||
| 305 | |||
| 306 | const listDir = fs.readdirSync('./node_modules/sillytavern-transformers/dist'); | ||
| 307 | |||
| 308 | for (const file of listDir) { | ||
| 309 | if (file.endsWith('.wasm')) { | ||
| 310 | const sourcePath = `./node_modules/sillytavern-transformers/dist/${file}`; | ||
| 311 | const targetPath = `./dist/${file}`; | ||
| 312 | |||
| 313 | // Don't copy if the file already exists and is the same checksum | ||
| 314 | if (fs.existsSync(targetPath)) { | ||
| 315 | const sourceChecksum = getMd5Hash(fs.readFileSync(sourcePath)); | ||
| 316 | const targetChecksum = getMd5Hash(fs.readFileSync(targetPath)); | ||
| 317 | |||
| 318 | if (sourceChecksum === targetChecksum) { | ||
| 319 | continue; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | fs.copyFileSync(sourcePath, targetPath); | ||
| 324 | console.log(`${file} successfully copied to ./dist/${file}`); | ||
| 325 | } | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | try { | 105 | try { |
| 330 | // 0. Convert config.conf to config.yaml | 106 | // 0. Convert config.conf to config.yaml |
| 331 | convertConfig(); | 107 | convertConfig(); |
| 332 | // 1. Create default config files | 108 | // 1. Create default config files |
| 333 | createDefaultFiles(); | 109 | createDefaultFiles(); |
| 334 | // 2. Copy transformers WASM binaries from node_modules | 110 | // 2. Add missing config values |
| 335 | copyWasmFiles(); | 111 | addMissingConfigValues(path.join(process.cwd(), './config.yaml')); |
| 336 | // 3. Add missing config values | ||
| 337 | addMissingConfigValues(); | ||
| 338 | } catch (error) { | 112 | } catch (error) { |
| 339 | console.error(error); | 113 | console.error(error); |
| 340 | } | 114 | } |
| @@ -55,11 +55,14 @@ | |||
| 55 | 55 | ||
| 56 | /* Flashing for highlighting animation */ | 56 | /* Flashing for highlighting animation */ |
| 57 | @keyframes flash { | 57 | @keyframes flash { |
| 58 | 0%, 50%, 100% { | 58 | 0%, |
| 59 | 50%, | ||
| 60 | 100% { | ||
| 59 | opacity: 1; | 61 | opacity: 1; |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | 25%, 75% { | 64 | 25%, |
| 65 | 75% { | ||
| 63 | opacity: 0.2; | 66 | opacity: 0.2; |
| 64 | } | 67 | } |
| 65 | } | 68 | } |
| @@ -1,4 +1,3 @@ | |||
| 1 | |||
| 2 | #rm_print_characters_block.group_overlay_mode_select .character_select { | 1 | #rm_print_characters_block.group_overlay_mode_select .character_select { |
| 3 | transition: background-color 0.4s ease; | 2 | transition: background-color 0.4s ease; |
| 4 | background-color: rgba(170, 170, 170, 0.15); | 3 | background-color: rgba(170, 170, 170, 0.15); |
| @@ -28,7 +27,10 @@ | |||
| 28 | height: 0 !important; | 27 | height: 0 !important; |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | #character_context_menu.hidden { display: none; } | 30 | #character_context_menu.hidden { |
| 31 | display: none; | ||
| 32 | } | ||
| 33 | |||
| 32 | #character_context_menu { | 34 | #character_context_menu { |
| 33 | position: absolute; | 35 | position: absolute; |
| 34 | padding: 3px; | 36 | padding: 3px; |
| @@ -115,7 +115,8 @@ | |||
| 115 | background-color: rgba(255, 255, 0, 0.05); | 115 | background-color: rgba(255, 255, 0, 0.05); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | .logprobs_tint_0:hover, .logprobs_tint_0.selected { | 118 | .logprobs_tint_0:hover, |
| 119 | .logprobs_tint_0.selected { | ||
| 119 | background-color: rgba(255, 255, 0, 0.4); | 120 | background-color: rgba(255, 255, 0, 0.4); |
| 120 | } | 121 | } |
| 121 | 122 | ||
| @@ -123,7 +124,8 @@ | |||
| 123 | background-color: rgba(255, 0, 255, 0.05); | 124 | background-color: rgba(255, 0, 255, 0.05); |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | .logprobs_tint_1:hover, .logprobs_tint_1.selected { | 127 | .logprobs_tint_1:hover, |
| 128 | .logprobs_tint_1.selected { | ||
| 127 | background-color: rgba(255, 0, 255, 0.4); | 129 | background-color: rgba(255, 0, 255, 0.4); |
| 128 | } | 130 | } |
| 129 | 131 | ||
| @@ -131,7 +133,8 @@ | |||
| 131 | background-color: rgba(0, 255, 255, 0.05); | 133 | background-color: rgba(0, 255, 255, 0.05); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | .logprobs_tint_2:hover, .logprobs_tint_2.selected { | 136 | .logprobs_tint_2:hover, |
| 137 | .logprobs_tint_2.selected { | ||
| 135 | background-color: rgba(0, 255, 255, 0.4); | 138 | background-color: rgba(0, 255, 255, 0.4); |
| 136 | } | 139 | } |
| 137 | 140 | ||
| @@ -139,6 +142,7 @@ | |||
| 139 | background-color: rgba(50, 205, 50, 0.05); | 142 | background-color: rgba(50, 205, 50, 0.05); |
| 140 | } | 143 | } |
| 141 | 144 | ||
| 142 | .logprobs_tint_3:hover, .logprobs_tint_3.selected { | 145 | .logprobs_tint_3:hover, |
| 146 | .logprobs_tint_3.selected { | ||
| 143 | background-color: rgba(50, 205, 50, 0.4); | 147 | background-color: rgba(50, 205, 50, 0.4); |
| 144 | } | 148 | } |
| @@ -34,9 +34,17 @@ dialog { | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | /** Popup styles applied to the main popup */ | 36 | /** Popup styles applied to the main popup */ |
| 37 | .popup--animation-fast { --popup-animation-speed: var(--animation-duration); } | 37 | .popup--animation-fast { |
| 38 | .popup--animation-slow { --popup-animation-speed: var(--animation-duration-slow); } | 38 | --popup-animation-speed: var(--animation-duration); |
| 39 | .popup--animation-none { --popup-animation-speed: 0ms; } | 39 | } |
| 40 | |||
| 41 | .popup--animation-slow { | ||
| 42 | --popup-animation-speed: var(--animation-duration-slow); | ||
| 43 | } | ||
| 44 | |||
| 45 | .popup--animation-none { | ||
| 46 | --popup-animation-speed: 0ms; | ||
| 47 | } | ||
| 40 | 48 | ||
| 41 | /* Styling of main popup elements */ | 49 | /* Styling of main popup elements */ |
| 42 | .popup .popup-body { | 50 | .popup .popup-body { |
| @@ -190,4 +198,3 @@ body.no-blur .popup[open]::backdrop { | |||
| 190 | /* Fix weird animation issue with font-scaling during popup open */ | 198 | /* Fix weird animation issue with font-scaling during popup open */ |
| 191 | backface-visibility: hidden; | 199 | backface-visibility: hidden; |
| 192 | } | 200 | } |
| 193 | |||
| @@ -359,10 +359,15 @@ | |||
| 359 | content: attr(external_piece_text); | 359 | content: attr(external_piece_text); |
| 360 | display: block; | 360 | display: block; |
| 361 | width: 100%; | 361 | width: 100%; |
| 362 | font-weight: 600; | 362 | font-weight: 500; |
| 363 | text-align: center; | 363 | text-align: center; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | .completion_prompt_manager_popup_entry_form_control #completion_prompt_manager_popup_entry_form_prompt:disabled { | 366 | .completion_prompt_manager_popup_entry_form_control #completion_prompt_manager_popup_entry_form_prompt:disabled { |
| 367 | visibility: hidden; | 367 | visibility: hidden; |
| 368 | } | 368 | } |
| 369 | |||
| 370 | #completion_prompt_manager_popup_entry_source_block { | ||
| 371 | display: flex; | ||
| 372 | justify-content: center; | ||
| 373 | } | ||
| @@ -87,7 +87,7 @@ | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | #rm_group_members:empty::before { | 89 | #rm_group_members:empty::before { |
| 90 | content: 'Group is empty'; | 90 | content: attr(group_empty_text); |
| 91 | 91 | ||
| 92 | font-weight: bolder; | 92 | font-weight: bolder; |
| 93 | width: 100%; | 93 | width: 100%; |
| @@ -115,7 +115,7 @@ | |||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | #rm_group_add_members:empty::before { | 117 | #rm_group_add_members:empty::before { |
| 118 | content: 'No characters available'; | 118 | content: attr(no_characters_text); |
| 119 | 119 | ||
| 120 | font-weight: bolder; | 120 | font-weight: bolder; |
| 121 | width: 100%; | 121 | width: 100%; |
| @@ -1,7 +1,10 @@ | |||
| 1 | .scrollable-buttons-container { | 1 | .scrollable-buttons-container { |
| 2 | max-height: 50vh; /* Use viewport height instead of fixed pixels */ | 2 | /* Use viewport height instead of fixed pixels */ |
| 3 | -webkit-overflow-scrolling: touch; /* Momentum scrolling on iOS */ | 3 | max-height: 50vh; |
| 4 | margin-top: 1rem; /* m-t-1 is equivalent to margin-top: 1rem; */ | 4 | /* Momentum scrolling on iOS */ |
| 5 | -webkit-overflow-scrolling: touch; | ||
| 6 | /* m-t-1 is equivalent to margin-top: 1rem; */ | ||
| 7 | margin-top: 1rem; | ||
| 5 | flex-shrink: 1; | 8 | flex-shrink: 1; |
| 6 | min-height: 0; | 9 | min-height: 0; |
| 7 | scrollbar-width: thin; | 10 | scrollbar-width: thin; |
| @@ -211,6 +211,7 @@ | |||
| 211 | 211 | ||
| 212 | .tag_as_folder.right_menu_button { | 212 | .tag_as_folder.right_menu_button { |
| 213 | filter: brightness(75%) saturate(0.6); | 213 | filter: brightness(75%) saturate(0.6); |
| 214 | margin-right: 5px; | ||
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | .tag_as_folder.right_menu_button:hover, | 217 | .tag_as_folder.right_menu_button:hover, |
| @@ -45,6 +45,11 @@ body.square-avatars .avatar img { | |||
| 45 | border-radius: var(--avatar-base-border-radius) !important; | 45 | border-radius: var(--avatar-base-border-radius) !important; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | body.rounded-avatars .avatar, | ||
| 49 | body.rounded-avatars .avatar img { | ||
| 50 | border-radius: var(--avatar-base-border-radius-rounded) !important; | ||
| 51 | } | ||
| 52 | |||
| 48 | /*char list grid mode*/ | 53 | /*char list grid mode*/ |
| 49 | 54 | ||
| 50 | body.charListGrid #rm_print_characters_block { | 55 | body.charListGrid #rm_print_characters_block { |
| @@ -226,6 +231,7 @@ body.big-avatars .avatars_inline_small .avatar img { | |||
| 226 | body.big-avatars .avatars_inline { | 231 | body.big-avatars .avatars_inline { |
| 227 | max-height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) + 2 * var(--avatar-base-border-radius)); | 232 | max-height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) + 2 * var(--avatar-base-border-radius)); |
| 228 | } | 233 | } |
| 234 | |||
| 229 | body.big-avatars .avatars_inline.avatars_multiline { | 235 | body.big-avatars .avatars_inline.avatars_multiline { |
| 230 | max-height: fit-content; | 236 | max-height: fit-content; |
| 231 | } | 237 | } |
| @@ -233,6 +239,7 @@ body.big-avatars .avatars_inline.avatars_multiline { | |||
| 233 | body.big-avatars .avatars_inline.avatars_inline_small { | 239 | body.big-avatars .avatars_inline.avatars_inline_small { |
| 234 | height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) * var(--inline-avatar-small-factor) + 2 * var(--avatar-base-border-radius)); | 240 | height: calc(var(--avatar-base-height) * var(--big-avatar-height-factor) * var(--inline-avatar-small-factor) + 2 * var(--avatar-base-border-radius)); |
| 235 | } | 241 | } |
| 242 | |||
| 236 | body.big-avatars .avatars_inline.avatars_inline_small.avatars_multiline { | 243 | body.big-avatars .avatars_inline.avatars_inline_small.avatars_multiline { |
| 237 | height: inherit; | 244 | height: inherit; |
| 238 | } | 245 | } |
| @@ -339,10 +346,15 @@ body.documentstyle #chat .last_mes .swipe_left { | |||
| 339 | body.documentstyle #chat .mes .mesAvatarWrapper, | 346 | body.documentstyle #chat .mes .mesAvatarWrapper, |
| 340 | body.documentstyle #chat .mes .mes_block .ch_name .name_text, | 347 | body.documentstyle #chat .mes .mes_block .ch_name .name_text, |
| 341 | body.documentstyle #chat .mes .mes_block .ch_name .timestamp, | 348 | body.documentstyle #chat .mes .mes_block .ch_name .timestamp, |
| 349 | body.documentstyle #chat .mes .mes_block .ch_name .timestamp-icon, | ||
| 342 | body.documentstyle .mes:not(.last_mes) .ch_name .mes_buttons { | 350 | body.documentstyle .mes:not(.last_mes) .ch_name .mes_buttons { |
| 343 | display: none !important; | 351 | display: none !important; |
| 344 | } | 352 | } |
| 345 | 353 | ||
| 354 | body.documentstyle #chat .mes_block .ch_name { | ||
| 355 | min-height: unset; | ||
| 356 | } | ||
| 357 | |||
| 346 | /*FastUI blur removal*/ | 358 | /*FastUI blur removal*/ |
| 347 | 359 | ||
| 348 | body.no-blur * { | 360 | body.no-blur * { |
| @@ -498,3 +510,15 @@ label[for="trim_spaces"]:not(:has(input:checked)) small { | |||
| 498 | #banned_tokens_block_ooba:not(:has(#send_banned_tokens_textgenerationwebui:checked)) #banned_tokens_controls_ooba { | 510 | #banned_tokens_block_ooba:not(:has(#send_banned_tokens_textgenerationwebui:checked)) #banned_tokens_controls_ooba { |
| 499 | filter: brightness(0.5); | 511 | filter: brightness(0.5); |
| 500 | } | 512 | } |
| 513 | |||
| 514 | #bind_preset_to_connection:checked~.toggleOff { | ||
| 515 | display: none; | ||
| 516 | } | ||
| 517 | |||
| 518 | #bind_preset_to_connection:not(:checked)~.toggleOn { | ||
| 519 | display: none; | ||
| 520 | } | ||
| 521 | |||
| 522 | label[for="bind_preset_to_connection"]:has(input:checked) { | ||
| 523 | color: var(--active); | ||
| 524 | } | ||
| @@ -0,0 +1,213 @@ | |||
| 1 | #chat .mes[type="assistant_message"] .mes_button { | ||
| 2 | display: none; | ||
| 3 | } | ||
| 4 | |||
| 5 | .welcomePanel { | ||
| 6 | display: flex; | ||
| 7 | flex-direction: column; | ||
| 8 | gap: 5px; | ||
| 9 | padding: 10px; | ||
| 10 | width: 100%; | ||
| 11 | } | ||
| 12 | |||
| 13 | .welcomePanel:has(.showMoreChats) { | ||
| 14 | padding-bottom: 5px; | ||
| 15 | } | ||
| 16 | |||
| 17 | .welcomePanel.recentHidden .welcomeRecent, | ||
| 18 | .welcomePanel.recentHidden .recentChatsTitle, | ||
| 19 | .welcomePanel.recentHidden .hideRecentChats, | ||
| 20 | .welcomePanel:not(.recentHidden) .showRecentChats { | ||
| 21 | display: none; | ||
| 22 | } | ||
| 23 | |||
| 24 | body.bubblechat .welcomePanel { | ||
| 25 | border-radius: 10px; | ||
| 26 | background-color: var(--SmartThemeBotMesBlurTintColor); | ||
| 27 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 28 | margin-bottom: 5px; | ||
| 29 | } | ||
| 30 | |||
| 31 | body.hideChatAvatars .welcomePanel .recentChatList .recentChat .avatar { | ||
| 32 | display: none; | ||
| 33 | } | ||
| 34 | |||
| 35 | .welcomePanel .welcomeHeader { | ||
| 36 | display: flex; | ||
| 37 | flex-direction: row; | ||
| 38 | align-items: center; | ||
| 39 | justify-content: flex-end; | ||
| 40 | } | ||
| 41 | |||
| 42 | .welcomePanel .recentChatsTitle { | ||
| 43 | flex-grow: 1; | ||
| 44 | font-size: calc(var(--mainFontSize) * 1.15); | ||
| 45 | font-weight: 600; | ||
| 46 | } | ||
| 47 | |||
| 48 | .welcomePanel .welcomeHeaderTitle { | ||
| 49 | margin: 0; | ||
| 50 | flex-grow: 1; | ||
| 51 | display: flex; | ||
| 52 | flex-direction: row; | ||
| 53 | align-items: center; | ||
| 54 | gap: 10px; | ||
| 55 | } | ||
| 56 | |||
| 57 | .welcomePanel .welcomeHeaderVersionDisplay { | ||
| 58 | font-size: calc(var(--mainFontSize) * 1.3); | ||
| 59 | font-weight: 600; | ||
| 60 | flex-grow: 1; | ||
| 61 | } | ||
| 62 | |||
| 63 | .welcomePanel .welcomeHeaderLogo { | ||
| 64 | width: 30px; | ||
| 65 | height: 30px; | ||
| 66 | } | ||
| 67 | |||
| 68 | .welcomePanel .welcomeShortcuts { | ||
| 69 | display: flex; | ||
| 70 | flex-direction: row; | ||
| 71 | flex-wrap: wrap; | ||
| 72 | align-items: center; | ||
| 73 | justify-content: center; | ||
| 74 | gap: 5px; | ||
| 75 | } | ||
| 76 | |||
| 77 | .welcomePanel .welcomeShortcuts .welcomeShortcutsSeparator { | ||
| 78 | margin: 0 2px; | ||
| 79 | color: var(--SmartThemeBorderColor); | ||
| 80 | font-size: calc(var(--mainFontSize) * 1.1); | ||
| 81 | } | ||
| 82 | |||
| 83 | .welcomeRecent .recentChatList { | ||
| 84 | display: flex; | ||
| 85 | flex-direction: column; | ||
| 86 | width: 100%; | ||
| 87 | gap: 2px; | ||
| 88 | } | ||
| 89 | |||
| 90 | .welcomeRecent .welcomePanelLoader { | ||
| 91 | display: flex; | ||
| 92 | justify-content: center; | ||
| 93 | align-items: center; | ||
| 94 | flex: 1; | ||
| 95 | width: 100%; | ||
| 96 | height: 100%; | ||
| 97 | position: absolute; | ||
| 98 | } | ||
| 99 | |||
| 100 | .welcomePanel .recentChatList .noRecentChat { | ||
| 101 | display: flex; | ||
| 102 | flex-direction: row; | ||
| 103 | justify-content: center; | ||
| 104 | align-items: baseline; | ||
| 105 | gap: 5px; | ||
| 106 | padding: 10px; | ||
| 107 | } | ||
| 108 | |||
| 109 | .welcomeRecent .recentChatList .recentChat { | ||
| 110 | display: flex; | ||
| 111 | flex-direction: row; | ||
| 112 | align-items: center; | ||
| 113 | padding: 5px 10px; | ||
| 114 | border-radius: 10px; | ||
| 115 | cursor: pointer; | ||
| 116 | gap: 10px; | ||
| 117 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 118 | } | ||
| 119 | |||
| 120 | .welcomeRecent .recentChatList .recentChat .avatar { | ||
| 121 | flex: 0; | ||
| 122 | align-self: center; | ||
| 123 | } | ||
| 124 | |||
| 125 | .welcomeRecent .recentChatList .recentChat:hover { | ||
| 126 | background-color: var(--white30a); | ||
| 127 | } | ||
| 128 | |||
| 129 | .welcomeRecent .recentChatList .recentChat .recentChatInfo { | ||
| 130 | display: flex; | ||
| 131 | flex-direction: column; | ||
| 132 | flex-wrap: nowrap; | ||
| 133 | flex-grow: 1; | ||
| 134 | overflow: hidden; | ||
| 135 | justify-content: center; | ||
| 136 | align-self: flex-start; | ||
| 137 | } | ||
| 138 | |||
| 139 | .welcomeRecent .recentChatList .recentChat .chatNameContainer { | ||
| 140 | display: flex; | ||
| 141 | flex-direction: row; | ||
| 142 | justify-content: space-between; | ||
| 143 | align-items: baseline; | ||
| 144 | font-size: calc(var(--mainFontSize) * 1); | ||
| 145 | } | ||
| 146 | |||
| 147 | .welcomeRecent .recentChatList .recentChat .chatNameContainer .chatName { | ||
| 148 | white-space: nowrap; | ||
| 149 | text-overflow: ellipsis; | ||
| 150 | overflow: hidden; | ||
| 151 | } | ||
| 152 | |||
| 153 | .welcomeRecent .recentChatList .recentChat .chatMessageContainer { | ||
| 154 | display: flex; | ||
| 155 | flex-direction: row; | ||
| 156 | align-items: center; | ||
| 157 | justify-content: space-between; | ||
| 158 | gap: 5px; | ||
| 159 | font-size: calc(var(--mainFontSize) * 0.85); | ||
| 160 | } | ||
| 161 | |||
| 162 | .welcomeRecent .recentChatList .recentChat .chatMessageContainer .chatMessage { | ||
| 163 | display: -webkit-box; | ||
| 164 | -webkit-box-orient: vertical; | ||
| 165 | -webkit-line-clamp: 2; | ||
| 166 | line-clamp: 2; | ||
| 167 | overflow: hidden; | ||
| 168 | } | ||
| 169 | |||
| 170 | body.big-avatars .welcomeRecent .recentChatList .recentChat .chatMessageContainer .chatMessage { | ||
| 171 | -webkit-line-clamp: 4; | ||
| 172 | line-clamp: 4; | ||
| 173 | } | ||
| 174 | |||
| 175 | .welcomeRecent .recentChatList .recentChat .chatStats { | ||
| 176 | display: flex; | ||
| 177 | flex-direction: row; | ||
| 178 | justify-content: flex-end; | ||
| 179 | align-items: baseline; | ||
| 180 | align-self: flex-start; | ||
| 181 | gap: 5px; | ||
| 182 | } | ||
| 183 | |||
| 184 | .welcomeRecent .recentChatList .recentChat .chatStats .counterBlock { | ||
| 185 | display: flex; | ||
| 186 | flex-direction: row; | ||
| 187 | align-items: baseline; | ||
| 188 | gap: 5px; | ||
| 189 | } | ||
| 190 | |||
| 191 | .welcomeRecent .recentChatList .recentChat .chatStats .counterBlock::after { | ||
| 192 | content: "|"; | ||
| 193 | color: var(--SmartThemeBorderColor); | ||
| 194 | font-size: calc(var(--mainFontSize) * 0.95); | ||
| 195 | } | ||
| 196 | |||
| 197 | .welcomeRecent .recentChatList .recentChat.hidden { | ||
| 198 | display: none; | ||
| 199 | } | ||
| 200 | |||
| 201 | .welcomeRecent .recentChatList .showMoreChats { | ||
| 202 | align-self: center; | ||
| 203 | } | ||
| 204 | |||
| 205 | .welcomeRecent .recentChatList .showMoreChats.rotated { | ||
| 206 | transform: rotate(180deg); | ||
| 207 | } | ||
| 208 | |||
| 209 | @media screen and (max-width: 1000px) { | ||
| 210 | .welcomePanel .welcomeShortcuts a span { | ||
| 211 | display: none; | ||
| 212 | } | ||
| 213 | } | ||
| @@ -124,6 +124,10 @@ | |||
| 124 | cursor: initial; | 124 | cursor: initial; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | .world_entry .inline-drawer-header-pointer { | ||
| 128 | cursor: pointer; | ||
| 129 | } | ||
| 130 | |||
| 127 | .world_entry .killSwitch { | 131 | .world_entry .killSwitch { |
| 128 | cursor: pointer; | 132 | cursor: pointer; |
| 129 | } | 133 | } |
| @@ -55,4 +55,15 @@ declare global { | |||
| 55 | * @param provider Translation provider | 55 | * @param provider Translation provider |
| 56 | */ | 56 | */ |
| 57 | async function translate(text: string, lang: string, provider: string = null): Promise<string>; | 57 | async function translate(text: string, lang: string, provider: string = null): Promise<string>; |
| 58 | |||
| 59 | interface ConvertVideoArgs { | ||
| 60 | buffer: Uint8Array; | ||
| 61 | name: string; | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Converts a video file to an animated WebP format using FFmpeg. | ||
| 66 | * @param args - The arguments for the conversion function. | ||
| 67 | */ | ||
| 68 | function convertVideoToAnimatedWebp(args: ConvertVideoArgs): Promise<Uint8Array>; | ||
| 58 | } | 69 | } |
| @@ -0,0 +1 @@ | |||
| 1 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="83.349 83.3488 333.396 333.395" width="333.396px" height="333.395px"><path d="M 246.799 88.148 C 237.605 99.343 230.641 107.833 225.288 114.438 C 219.934 121.04 216.192 125.76 213.443 129.413 C 210.694 133.068 208.937 135.657 207.555 138.004 C 206.173 140.351 205.166 142.451 203.918 145.134 C 203.529 145.968 203.154 146.767 202.809 147.499 C 202.464 148.229 202.148 148.895 201.878 149.459 C 201.608 150.023 201.384 150.483 201.222 150.812 C 201.06 151.139 200.96 151.332 200.939 151.353 C 200.919 151.375 200.764 151.356 200.506 151.3 C 200.246 151.244 199.879 151.153 199.436 151.037 C 198.991 150.917 198.469 150.773 197.892 150.603 C 197.317 150.436 196.689 150.247 196.036 150.046 C 193.038 149.119 190.766 148.419 188.573 147.896 C 186.381 147.37 184.269 147.017 181.59 146.781 C 178.913 146.546 175.671 146.422 171.216 146.362 C 166.763 146.297 161.1 146.294 153.58 146.292 L 146.676 146.288 L 139.771 146.285 L 132.866 146.285 L 125.963 146.282 L 125.963 161.225 L 125.963 176.168 L 125.963 191.11 L 125.963 206.054 L 124.505 206.222 L 123.043 206.394 L 121.58 206.565 L 120.123 206.739 C 118.48 206.931 116.775 207.193 115.008 207.526 C 113.241 207.858 111.416 208.259 109.537 208.733 C 107.656 209.205 105.722 209.74 103.738 210.348 C 101.755 210.954 99.725 211.627 97.647 212.364 C 96.339 212.83 94.795 213.413 93.208 214.032 C 91.621 214.654 90 215.308 88.538 215.915 C 87.078 216.521 85.78 217.079 84.849 217.507 C 83.916 217.933 83.349 218.228 83.349 218.304 C 83.349 218.42 83.547 218.985 83.877 219.854 C 84.21 220.722 84.681 221.891 85.224 223.212 C 85.766 224.536 86.385 226.012 87.016 227.493 C 87.65 228.973 88.298 230.46 88.895 231.803 C 92.249 239.318 96.203 246.526 100.658 253.31 C 105.109 260.093 110.057 266.454 115.394 272.272 C 120.73 278.09 126.455 283.367 132.461 287.984 C 138.465 292.602 144.751 296.561 151.21 299.743 C 154.416 301.323 157.57 302.733 160.7 303.984 C 163.828 305.234 166.929 306.324 170.027 307.259 C 173.121 308.195 176.211 308.975 179.318 309.607 C 182.422 310.239 185.543 310.723 188.7 311.066 C 191.033 311.319 193.65 311.47 196.411 311.526 C 199.175 311.58 202.086 311.54 205.006 311.41 C 207.923 311.28 210.852 311.059 213.651 310.756 C 216.452 310.453 219.124 310.065 221.53 309.602 C 222.605 309.396 223.636 309.202 224.579 309.032 C 225.521 308.86 226.377 308.712 227.1 308.591 C 227.825 308.472 228.417 308.38 228.834 308.325 C 229.253 308.271 229.495 308.252 229.52 308.277 C 229.639 308.401 229.468 308.844 229.097 309.479 C 228.727 310.113 228.16 310.942 227.484 311.844 C 226.807 312.746 226.024 313.719 225.224 314.643 C 224.423 315.568 223.606 316.443 222.867 317.146 C 221.275 318.657 219.615 319.961 217.836 321.079 C 216.055 322.197 214.155 323.128 212.083 323.891 C 210.01 324.654 207.767 325.248 205.3 325.694 C 202.832 326.139 200.141 326.437 197.175 326.604 C 193.395 326.816 189.994 327.211 186.887 327.829 C 183.779 328.444 180.965 329.279 178.358 330.369 C 175.752 331.46 173.355 332.803 171.08 334.439 C 168.806 336.074 166.656 338 164.545 340.251 C 163.003 341.894 161.632 343.591 160.417 345.379 C 159.202 347.155 158.141 349.036 157.218 351.03 C 156.299 353.03 155.514 355.155 154.851 357.438 C 154.187 359.726 153.647 362.172 153.207 364.827 C 153.04 365.842 152.913 366.599 152.77 367.206 C 152.629 367.806 152.477 368.253 152.26 368.612 C 152.039 368.982 151.76 369.267 151.359 369.577 C 150.959 369.876 150.447 370.191 149.76 370.613 C 146.959 372.322 144.585 374.482 142.688 376.955 C 140.791 379.425 139.371 382.199 138.474 385.12 C 137.578 388.043 137.204 391.112 137.403 394.171 C 137.604 397.235 138.377 400.285 139.767 403.172 C 140.861 405.439 142.364 407.507 144.142 409.321 C 145.922 411.128 147.979 412.675 150.17 413.873 C 152.363 415.081 154.697 415.943 157.03 416.386 C 159.365 416.839 161.698 416.875 163.895 416.418 C 164.949 416.196 166.066 415.865 167.196 415.439 C 168.328 415.022 169.477 414.508 170.59 413.938 C 171.704 413.364 172.786 412.725 173.788 412.048 C 174.788 411.367 175.707 410.655 176.498 409.921 C 178.133 408.414 179.505 406.573 180.589 404.517 C 181.676 402.458 182.476 400.186 182.966 397.809 C 183.455 395.427 183.639 392.941 183.488 390.468 C 183.336 387.983 182.855 385.516 182.015 383.162 C 181.582 381.95 180.935 380.688 180.125 379.438 C 179.315 378.191 178.341 376.955 177.262 375.785 C 176.185 374.625 174.998 373.524 173.755 372.556 C 172.515 371.586 171.22 370.754 169.926 370.097 C 168.776 369.515 167.913 369.078 167.286 368.673 C 166.659 368.268 166.268 367.888 166.061 367.416 C 165.854 366.955 165.831 366.396 165.939 365.633 C 166.049 364.866 166.289 363.903 166.61 362.606 C 167.239 360.073 168.181 357.677 169.396 355.447 C 170.611 353.217 172.097 351.164 173.814 349.33 C 175.528 347.5 177.474 345.885 179.607 344.542 C 181.739 343.195 184.058 342.114 186.521 341.341 C 186.953 341.205 187.6 341.061 188.405 340.918 C 189.209 340.774 190.17 340.632 191.23 340.497 C 192.288 340.361 193.447 340.231 194.643 340.119 C 195.841 340.003 197.079 339.906 198.295 339.827 C 201.179 339.647 203.718 339.414 206.01 339.104 C 208.301 338.796 210.345 338.408 212.239 337.919 C 214.133 337.43 215.877 336.839 217.568 336.12 C 219.258 335.404 220.895 334.56 222.575 333.563 C 224.387 332.489 226.003 331.431 227.5 330.319 C 228.997 329.208 230.375 328.042 231.706 326.75 C 233.036 325.458 234.32 324.041 235.631 322.425 C 236.941 320.811 238.279 318.999 239.716 316.919 L 240.575 315.675 L 241.434 314.431 L 242.295 313.186 L 243.154 311.942 L 243.154 326.201 L 243.154 340.461 L 243.154 354.718 L 243.154 368.982 L 242.045 369.749 L 240.935 370.52 L 239.826 371.287 L 238.717 372.06 C 237.028 373.232 235.59 374.381 234.363 375.574 C 233.136 376.776 232.119 378.012 231.271 379.369 C 230.425 380.723 229.744 382.188 229.194 383.828 C 228.644 385.475 228.221 387.29 227.883 389.357 C 227.479 391.83 227.522 394.366 227.954 396.838 C 228.384 399.312 229.204 401.725 230.354 403.963 C 231.502 406.2 232.982 408.267 234.729 410.037 C 236.476 411.812 238.496 413.299 240.725 414.378 C 242.961 415.451 245.261 416.147 247.564 416.456 C 249.866 416.765 252.172 416.695 254.42 416.259 C 256.67 415.821 258.86 415.016 260.936 413.85 C 263.011 412.685 264.971 411.168 266.752 409.303 C 267.88 408.125 268.805 407.004 269.558 405.869 C 270.312 404.73 270.893 403.56 271.335 402.289 C 271.779 401.005 272.081 399.612 272.276 398.009 C 272.469 396.41 272.555 394.602 272.563 392.497 C 272.57 390.978 272.569 389.795 272.536 388.827 C 272.504 387.847 272.44 387.086 272.323 386.397 C 272.208 385.705 272.038 385.089 271.792 384.412 C 271.547 383.734 271.226 382.997 270.806 382.07 C 270.242 380.813 269.59 379.645 268.853 378.552 C 268.115 377.458 267.292 376.441 266.385 375.504 C 265.476 374.575 264.482 373.72 263.404 372.943 C 262.327 372.17 261.164 371.474 259.918 370.858 L 258.956 370.387 L 257.997 369.912 L 257.034 369.443 L 256.073 368.964 L 256.069 361.769 L 256.067 354.564 L 256.064 347.36 L 256.061 340.163 C 256.059 336.205 256.072 332.439 256.094 329.025 C 256.116 325.612 256.15 322.547 256.192 319.988 C 256.233 317.43 256.282 315.375 256.339 313.979 C 256.395 312.583 256.457 311.846 256.52 311.925 C 256.586 312.001 256.737 312.211 256.957 312.525 C 257.177 312.839 257.463 313.255 257.799 313.747 C 258.134 314.24 258.514 314.803 258.923 315.413 C 259.33 316.023 259.767 316.677 260.21 317.345 C 261.259 318.93 262.251 320.334 263.231 321.608 C 264.21 322.884 265.181 324.03 266.189 325.097 C 267.199 326.165 268.243 327.152 269.376 328.113 C 270.508 329.075 271.726 330.008 273.076 330.964 C 275.237 332.493 277.247 333.763 279.249 334.822 C 281.25 335.88 283.244 336.729 285.372 337.409 C 287.499 338.088 289.763 338.603 292.306 338.994 C 294.847 339.391 297.667 339.661 300.908 339.859 C 302.102 339.933 303.315 340.021 304.482 340.117 C 305.649 340.212 306.771 340.317 307.787 340.422 C 308.804 340.531 309.713 340.637 310.456 340.741 C 311.2 340.842 311.775 340.944 312.123 341.031 C 314.804 341.716 317.399 342.888 319.797 344.43 C 322.195 345.971 324.398 347.874 326.3 350.033 C 328.2 352.182 329.795 354.583 330.987 357.111 C 332.176 359.636 332.954 362.288 333.219 364.942 L 333.311 365.851 L 333.4 366.755 L 333.487 367.664 L 333.577 368.57 L 332.828 368.973 L 332.08 369.369 L 331.331 369.766 L 330.58 370.171 C 328.268 371.397 326.239 372.85 324.51 374.503 C 322.782 376.157 321.349 378.012 320.228 380.046 C 319.108 382.076 318.298 384.294 317.809 386.655 C 317.321 389.026 317.161 391.537 317.332 394.194 C 317.514 396.986 318.125 399.626 319.11 402.047 C 320.093 404.473 321.455 406.682 323.135 408.609 C 324.812 410.535 326.813 412.191 329.079 413.492 C 331.346 414.804 333.877 415.771 336.617 416.34 C 340.253 417.085 343.896 416.704 347.28 415.477 C 350.658 414.247 353.773 412.16 356.353 409.511 C 358.941 406.853 360.988 403.623 362.234 400.105 C 363.484 396.582 363.929 392.762 363.303 388.924 C 362.986 386.999 362.469 385.132 361.769 383.362 C 361.063 381.582 360.179 379.902 359.126 378.334 C 358.078 376.779 356.865 375.337 355.511 374.047 C 354.153 372.762 352.659 371.629 351.044 370.681 C 350.548 370.39 350.073 370.101 349.631 369.823 C 349.186 369.544 348.781 369.287 348.427 369.052 C 348.074 368.816 347.784 368.608 347.563 368.445 C 347.35 368.279 347.213 368.156 347.174 368.089 C 347.136 368.028 347.076 367.839 347.002 367.559 C 346.926 367.279 346.841 366.906 346.738 366.472 C 346.641 366.033 346.533 365.524 346.426 364.982 C 346.319 364.434 346.202 363.845 346.093 363.251 C 345.827 361.805 345.469 360.28 345.026 358.734 C 344.585 357.193 344.07 355.622 343.499 354.103 C 342.926 352.579 342.301 351.092 341.649 349.713 C 340.989 348.331 340.301 347.057 339.606 345.941 C 338.365 343.951 336.881 342.049 335.214 340.264 C 333.55 338.488 331.694 336.833 329.706 335.343 C 327.721 333.854 325.599 332.529 323.396 331.407 C 321.193 330.286 318.908 329.368 316.592 328.692 C 315.968 328.51 315.181 328.325 314.274 328.149 C 313.368 327.97 312.343 327.796 311.24 327.635 C 310.135 327.472 308.952 327.322 307.73 327.188 C 306.509 327.055 305.25 326.938 303.992 326.845 C 302.835 326.758 301.629 326.652 300.44 326.533 C 299.251 326.415 298.077 326.285 296.986 326.151 C 295.893 326.015 294.886 325.877 294.026 325.743 C 293.163 325.608 292.45 325.478 291.951 325.359 C 290.551 325.028 289.144 324.58 287.755 324.032 C 286.368 323.482 284.996 322.832 283.67 322.094 C 282.343 321.357 281.061 320.531 279.845 319.631 C 278.63 318.731 277.484 317.757 276.431 316.723 C 275.528 315.836 274.654 314.903 273.863 313.989 C 273.069 313.075 272.358 312.184 271.778 311.386 C 271.197 310.585 270.749 309.877 270.482 309.33 C 270.215 308.783 270.132 308.398 270.279 308.242 C 270.319 308.199 270.599 308.205 271.069 308.254 C 271.539 308.302 272.201 308.388 273.006 308.512 C 273.81 308.633 274.756 308.789 275.797 308.972 C 276.837 309.155 277.971 309.361 279.151 309.589 C 281.082 309.962 282.663 310.252 284.125 310.478 C 285.586 310.702 286.929 310.864 288.385 310.98 C 289.843 311.095 291.412 311.165 293.33 311.207 C 295.246 311.249 297.507 311.264 300.348 311.27 C 303.731 311.276 306.472 311.257 308.843 311.18 C 311.214 311.103 313.217 310.969 315.118 310.744 C 317.024 310.519 318.828 310.203 320.809 309.766 C 322.789 309.328 324.942 308.768 327.542 308.055 C 332.681 306.644 337.629 304.941 342.407 302.934 C 347.183 300.926 351.786 298.616 356.237 295.996 C 360.679 293.374 364.967 290.442 369.116 287.188 C 373.258 283.937 377.262 280.363 381.138 276.462 C 384.43 273.143 387.487 269.801 390.337 266.384 C 393.193 262.965 395.853 259.47 398.333 255.848 C 400.816 252.227 403.137 248.477 405.327 244.549 C 407.513 240.621 409.562 236.514 411.525 232.177 C 412.561 229.876 413.445 227.881 414.159 226.174 C 414.883 224.465 415.448 223.047 415.864 221.895 C 416.273 220.745 416.543 219.863 416.662 219.23 C 416.79 218.598 416.766 218.215 416.617 218.065 C 416.403 217.855 415.469 217.39 414.106 216.784 C 412.749 216.177 410.956 215.431 409.029 214.662 C 407.111 213.893 405.047 213.1 403.143 212.404 C 401.237 211.7 399.492 211.096 398.191 210.7 C 396.677 210.239 395.049 209.785 393.395 209.353 C 391.728 208.922 390.04 208.513 388.387 208.145 C 386.734 207.78 385.125 207.449 383.627 207.179 C 382.127 206.908 380.746 206.695 379.552 206.553 L 378.67 206.449 L 377.799 206.345 L 376.92 206.242 L 376.049 206.139 L 376.049 191.175 L 376.049 176.209 L 376.049 161.245 L 376.049 146.282 L 369.208 146.288 L 362.377 146.294 L 355.542 146.3 L 348.71 146.305 C 341.359 146.316 335.755 146.325 331.3 146.393 C 326.842 146.461 323.533 146.582 320.775 146.808 C 318.016 147.032 315.807 147.359 313.553 147.835 C 311.298 148.315 308.996 148.944 306.05 149.775 C 305.408 149.956 304.791 150.123 304.223 150.27 C 303.656 150.416 303.14 150.545 302.701 150.646 C 302.263 150.75 301.902 150.821 301.644 150.865 C 301.384 150.909 301.232 150.919 301.208 150.892 C 301.185 150.865 301.079 150.664 300.909 150.329 C 300.739 149.991 300.505 149.516 300.222 148.939 C 299.941 148.362 299.611 147.679 299.251 146.929 C 298.889 146.183 298.499 145.366 298.094 144.516 C 296.849 141.904 295.91 139.934 294.85 138.024 C 293.792 136.115 292.615 134.263 290.896 131.882 C 289.177 129.5 286.916 126.595 283.689 122.568 C 280.463 118.545 276.269 113.409 270.689 106.572 C 266.798 101.8 263.658 97.966 261.13 94.892 C 258.6 91.819 256.681 89.508 255.231 87.798 C 253.782 86.083 252.8 84.967 252.148 84.281 C 251.494 83.597 251.168 83.34 251.03 83.349 C 250.988 83.351 250.839 83.488 250.602 83.734 C 250.365 83.978 250.045 84.33 249.661 84.765 C 249.277 85.2 248.832 85.719 248.346 86.291 C 247.861 86.861 247.338 87.491 246.799 88.148 M 266.415 121.571 C 270.276 126.312 273.576 130.479 276.367 134.164 C 279.161 137.852 281.446 141.053 283.281 143.861 C 285.116 146.665 286.5 149.073 287.489 151.167 C 288.478 153.261 289.071 155.042 289.325 156.6 C 289.391 157.001 289.427 157.324 289.406 157.608 C 289.387 157.891 289.312 158.132 289.156 158.371 C 288.999 158.614 288.764 158.85 288.422 159.121 C 288.081 159.394 287.635 159.704 287.057 160.086 C 286.13 160.701 284.911 161.698 283.538 162.934 C 282.166 164.169 280.642 165.642 279.106 167.213 C 277.57 168.782 276.02 170.446 274.598 172.064 C 273.176 173.682 271.881 175.253 270.852 176.635 C 269.742 178.128 268.593 179.804 267.454 181.582 C 266.313 183.359 265.182 185.239 264.108 187.135 C 263.031 189.033 262.014 190.945 261.098 192.793 C 260.183 194.64 259.372 196.421 258.712 198.054 C 257.763 200.401 256.843 203.065 255.996 205.859 C 255.15 208.65 254.379 211.569 253.725 214.423 C 253.07 217.278 252.534 220.067 252.159 222.599 C 251.786 225.133 251.572 227.407 251.565 229.235 C 251.559 231.007 251.505 232.294 251.409 233.097 C 251.313 233.901 251.172 234.221 250.988 234.059 C 250.805 233.896 250.578 233.251 250.308 232.123 C 250.039 230.997 249.728 229.388 249.375 227.297 C 248.928 224.65 248.419 221.945 247.871 219.288 C 247.324 216.629 246.741 214.02 246.144 211.567 C 245.548 209.108 244.941 206.809 244.349 204.765 C 243.755 202.725 243.176 200.941 242.636 199.525 C 242.096 198.111 241.387 196.463 240.57 194.704 C 239.751 192.947 238.827 191.079 237.856 189.225 C 236.887 187.368 235.876 185.527 234.884 183.818 C 233.891 182.112 232.922 180.542 232.034 179.229 C 231.241 178.051 230.127 176.6 228.825 175.023 C 227.525 173.446 226.04 171.74 224.505 170.059 C 222.969 168.38 221.388 166.72 219.895 165.239 C 218.402 163.755 216.997 162.448 215.818 161.464 C 215.336 161.059 214.877 160.657 214.458 160.269 C 214.038 159.881 213.662 159.514 213.344 159.185 C 213.026 158.855 212.769 158.564 212.591 158.328 C 212.412 158.094 212.315 157.918 212.315 157.821 C 212.315 157.515 212.586 156.721 213.037 155.637 C 213.488 154.55 214.117 153.171 214.832 151.693 C 215.545 150.216 216.346 148.636 217.135 147.152 C 217.926 145.667 218.707 144.278 219.388 143.171 C 220.106 142.009 220.79 140.942 221.523 139.864 C 222.255 138.785 223.035 137.697 223.945 136.49 C 224.854 135.283 225.892 133.959 227.139 132.41 C 228.388 130.863 229.845 129.087 231.591 126.978 C 232.242 126.195 233.071 125.195 234.012 124.055 C 234.953 122.912 236.008 121.635 237.109 120.301 C 238.209 118.966 239.355 117.572 240.481 116.204 C 241.608 114.835 242.714 113.49 243.733 112.249 L 245.587 109.989 L 247.441 107.734 L 249.294 105.474 L 251.148 103.218 L 251.468 103.562 L 251.787 103.908 L 252.107 104.253 L 252.425 104.6 C 252.602 104.789 253.127 105.411 253.925 106.367 C 254.724 107.321 255.795 108.617 257.063 110.156 C 258.33 111.693 259.793 113.476 261.378 115.41 C 262.962 117.344 264.666 119.429 266.415 121.571 M 183.998 160.363 C 185.176 160.625 186.407 160.937 187.616 161.281 C 188.827 161.622 190.016 161.992 191.109 162.365 C 192.203 162.735 193.201 163.112 194.031 163.464 C 194.862 163.817 195.522 164.145 195.942 164.429 C 196.089 164.529 196.193 164.698 196.252 164.982 C 196.308 165.272 196.318 165.679 196.28 166.259 C 196.241 166.839 196.151 167.592 196.008 168.57 C 195.864 169.545 195.668 170.747 195.412 172.22 C 195.151 173.746 194.94 175.096 194.774 176.424 C 194.605 177.758 194.481 179.068 194.391 180.521 C 194.301 181.972 194.241 183.564 194.208 185.453 C 194.172 187.342 194.161 189.528 194.161 192.172 C 194.164 195.029 194.175 197.291 194.21 199.182 C 194.244 201.077 194.306 202.596 194.408 203.967 C 194.511 205.335 194.654 206.558 194.858 207.853 C 195.061 209.146 195.321 210.509 195.658 212.173 C 195.862 213.183 196.089 214.264 196.321 215.352 C 196.555 216.44 196.797 217.535 197.032 218.574 C 197.265 219.613 197.493 220.596 197.7 221.462 C 197.905 222.326 198.091 223.072 198.243 223.638 C 198.394 224.202 198.535 224.745 198.659 225.244 C 198.782 225.742 198.892 226.196 198.979 226.582 C 199.065 226.966 199.132 227.283 199.171 227.509 C 199.212 227.735 199.225 227.868 199.206 227.889 C 199.187 227.907 199.005 227.826 198.692 227.662 C 198.379 227.498 197.934 227.251 197.392 226.94 C 196.848 226.63 196.208 226.256 195.501 225.836 C 194.794 225.418 194.021 224.953 193.218 224.462 C 191.127 223.191 189.283 222.093 187.58 221.118 C 185.876 220.143 184.316 219.291 182.796 218.508 C 181.276 217.728 179.798 217.016 178.258 216.323 C 176.721 215.629 175.121 214.956 173.362 214.247 C 170.717 213.183 168.056 212.21 165.422 211.339 C 162.788 210.463 160.182 209.691 157.644 209.029 C 155.104 208.371 152.636 207.82 150.279 207.395 C 147.925 206.969 145.681 206.665 143.592 206.499 L 142.411 206.402 L 141.228 206.307 L 140.044 206.211 L 138.86 206.118 L 138.86 194.393 L 138.86 182.673 L 138.86 170.946 L 138.86 159.226 L 143.872 159.226 L 148.881 159.228 L 153.894 159.231 L 158.904 159.235 C 163.288 159.238 166.776 159.245 169.604 159.275 C 172.433 159.304 174.608 159.354 176.374 159.432 C 178.138 159.514 179.492 159.621 180.68 159.775 C 181.87 159.924 182.895 160.118 183.998 160.363 M 364.273 182.135 C 364.273 185.703 364.256 188.927 364.232 191.757 C 364.21 194.592 364.168 197.034 364.123 199.037 C 364.073 201.036 364.017 202.602 363.951 203.678 C 363.884 204.753 363.806 205.345 363.72 205.401 C 363.647 205.446 363.37 205.516 362.943 205.606 C 362.51 205.689 361.917 205.788 361.219 205.895 C 360.52 206.004 359.703 206.12 358.815 206.24 C 357.924 206.356 356.965 206.475 355.976 206.593 C 353.857 206.84 351.706 207.169 349.519 207.584 C 347.333 207.998 345.11 208.5 342.841 209.089 C 340.568 209.674 338.248 210.35 335.881 211.113 C 333.508 211.88 331.079 212.734 328.586 213.682 C 326.553 214.453 324.965 215.067 323.583 215.633 C 322.202 216.201 321.032 216.721 319.838 217.313 C 318.643 217.904 317.43 218.565 315.96 219.411 C 314.488 220.256 312.763 221.287 310.551 222.616 C 309.679 223.141 308.838 223.631 308.064 224.069 C 307.29 224.507 306.584 224.894 305.98 225.209 C 305.376 225.524 304.876 225.767 304.515 225.919 C 304.155 226.073 303.935 226.136 303.892 226.09 C 303.846 226.043 303.838 225.853 303.86 225.549 C 303.882 225.248 303.933 224.832 304.011 224.332 C 304.09 223.832 304.193 223.251 304.319 222.615 C 304.443 221.979 304.59 221.291 304.752 220.58 C 305.47 217.443 306.014 215.037 306.432 212.994 C 306.85 210.95 307.141 209.27 307.353 207.569 C 307.562 205.873 307.692 204.161 307.789 202.063 C 307.885 199.964 307.946 197.477 308.022 194.23 C 308.085 191.376 308.129 189.088 308.139 187.161 C 308.15 185.237 308.129 183.672 308.067 182.266 C 308.006 180.861 307.902 179.617 307.75 178.328 C 307.598 177.043 307.396 175.711 307.135 174.134 C 306.71 171.557 306.387 169.65 306.2 168.219 C 306.013 166.785 305.963 165.825 306.087 165.14 C 306.209 164.453 306.505 164.042 307.009 163.705 C 307.512 163.372 308.223 163.115 309.179 162.732 C 311.103 161.968 312.767 161.372 314.532 160.905 C 316.301 160.441 318.17 160.105 320.508 159.868 C 322.849 159.628 325.656 159.482 329.301 159.394 C 332.944 159.308 337.422 159.278 343.102 159.267 L 348.391 159.254 L 353.686 159.245 L 358.977 159.235 L 364.273 159.226 L 364.273 164.952 L 364.273 170.68 L 364.273 176.408 L 364.273 182.135 M 294.672 175.255 C 295.22 178.215 295.627 180.998 295.891 183.706 C 296.156 186.417 296.277 189.05 296.257 191.703 C 296.236 194.356 296.071 197.028 295.763 199.821 C 295.454 202.614 295.003 205.519 294.406 208.644 C 293.797 211.84 293.112 214.843 292.333 217.708 C 291.556 220.571 290.684 223.295 289.702 225.927 C 288.719 228.56 287.624 231.1 286.4 233.599 C 285.175 236.098 283.82 238.555 282.318 241.02 C 281.712 242.01 280.648 243.522 279.328 245.293 C 278.009 247.063 276.436 249.097 274.815 251.131 C 273.192 253.166 271.522 255.203 270.01 256.985 C 268.497 258.766 267.144 260.289 266.154 261.3 L 265.432 262.034 L 264.711 262.769 L 263.989 263.505 L 263.268 264.24 L 263.324 259.533 L 263.381 254.828 L 263.438 250.12 L 263.494 245.413 C 263.544 241.302 263.592 238.027 263.653 235.351 C 263.714 232.674 263.788 230.597 263.886 228.883 C 263.984 227.17 264.11 225.82 264.274 224.597 C 264.438 223.375 264.644 222.28 264.901 221.077 C 265.759 217.074 266.758 213.304 267.919 209.718 C 269.078 206.136 270.399 202.738 271.899 199.486 C 273.402 196.236 275.083 193.128 276.966 190.122 C 278.847 187.116 280.93 184.215 283.231 181.372 C 284.057 180.355 285.031 179.27 286.048 178.218 C 287.064 177.162 288.122 176.139 289.116 175.244 C 290.109 174.346 291.038 173.58 291.794 173.034 C 292.549 172.49 293.134 172.169 293.439 172.169 C 293.53 172.169 293.633 172.257 293.74 172.41 C 293.849 172.568 293.962 172.795 294.074 173.075 C 294.185 173.355 294.296 173.687 294.397 174.058 C 294.5 174.427 294.593 174.834 294.672 175.255 M 214.395 177.903 C 216.932 180.555 219.226 183.303 221.306 186.208 C 223.386 189.113 225.254 192.18 226.941 195.469 C 228.628 198.754 230.134 202.263 231.491 206.056 C 232.848 209.852 234.059 213.927 235.152 218.351 C 235.497 219.75 235.762 220.875 235.967 222.052 C 236.173 223.23 236.32 224.462 236.431 226.076 C 236.542 227.689 236.617 229.684 236.678 232.391 C 236.739 235.098 236.787 238.515 236.843 242.97 C 236.897 247.165 236.932 250.429 236.945 252.96 C 236.956 255.491 236.943 257.287 236.9 258.545 C 236.857 259.805 236.783 260.525 236.67 260.902 C 236.559 261.279 236.409 261.312 236.215 261.199 C 235.931 261.033 235.183 260.258 234.159 259.102 C 233.133 257.946 231.83 256.409 230.435 254.715 C 229.04 253.02 227.55 251.167 226.157 249.385 C 224.763 247.601 223.46 245.887 222.435 244.464 C 221.492 243.154 220.43 241.461 219.336 239.557 C 218.241 237.652 217.115 235.538 216.04 233.384 C 214.966 231.23 213.945 229.037 213.062 226.975 C 212.18 224.913 211.436 222.985 210.915 221.36 C 210.715 220.733 210.491 219.974 210.254 219.14 C 210.019 218.305 209.774 217.396 209.534 216.468 C 209.293 215.536 209.057 214.589 208.838 213.677 C 208.62 212.764 208.422 211.887 208.257 211.105 C 207.734 208.612 207.373 204.972 207.161 200.908 C 206.951 196.847 206.892 192.364 206.97 188.194 C 207.047 184.025 207.261 180.165 207.598 177.346 C 207.937 174.531 208.397 172.757 208.967 172.757 C 209.037 172.757 209.24 172.9 209.55 173.163 C 209.861 173.425 210.276 173.8 210.768 174.267 C 211.26 174.734 211.827 175.29 212.443 175.906 C 213.057 176.521 213.719 177.198 214.395 177.903 M 362.287 222.616 C 362.039 224.822 361.696 226.999 361.25 229.168 C 360.802 231.336 360.258 233.494 359.605 235.661 C 358.949 237.827 358.193 240.002 357.321 242.202 C 356.451 244.402 355.468 246.626 354.373 248.894 C 353.42 250.857 352.54 252.568 351.651 254.143 C 350.761 255.716 349.869 257.152 348.886 258.564 C 347.908 259.976 346.841 261.366 345.604 262.846 C 344.366 264.324 342.963 265.895 341.318 267.67 C 339.751 269.361 338.317 270.826 336.939 272.137 C 335.552 273.447 334.221 274.599 332.854 275.666 C 331.483 276.729 330.076 277.706 328.545 278.66 C 327.016 279.613 325.361 280.546 323.495 281.524 C 321.16 282.75 318.988 283.737 316.707 284.525 C 314.424 285.314 312.031 285.904 309.247 286.342 C 306.462 286.78 303.287 287.064 299.44 287.237 C 295.592 287.414 291.074 287.479 285.605 287.479 L 281.702 287.479 L 277.799 287.479 L 273.896 287.479 L 269.992 287.479 L 270.084 287.147 L 270.176 286.818 L 270.267 286.486 L 270.359 286.155 C 270.515 285.585 271.039 284.472 271.797 283.034 C 272.555 281.597 273.55 279.834 274.654 277.964 C 275.759 276.092 276.971 274.114 278.164 272.243 C 279.357 270.373 280.53 268.61 281.557 267.176 C 286.49 260.272 291.976 254.005 297.894 248.447 C 303.812 242.89 310.161 238.045 316.821 233.98 C 323.478 229.92 330.443 226.642 337.598 224.224 C 344.751 221.805 352.094 220.246 359.505 219.621 C 359.812 219.595 360.119 219.566 360.408 219.538 C 360.702 219.512 360.977 219.484 361.223 219.458 C 361.467 219.431 361.682 219.408 361.848 219.385 C 362.019 219.365 362.146 219.345 362.209 219.333 C 362.27 219.318 362.323 219.401 362.356 219.562 C 362.393 219.721 362.413 219.958 362.42 220.256 C 362.429 220.554 362.42 220.912 362.398 221.311 C 362.377 221.709 362.343 222.151 362.287 222.616 M 127.615 226.441 C 128.292 230.02 129.18 233.67 130.242 237.294 C 131.303 240.92 132.536 244.52 133.907 247.993 C 135.276 251.468 136.779 254.816 138.38 257.942 C 139.98 261.066 141.674 263.97 143.424 266.55 C 144.672 268.387 146.181 270.359 147.856 272.368 C 149.529 274.375 151.367 276.418 153.273 278.395 C 155.18 280.373 157.152 282.285 159.098 284.03 C 161.042 285.778 162.959 287.36 164.749 288.675 C 165.572 289.278 166.345 289.86 167.036 290.395 C 167.727 290.928 168.34 291.415 168.84 291.828 C 169.34 292.244 169.73 292.585 169.977 292.83 C 170.226 293.076 170.333 293.222 170.27 293.245 C 170.079 293.318 169.361 293.128 168.296 292.752 C 167.229 292.375 165.819 291.812 164.242 291.142 C 162.667 290.473 160.928 289.694 159.204 288.884 C 157.485 288.076 155.783 287.236 154.28 286.444 C 148.912 283.61 143.725 280.241 138.787 276.403 C 133.85 272.565 129.161 268.258 124.779 263.552 C 120.398 258.843 116.327 253.735 112.627 248.29 C 108.926 242.846 105.598 237.068 102.705 231.024 C 102.347 230.274 102.01 229.555 101.708 228.897 C 101.405 228.236 101.138 227.636 100.919 227.125 C 100.7 226.615 100.527 226.195 100.416 225.896 C 100.305 225.595 100.254 225.419 100.28 225.393 C 100.305 225.366 100.453 225.299 100.693 225.199 C 100.936 225.098 101.274 224.965 101.685 224.809 C 102.093 224.653 102.577 224.475 103.105 224.282 C 103.634 224.09 104.209 223.883 104.806 223.672 C 106.009 223.25 107.545 222.805 109.237 222.376 C 110.928 221.944 112.775 221.528 114.594 221.164 C 116.416 220.798 118.211 220.485 119.804 220.256 C 121.393 220.028 122.779 219.888 123.781 219.869 L 124.429 219.858 L 125.074 219.846 L 125.721 219.835 L 126.365 219.822 L 126.679 221.477 L 126.992 223.132 L 127.305 224.785 L 127.615 226.441 M 150.401 221.008 C 154.24 221.696 158.178 222.712 162.136 224.018 C 166.097 225.324 170.077 226.921 174.005 228.775 C 177.933 230.628 181.809 232.737 185.555 235.067 C 189.3 237.396 192.918 239.945 196.335 242.681 C 197.475 243.592 198.972 244.936 200.637 246.513 C 202.302 248.09 204.136 249.904 205.952 251.762 C 207.767 253.618 209.561 255.52 211.151 257.272 C 212.738 259.023 214.118 260.626 215.102 261.887 C 216.675 263.902 218.309 266.157 219.896 268.474 C 221.483 270.789 223.022 273.167 224.404 275.429 C 225.787 277.689 227.013 279.833 227.971 281.68 C 228.931 283.527 229.625 285.078 229.943 286.155 L 230.04 286.486 L 230.138 286.818 L 230.234 287.147 L 230.332 287.479 L 226.503 287.477 L 222.673 287.477 L 218.844 287.476 L 215.015 287.475 C 209.688 287.474 205.347 287.414 201.67 287.244 C 197.995 287.073 194.981 286.791 192.311 286.34 C 189.64 285.89 187.313 285.277 185.006 284.44 C 182.7 283.607 180.415 282.551 177.83 281.222 C 174.857 279.694 171.933 277.808 169.117 275.629 C 166.299 273.452 163.592 270.984 161.055 268.292 C 158.521 265.6 156.16 262.686 154.036 259.619 C 151.913 256.549 150.026 253.325 148.439 250.014 C 147.262 247.55 146.142 244.939 145.129 242.32 C 144.116 239.702 143.208 237.077 142.447 234.583 C 141.685 232.09 141.071 229.729 140.647 227.639 C 140.221 225.549 139.987 223.73 139.984 222.322 C 139.984 221.708 139.984 221.246 140.018 220.897 C 140.049 220.548 140.113 220.311 140.234 220.152 C 140.354 219.994 140.534 219.91 140.801 219.868 C 141.068 219.825 141.421 219.822 141.887 219.822 C 142.149 219.822 142.585 219.855 143.15 219.915 C 143.714 219.974 144.405 220.063 145.175 220.169 C 145.948 220.277 146.798 220.405 147.684 220.547 C 148.573 220.689 149.493 220.845 150.401 221.008 M 386.42 221.248 C 387.353 221.423 388.673 221.736 390.135 222.113 C 391.591 222.492 393.193 222.935 394.695 223.376 C 396.202 223.819 397.608 224.256 398.663 224.619 C 399.736 224.982 400.461 225.272 400.609 225.415 C 400.68 225.485 400.53 225.956 400.194 226.725 C 399.861 227.493 399.357 228.559 398.729 229.813 C 398.108 231.071 397.359 232.516 396.542 234.047 C 395.729 235.578 394.837 237.194 393.935 238.788 C 391.085 243.831 387.831 248.73 384.286 253.39 C 380.74 258.048 376.892 262.47 372.836 266.561 C 368.783 270.648 364.517 274.407 360.141 277.739 C 355.761 281.071 351.268 283.979 346.75 286.368 C 345.452 287.056 344.007 287.771 342.554 288.454 C 341.116 289.135 339.666 289.782 338.358 290.338 C 337.05 290.892 335.883 291.352 335 291.658 C 334.116 291.965 333.516 292.119 333.34 292.056 C 333.27 292.032 333.351 291.899 333.557 291.677 C 333.766 291.455 334.099 291.147 334.531 290.774 C 334.964 290.402 335.5 289.964 336.102 289.485 C 336.708 289.004 337.386 288.483 338.112 287.941 C 341.136 285.688 343.974 283.293 346.63 280.752 C 349.291 278.211 351.77 275.522 354.078 272.675 C 356.388 269.829 358.521 266.827 360.496 263.659 C 362.468 260.491 364.28 257.157 365.927 253.651 C 367.035 251.305 368.003 249.097 368.864 246.948 C 369.735 244.801 370.491 242.715 371.167 240.614 C 371.845 238.512 372.436 236.399 372.969 234.196 C 373.503 231.992 373.983 229.7 374.42 227.243 L 374.728 225.536 L 375.036 223.826 L 375.34 222.118 L 375.649 220.411 L 376.434 220.411 L 377.215 220.411 L 378.007 220.411 L 378.79 220.412 C 379.221 220.412 379.759 220.435 380.363 220.477 C 380.966 220.519 381.638 220.582 382.324 220.657 C 383.019 220.733 383.73 220.823 384.425 220.923 C 385.125 221.022 385.801 221.133 386.42 221.248 M 166.406 383.113 C 167.419 383.787 168.276 384.729 168.956 385.829 C 169.636 386.933 170.14 388.194 170.444 389.526 C 170.75 390.856 170.855 392.249 170.74 393.607 C 170.623 394.962 170.287 396.289 169.705 397.491 C 169.275 398.374 168.776 399.155 168.21 399.84 C 167.643 400.526 167.009 401.111 166.308 401.589 C 165.608 402.076 164.842 402.456 164.012 402.74 C 163.182 403.017 162.286 403.196 161.331 403.266 C 160.319 403.339 159.365 403.306 158.461 403.149 C 157.561 402.989 156.714 402.722 155.918 402.326 C 155.12 401.943 154.38 401.436 153.684 400.806 C 152.989 400.182 152.347 399.439 151.749 398.569 C 150.993 397.473 150.484 396.193 150.213 394.844 C 149.94 393.491 149.901 392.061 150.082 390.669 C 150.263 389.281 150.665 387.932 151.269 386.723 C 151.88 385.518 152.69 384.454 153.693 383.652 C 154.574 382.95 155.573 382.409 156.637 382.032 C 157.704 381.652 158.834 381.438 159.969 381.389 C 161.104 381.338 162.25 381.458 163.342 381.743 C 164.433 382.032 165.476 382.487 166.406 383.113 M 345.257 382.546 C 345.746 382.799 346.29 383.216 346.852 383.725 C 347.405 384.236 347.969 384.833 348.486 385.466 C 349.005 386.089 349.475 386.74 349.844 387.357 C 350.214 387.97 350.484 388.541 350.592 389.004 C 350.641 389.209 350.681 389.489 350.711 389.834 C 350.741 390.167 350.758 390.564 350.768 390.987 C 350.78 391.407 350.775 391.861 350.764 392.314 C 350.753 392.762 350.73 393.223 350.694 393.657 C 350.519 395.874 349.727 397.797 348.544 399.335 C 347.358 400.876 345.774 402.039 344.023 402.733 C 342.273 403.416 340.349 403.642 338.478 403.309 C 336.608 402.974 334.783 402.084 333.238 400.552 C 332.63 399.949 332.127 399.371 331.714 398.778 C 331.303 398.185 330.981 397.582 330.739 396.925 C 330.496 396.269 330.327 395.558 330.219 394.757 C 330.11 393.949 330.063 393.055 330.063 392.027 C 330.063 391.002 330.137 390.074 330.287 389.23 C 330.437 388.384 330.669 387.62 330.99 386.92 C 331.313 386.21 331.724 385.565 332.24 384.952 C 332.751 384.338 333.368 383.766 334.095 383.201 C 334.781 382.662 335.614 382.248 336.528 381.942 C 337.445 381.642 338.436 381.46 339.45 381.399 C 340.465 381.338 341.495 381.406 342.484 381.595 C 343.476 381.782 344.419 382.102 345.257 382.546 M 256.549 383.921 C 257.04 384.288 257.567 384.871 258.086 385.576 C 258.603 386.279 259.108 387.117 259.552 387.97 C 259.996 388.827 260.38 389.704 260.654 390.521 C 260.927 391.338 261.089 392.084 261.091 392.668 C 261.093 393.424 260.884 394.317 260.52 395.267 C 260.156 396.208 259.636 397.208 259.024 398.158 C 258.412 399.112 257.705 400.024 256.963 400.796 C 256.221 401.575 255.444 402.216 254.691 402.622 C 253.829 403.093 252.859 403.383 251.845 403.496 C 250.833 403.619 249.778 403.563 248.745 403.359 C 247.713 403.153 246.705 402.789 245.785 402.286 C 244.865 401.776 244.035 401.126 243.361 400.348 C 242.582 399.455 241.949 398.455 241.467 397.409 C 240.988 396.359 240.659 395.258 240.488 394.145 C 240.317 393.027 240.304 391.897 240.457 390.794 C 240.607 389.696 240.924 388.62 241.412 387.617 C 241.927 386.563 242.454 385.689 243.041 384.979 C 243.624 384.273 244.264 383.725 245.007 383.317 C 245.748 382.912 246.591 382.65 247.577 382.499 C 248.565 382.347 249.696 382.312 251.015 382.365 C 251.715 382.396 252.322 382.44 252.859 382.506 C 253.397 382.575 253.866 382.662 254.293 382.784 C 254.72 382.906 255.104 383.052 255.472 383.239 C 255.839 383.435 256.189 383.652 256.549 383.921" fill-rule="evenodd" id="object-1" transform="matrix(1, 0, 0, 1, 1.4210854715202004e-14, 0)" style="stroke-opacity: 0;"></path></svg> | ||
| \ No newline at end of file | 1 | \ No newline at end of file | |
| @@ -10,6 +10,7 @@ | |||
| 10 | <meta name="mobile-web-app-capable" content="yes"> | 10 | <meta name="mobile-web-app-capable" content="yes"> |
| 11 | <meta name="darkreader-lock"> | 11 | <meta name="darkreader-lock"> |
| 12 | <meta name="robots" content="noindex, nofollow" /> | 12 | <meta name="robots" content="noindex, nofollow" /> |
| 13 | <meta name="theme-color" content="#333"> | ||
| 13 | <style> | 14 | <style> |
| 14 | /* Put critical CSS here. The rest should go in stylesheets. */ | 15 | /* Put critical CSS here. The rest should go in stylesheets. */ |
| 15 | body { | 16 | body { |
| @@ -176,6 +177,11 @@ | |||
| 176 | </strong> | 177 | </strong> |
| 177 | 178 | ||
| 178 | <div class="flex-container gap3px"> | 179 | <div class="flex-container gap3px"> |
| 180 | <label for="bind_preset_to_connection" class="margin0 menu_button menu_button_icon" title="Bind presets to API connections" data-i18n="[title]Bind presets to API connections"> | ||
| 181 | <input id="bind_preset_to_connection" type="checkbox" class="displayNone" /> | ||
| 182 | <i class="fa-fw fa-solid fa-link toggleOn"></i> | ||
| 183 | <i class="fa-fw fa-solid fa-link-slash toggleOff"></i> | ||
| 184 | </label> | ||
| 179 | <div id="import_oai_preset" class="margin0 menu_button menu_button_icon" title="Import preset" data-i18n="[title]Import preset"> | 185 | <div id="import_oai_preset" class="margin0 menu_button menu_button_icon" title="Import preset" data-i18n="[title]Import preset"> |
| 180 | <i class="fa-fw fa-solid fa-file-import"></i> | 186 | <i class="fa-fw fa-solid fa-file-import"></i> |
| 181 | </div> | 187 | </div> |
| @@ -685,7 +691,7 @@ | |||
| 685 | </span> | 691 | </span> |
| 686 | </div> | 692 | </div> |
| 687 | </div> | 693 | </div> |
| 688 | <div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek,xai"> | 694 | <div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek,xai"> |
| 689 | <div class="range-block-title" data-i18n="Temperature"> | 695 | <div class="range-block-title" data-i18n="Temperature"> |
| 690 | Temperature | 696 | Temperature |
| 691 | </div> | 697 | </div> |
| @@ -724,7 +730,7 @@ | |||
| 724 | </div> | 730 | </div> |
| 725 | </div> | 731 | </div> |
| 726 | </div> | 732 | </div> |
| 727 | <div class="range-block" data-source="claude,openrouter,makersuite,cohere,perplexity"> | 733 | <div class="range-block" data-source="claude,openrouter,makersuite,vertexai,cohere,perplexity"> |
| 728 | <div class="range-block-title" data-i18n="Top K"> | 734 | <div class="range-block-title" data-i18n="Top K"> |
| 729 | Top K | 735 | Top K |
| 730 | </div> | 736 | </div> |
| @@ -737,7 +743,7 @@ | |||
| 737 | </div> | 743 | </div> |
| 738 | </div> | 744 | </div> |
| 739 | </div> | 745 | </div> |
| 740 | <div class="range-block" data-source="openai,claude,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek,xai"> | 746 | <div class="range-block" data-source="openai,claude,openrouter,ai21,scale,makersuite,vertexai,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek,xai"> |
| 741 | <div class="range-block-title" data-i18n="Top P"> | 747 | <div class="range-block-title" data-i18n="Top P"> |
| 742 | Top P | 748 | Top P |
| 743 | </div> | 749 | </div> |
| @@ -974,7 +980,7 @@ | |||
| 974 | </div> | 980 | </div> |
| 975 | </div> | 981 | </div> |
| 976 | </div> | 982 | </div> |
| 977 | <div class="range-block" data-source="openai,openrouter,mistralai,custom,cohere,groq,nanogpt,xai"> | 983 | <div class="range-block" data-source="openai,openrouter,mistralai,custom,cohere,groq,nanogpt,xai,pollinations"> |
| 978 | <div class="range-block-title justifyLeft" data-i18n="Seed"> | 984 | <div class="range-block-title justifyLeft" data-i18n="Seed"> |
| 979 | Seed | 985 | Seed |
| 980 | </div> | 986 | </div> |
| @@ -1284,7 +1290,7 @@ | |||
| 1284 | <input class="neo-range-slider" type="range" id="min_p_textgenerationwebui" name="volume" min="0" max="1" step="0.001"> | 1290 | <input class="neo-range-slider" type="range" id="min_p_textgenerationwebui" name="volume" min="0" max="1" step="0.001"> |
| 1285 | <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="min_p_textgenerationwebui" id="min_p_counter_textgenerationwebui"> | 1291 | <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="min_p_textgenerationwebui" id="min_p_counter_textgenerationwebui"> |
| 1286 | </div> | 1292 | </div> |
| 1287 | <div data-tg-type-mode="except" data-tg-type="generic" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | 1293 | <div data-tg-type-mode="except" data-tg-type="generic,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> |
| 1288 | <small> | 1294 | <small> |
| 1289 | <span data-i18n="Top A">Top A</span> | 1295 | <span data-i18n="Top A">Top A</span> |
| 1290 | <div class="fa-solid fa-circle-info opacity50p" title="Top A sets a threshold for token selection based on the square of the highest token probability. E.g if the Top-A value is 0.2 and the top token's probability is 50%, tokens with probabilities below 5% (0.2 * 0.5^2) are excluded. Set to 0 to disable." data-i18n="[title]Top_A_desc"></div> | 1296 | <div class="fa-solid fa-circle-info opacity50p" title="Top A sets a threshold for token selection based on the square of the highest token probability. E.g if the Top-A value is 0.2 and the top token's probability is 50%, tokens with probabilities below 5% (0.2 * 0.5^2) are excluded. Set to 0 to disable." data-i18n="[title]Top_A_desc"></div> |
| @@ -1292,7 +1298,7 @@ | |||
| 1292 | <input class="neo-range-slider" type="range" id="top_a_textgenerationwebui" name="volume" min="0" max="1" step="0.01"> | 1298 | <input class="neo-range-slider" type="range" id="top_a_textgenerationwebui" name="volume" min="0" max="1" step="0.01"> |
| 1293 | <input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="top_a_textgenerationwebui" id="top_a_counter_textgenerationwebui"> | 1299 | <input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="top_a_textgenerationwebui" id="top_a_counter_textgenerationwebui"> |
| 1294 | </div> | 1300 | </div> |
| 1295 | <div data-tg-type-mode="except" data-tg-type="generic" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | 1301 | <div data-tg-type-mode="except" data-tg-type="generic,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> |
| 1296 | <small> | 1302 | <small> |
| 1297 | <span data-i18n="TFS">TFS</span> | 1303 | <span data-i18n="TFS">TFS</span> |
| 1298 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail_Free_Sampling_desc" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution, by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative. The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div> | 1304 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail_Free_Sampling_desc" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution, by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative. The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div> |
| @@ -1308,7 +1314,7 @@ | |||
| 1308 | <input class="neo-range-slider" type="range" id="epsilon_cutoff_textgenerationwebui" name="volume" min="0" max="9" step="0.01"> | 1314 | <input class="neo-range-slider" type="range" id="epsilon_cutoff_textgenerationwebui" name="volume" min="0" max="9" step="0.01"> |
| 1309 | <input class="neo-range-input" type="number" min="0" max="9" step="0.01" data-for="epsilon_cutoff_textgenerationwebui" id="epsilon_cutoff_counter_textgenerationwebui"> | 1315 | <input class="neo-range-input" type="number" min="0" max="9" step="0.01" data-for="epsilon_cutoff_textgenerationwebui" id="epsilon_cutoff_counter_textgenerationwebui"> |
| 1310 | </div> | 1316 | </div> |
| 1311 | <div data-tg-type="aphrodite,koboldcpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | 1317 | <div data-tg-type="aphrodite,koboldcpp,llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> |
| 1312 | <small> | 1318 | <small> |
| 1313 | <span data-i18n="Top nsigma">Top nsigma</span> | 1319 | <span data-i18n="Top nsigma">Top nsigma</span> |
| 1314 | <div class="fa-solid fa-circle-info opacity50p" title="A sampling method that filters logits based on their statistical properties. It keeps tokens within n standard deviations of the maximum logit value, providing a simpler alternative to top-p/top-k sampling while maintaining sampling stability across different temperatures."></div> | 1320 | <div class="fa-solid fa-circle-info opacity50p" title="A sampling method that filters logits based on their statistical properties. It keeps tokens within n standard deviations of the maximum logit value, providing a simpler alternative to top-p/top-k sampling while maintaining sampling stability across different temperatures."></div> |
| @@ -1316,6 +1322,14 @@ | |||
| 1316 | <input class="neo-range-slider" type="range" id="nsigma_textgenerationwebui" name="volume" min="0" max="5" step="0.01"> | 1322 | <input class="neo-range-slider" type="range" id="nsigma_textgenerationwebui" name="volume" min="0" max="5" step="0.01"> |
| 1317 | <input class="neo-range-input" type="number" min="0" max="5" step="0.01" data-for="nsigma_textgenerationwebui" id="nsigma_counter_textgenerationwebui"> | 1323 | <input class="neo-range-input" type="number" min="0" max="5" step="0.01" data-for="nsigma_textgenerationwebui" id="nsigma_counter_textgenerationwebui"> |
| 1318 | </div> | 1324 | </div> |
| 1325 | <div data-tg-type="llamacpp" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | ||
| 1326 | <small> | ||
| 1327 | <span data-i18n="Min Keep">Min Keep</span> | ||
| 1328 | <div class="fa-solid fa-circle-info opacity50p" title="A sampling modifier that ensures that truncation samplers such as top-p, min-p, typical-p, and xtc return at least this many tokens. Set to 0 to disable."></div> | ||
| 1329 | </small> | ||
| 1330 | <input class="neo-range-slider" type="range" id="min_keep_textgenerationwebui" name="volume" min="0" max="50" step="1"> | ||
| 1331 | <input class="neo-range-input" type="number" min="0" max="50" step="1" data-for="min_keep_textgenerationwebui" id="min_keep_counter_textgenerationwebui"> | ||
| 1332 | </div> | ||
| 1319 | <div data-tg-type="ooba,mancer,aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> | 1333 | <div data-tg-type="ooba,mancer,aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0"> |
| 1320 | <small> | 1334 | <small> |
| 1321 | <span data-i18n="Eta Cutoff">Eta Cutoff</span> | 1335 | <span data-i18n="Eta Cutoff">Eta Cutoff</span> |
| @@ -1398,7 +1412,7 @@ | |||
| 1398 | </div> | 1412 | </div> |
| 1399 | </div> | 1413 | </div> |
| 1400 | 1414 | ||
| 1401 | <div data-tg-type="koboldcpp, aphrodite, tabby, ooba, llamacpp" id="xtc_block" class="wide100p"> | 1415 | <div data-tg-type="koboldcpp, aphrodite, mancer, tabby, ooba, llamacpp" id="xtc_block" class="wide100p"> |
| 1402 | <h4 class="wide100p textAlignCenter"> | 1416 | <h4 class="wide100p textAlignCenter"> |
| 1403 | <label data-i18n="Exclude Top Choices (XTC)">Exclude Top Choices (XTC)</label> | 1417 | <label data-i18n="Exclude Top Choices (XTC)">Exclude Top Choices (XTC)</label> |
| 1404 | <a href="https://github.com/oobabooga/text-generation-webui/pull/6335" target="_blank"> | 1418 | <a href="https://github.com/oobabooga/text-generation-webui/pull/6335" target="_blank"> |
| @@ -1419,7 +1433,7 @@ | |||
| 1419 | </div> | 1433 | </div> |
| 1420 | </div> | 1434 | </div> |
| 1421 | 1435 | ||
| 1422 | <div data-tg-type="aphrodite, ooba, koboldcpp, tabby, llamacpp, dreamgen" id="dryBlock" class="wide100p"> | 1436 | <div data-tg-type="aphrodite, mancer, ooba, koboldcpp, tabby, llamacpp, dreamgen" id="dryBlock" class="wide100p"> |
| 1423 | <h4 class="wide100p textAlignCenter" title="DRY penalizes tokens that would extend the end of the input into a sequence that has previously occurred in the input. Set multiplier to 0 to disable." data-i18n="[title]DRY_Repetition_Penalty_desc"> | 1437 | <h4 class="wide100p textAlignCenter" title="DRY penalizes tokens that would extend the end of the input into a sequence that has previously occurred in the input. Set multiplier to 0 to disable." data-i18n="[title]DRY_Repetition_Penalty_desc"> |
| 1424 | <label data-i18n="DRY Repetition Penalty">DRY Repetition Penalty</label> | 1438 | <label data-i18n="DRY Repetition Penalty">DRY Repetition Penalty</label> |
| 1425 | <a href="https://github.com/oobabooga/text-generation-webui/pull/5677" target="_blank"> | 1439 | <a href="https://github.com/oobabooga/text-generation-webui/pull/5677" target="_blank"> |
| @@ -1485,7 +1499,7 @@ | |||
| 1485 | </div> | 1499 | </div> |
| 1486 | </div> | 1500 | </div> |
| 1487 | </div> | 1501 | </div> |
| 1488 | <div data-tg-type="ooba,infermaticai,koboldcpp,llamacpp,mancer,ollama,tabby" id="mirostat_block_ooba" class="wide100p"> | 1502 | <div data-tg-type="ooba,infermaticai,koboldcpp,llamacpp,ollama,tabby" id="mirostat_block_ooba" class="wide100p"> |
| 1489 | <h4 class="wide100p textAlignCenter"> | 1503 | <h4 class="wide100p textAlignCenter"> |
| 1490 | <label data-i18n="Mirostat (mode=1 is only for llama.cpp)">Mirostat</label> | 1504 | <label data-i18n="Mirostat (mode=1 is only for llama.cpp)">Mirostat</label> |
| 1491 | <div class=" fa-solid fa-circle-info opacity50p " data-i18n="[title]Mirostat_desc" title="Mirostat is a thermostat for output perplexity. Mirostat matches the output perplexity to that of the input, thus avoiding the repetition trap (where, as the autoregressive inference produces text, the perplexity of the output tends toward zero) and the confusion trap (where the perplexity diverges). For details, see the paper Mirostat: A Neural Text Decoding Algorithm that Directly Controls Perplexity by Basu et al. (2020). Mode chooses the Mirostat version. 0=disable, 1=Mirostat 1.0 (llama.cpp only), 2=Mirostat 2.0."></div> | 1505 | <div class=" fa-solid fa-circle-info opacity50p " data-i18n="[title]Mirostat_desc" title="Mirostat is a thermostat for output perplexity. Mirostat matches the output perplexity to that of the input, thus avoiding the repetition trap (where, as the autoregressive inference produces text, the perplexity of the output tends toward zero) and the confusion trap (where the perplexity diverges). For details, see the paper Mirostat: A Neural Text Decoding Algorithm that Directly Controls Perplexity by Basu et al. (2020). Mode chooses the Mirostat version. 0=disable, 1=Mirostat 1.0 (llama.cpp only), 2=Mirostat 2.0."></div> |
| @@ -1769,11 +1783,12 @@ | |||
| 1769 | <div data-name="temperature" draggable="true"><span>Temperature</span><small></small></div> | 1783 | <div data-name="temperature" draggable="true"><span>Temperature</span><small></small></div> |
| 1770 | <div data-name="top_k" draggable="true"><span>Top K</span><small></small></div> | 1784 | <div data-name="top_k" draggable="true"><span>Top K</span><small></small></div> |
| 1771 | <div data-name="top_p" draggable="true"><span>Top P</span><small></small></div> | 1785 | <div data-name="top_p" draggable="true"><span>Top P</span><small></small></div> |
| 1772 | <div data-name="typical_p" draggable="true"><span>Typical P</span><small></small></div> | 1786 | <div data-name="typ_p" draggable="true"><span>Typical P</span><small></small></div> |
| 1773 | <div data-name="tfs_z" draggable="true"><span>Tail Free Sampling</span><small></small></div> | ||
| 1774 | <div data-name="min_p" draggable="true"><span>Min P</span><small></small></div> | 1787 | <div data-name="min_p" draggable="true"><span>Min P</span><small></small></div> |
| 1775 | <div data-name="xtc" draggable="true"><span>Exclude Top Choices</span><small></small></div> | 1788 | <div data-name="xtc" draggable="true"><span>Exclude Top Choices</span><small></small></div> |
| 1776 | <div data-name="dry" draggable="true"><span>DRY</span><small></small></div> | 1789 | <div data-name="dry" draggable="true"><span>DRY</span><small></small></div> |
| 1790 | <div data-name="penalties" draggable="true"><span>Rep/Freq/Pres Penalties</span><small></small></div> | ||
| 1791 | <div data-name="top_n_sigma" draggable="true"><span>Top N-Sigma</span><small></small></div> | ||
| 1777 | </div> | 1792 | </div> |
| 1778 | <div id="llamacpp_samplers_default_order" class="menu_button menu_button_icon"> | 1793 | <div id="llamacpp_samplers_default_order" class="menu_button menu_button_icon"> |
| 1779 | <span data-i18n="Load default order">Load default order</span> | 1794 | <span data-i18n="Load default order">Load default order</span> |
| @@ -1954,7 +1969,7 @@ | |||
| 1954 | </span> | 1969 | </span> |
| 1955 | </div> | 1970 | </div> |
| 1956 | </div> | 1971 | </div> |
| 1957 | <div class="range-block" data-source="makersuite,openrouter"> | 1972 | <div class="range-block" data-source="makersuite,vertexai,openrouter,claude"> |
| 1958 | <label for="openai_enable_web_search" class="checkbox_label flexWrap widthFreeExpand"> | 1973 | <label for="openai_enable_web_search" class="checkbox_label flexWrap widthFreeExpand"> |
| 1959 | <input id="openai_enable_web_search" type="checkbox" /> | 1974 | <input id="openai_enable_web_search" type="checkbox" /> |
| 1960 | <span data-i18n="Enable web search">Enable web search</span> | 1975 | <span data-i18n="Enable web search">Enable web search</span> |
| @@ -1968,7 +1983,7 @@ | |||
| 1968 | </b> | 1983 | </b> |
| 1969 | </div> | 1984 | </div> |
| 1970 | </div> | 1985 | </div> |
| 1971 | <div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq,deepseek,makersuite,ai21,xai"> | 1986 | <div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq,deepseek,makersuite,vertexai,ai21,xai,pollinations"> |
| 1972 | <label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand"> | 1987 | <label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand"> |
| 1973 | <input id="openai_function_calling" type="checkbox" /> | 1988 | <input id="openai_function_calling" type="checkbox" /> |
| 1974 | <span data-i18n="Enable function calling">Enable function calling</span> | 1989 | <span data-i18n="Enable function calling">Enable function calling</span> |
| @@ -1976,21 +1991,22 @@ | |||
| 1976 | <div class="flexBasis100p toggle-description justifyLeft"> | 1991 | <div class="flexBasis100p toggle-description justifyLeft"> |
| 1977 | <span data-i18n="enable_functions_desc_1">Allows using </span><a href="https://platform.openai.com/docs/guides/function-calling" target="_blank" data-i18n="enable_functions_desc_2">function tools</a>. | 1992 | <span data-i18n="enable_functions_desc_1">Allows using </span><a href="https://platform.openai.com/docs/guides/function-calling" target="_blank" data-i18n="enable_functions_desc_2">function tools</a>. |
| 1978 | <span data-i18n="enable_functions_desc_3">Can be utilized by various extensions to provide additional functionality.</span> | 1993 | <span data-i18n="enable_functions_desc_3">Can be utilized by various extensions to provide additional functionality.</span> |
| 1994 | <strong data-i18n="enable_functions_desc_4">Not supported when Prompt Post-Processing is used!</strong> | ||
| 1979 | </div> | 1995 | </div> |
| 1980 | </div> | 1996 | </div> |
| 1981 | <div class="range-block" data-source="openai,openrouter,mistralai,makersuite,claude,custom,01ai,xai"> | 1997 | <div class="range-block" data-source="openai,openrouter,mistralai,makersuite,vertexai,claude,custom,01ai,xai,pollinations"> |
| 1982 | <label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand"> | 1998 | <label for="openai_image_inlining" class="checkbox_label flexWrap widthFreeExpand"> |
| 1983 | <input id="openai_image_inlining" type="checkbox" /> | 1999 | <input id="openai_image_inlining" type="checkbox" /> |
| 1984 | <span data-i18n="Send inline images">Send inline images</span> | 2000 | <span data-i18n="Send inline images">Send inline images</span> |
| 1985 | </label> | 2001 | </label> |
| 1986 | <div id="image_inlining_hint" class="flexBasis100p toggle-description justifyLeft"> | 2002 | <div id="image_inlining_hint" class="flexBasis100p toggle-description justifyLeft"> |
| 1987 | <span data-i18n="image_inlining_hint_1">Sends images in prompts if the model supports it (e.g. GPT-4V, Claude 3 or Llava 13B). Use the</span> | 2003 | <span data-i18n="image_inlining_hint_1">Sends images in prompts if the model supports it. Use the</span> |
| 1988 | <code><i class="fa-solid fa-paperclip"></i></code> | 2004 | <code><i class="fa-solid fa-paperclip"></i></code> |
| 1989 | <span data-i18n="image_inlining_hint_2">action on any message or the</span> | 2005 | <span data-i18n="image_inlining_hint_2">action on any message or the</span> |
| 1990 | <code><i class="fa-solid fa-wand-magic-sparkles"></i></code> | 2006 | <code><i class="fa-solid fa-wand-magic-sparkles"></i></code> |
| 1991 | <span data-i18n="image_inlining_hint_3">menu to attach an image file to the chat.</span> | 2007 | <span data-i18n="image_inlining_hint_3">menu to attach an image file to the chat.</span> |
| 1992 | </div> | 2008 | </div> |
| 1993 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai"> | 2009 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai,pollinations"> |
| 1994 | <div class="flex-container oneline-dropdown"> | 2010 | <div class="flex-container oneline-dropdown"> |
| 1995 | <label for="openai_inline_image_quality" data-i18n="Inline Image Quality"> | 2011 | <label for="openai_inline_image_quality" data-i18n="Inline Image Quality"> |
| 1996 | Inline Image Quality | 2012 | Inline Image Quality |
| @@ -2003,7 +2019,7 @@ | |||
| 2003 | </div> | 2019 | </div> |
| 2004 | </div> | 2020 | </div> |
| 2005 | </div> | 2021 | </div> |
| 2006 | <div class="range-block" data-source="makersuite"> | 2022 | <div class="range-block" data-source="makersuite,vertexai"> |
| 2007 | <label for="openai_request_images" class="checkbox_label widthFreeExpand"> | 2023 | <label for="openai_request_images" class="checkbox_label widthFreeExpand"> |
| 2008 | <input id="openai_request_images" type="checkbox" /> | 2024 | <input id="openai_request_images" type="checkbox" /> |
| 2009 | <span> | 2025 | <span> |
| @@ -2015,17 +2031,17 @@ | |||
| 2015 | <span data-i18n="Allows the model to return image attachments."> | 2031 | <span data-i18n="Allows the model to return image attachments."> |
| 2016 | Allows the model to return image attachments. | 2032 | Allows the model to return image attachments. |
| 2017 | </span> | 2033 | </span> |
| 2018 | <em data-source="makersuite" data-i18n="Request inline images_desc_2"> | 2034 | <em data-source="makersuite,vertexai" data-i18n="Request inline images_desc_2"> |
| 2019 | Incompatible with the following features: function calling, web search, system prompt. | 2035 | Incompatible with the following features: function calling, web search, system prompt. |
| 2020 | </em> | 2036 | </em> |
| 2021 | </div> | 2037 | </div> |
| 2022 | </div> | 2038 | </div> |
| 2023 | <div class="range-block" data-source="makersuite"> | 2039 | <div class="range-block" data-source="makersuite,vertexai"> |
| 2024 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> | 2040 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> |
| 2025 | <input id="use_makersuite_sysprompt" type="checkbox" /> | 2041 | <input id="use_makersuite_sysprompt" type="checkbox" /> |
| 2026 | <span> | 2042 | <span> |
| 2027 | <span data-i18n="Use system prompt">Use system prompt</span> | 2043 | <span data-i18n="Use system prompt">Use system prompt</span> |
| 2028 | <i class="opacity50p fa-solid fa-circle-info" title="Gemini 1.5/2.0 Pro/Flash"></i> | 2044 | <i class="opacity50p fa-solid fa-circle-info" title="Gemini 1.5+, LearnLM"></i> |
| 2029 | </span> | 2045 | </span> |
| 2030 | </label> | 2046 | </label> |
| 2031 | <div class="toggle-description justifyLeft marginBot5"> | 2047 | <div class="toggle-description justifyLeft marginBot5"> |
| @@ -2034,31 +2050,43 @@ | |||
| 2034 | </span> | 2050 | </span> |
| 2035 | </div> | 2051 | </div> |
| 2036 | </div> | 2052 | </div> |
| 2037 | <div class="range-block" data-source="deepseek,openrouter,custom,claude,xai"> | 2053 | <div class="range-block" data-source="deepseek,openrouter,custom,claude,xai,makersuite"> |
| 2038 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> | 2054 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> |
| 2039 | <input id="openai_show_thoughts" type="checkbox" /> | 2055 | <input id="openai_show_thoughts" type="checkbox" /> |
| 2040 | <span> | ||
| 2041 | <span data-i18n="Request model reasoning">Request model reasoning</span> | 2056 | <span data-i18n="Request model reasoning">Request model reasoning</span> |
| 2042 | <i class="opacity50p fa-solid fa-circle-info" title="DeepSeek Reasoner"></i> | ||
| 2043 | </span> | ||
| 2044 | </label> | 2057 | </label> |
| 2045 | <div class="toggle-description justifyLeft marginBot5"> | 2058 | <div class="toggle-description justifyLeft marginBot5"> |
| 2046 | <span data-i18n="Allows the model to return its thinking process."> | 2059 | <span data-i18n="Allows the model to return its thinking process."> |
| 2047 | Allows the model to return its thinking process. | 2060 | Allows the model to return its thinking process. |
| 2048 | </span> | 2061 | </span> |
| 2062 | <span data-i18n="This setting affects visibility only."> | ||
| 2063 | This setting affects visibility only. | ||
| 2064 | </span> | ||
| 2049 | </div> | 2065 | </div> |
| 2050 | </div> | 2066 | </div> |
| 2051 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai"> | 2067 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai,makersuite,vertexai,openrouter,pollinations"> |
| 2052 | <div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models. Currently supported values are low, medium, and high. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models."> | 2068 | <div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models."> |
| 2053 | <label for="openai_reasoning_effort"> | 2069 | <label for="openai_reasoning_effort"> |
| 2054 | <span data-i18n="Reasoning Effort">Reasoning Effort</span> | 2070 | <span data-i18n="Reasoning Effort">Reasoning Effort</span> |
| 2055 | <i data-source="claude" class="opacity50p fa-solid fa-circle-info" title="Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%), but minimum 1024 tokens."></i> | 2071 | <a href="https://docs.sillytavern.app/usage/prompts/reasoning/#reasoning-effort" target="_blank" class="opacity50p fa-solid fa-circle-question"></a> |
| 2056 | </label> | 2072 | </label> |
| 2057 | <select id="openai_reasoning_effort"> | 2073 | <select id="openai_reasoning_effort"> |
| 2074 | <option data-i18n="openai_reasoning_effort_auto" value="auto">Auto</option> | ||
| 2075 | <option data-i18n="openai_reasoning_effort_minimum" value="min">Mininum</option> | ||
| 2058 | <option data-i18n="openai_reasoning_effort_low" value="low">Low</option> | 2076 | <option data-i18n="openai_reasoning_effort_low" value="low">Low</option> |
| 2059 | <option data-i18n="openai_reasoning_effort_medium" value="medium">Medium</option> | 2077 | <option data-i18n="openai_reasoning_effort_medium" value="medium">Medium</option> |
| 2060 | <option data-i18n="openai_reasoning_effort_high" value="high">High</option> | 2078 | <option data-i18n="openai_reasoning_effort_high" value="high">High</option> |
| 2079 | <option data-i18n="openai_reasoning_effort_maximum" value="max">Maximum</option> | ||
| 2061 | </select> | 2080 | </select> |
| 2081 | <div class="toggle-description justifyLeft marginBot5" data-source="openai,custom,xai,openrouter" data-i18n="OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level."> | ||
| 2082 | OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level. | ||
| 2083 | </div> | ||
| 2084 | <div class="toggle-description justifyLeft marginBot5" data-source="claude" data-i18n="Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking."> | ||
| 2085 | Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking. | ||
| 2086 | </div> | ||
| 2087 | <div class="toggle-description justifyLeft marginBot5" data-source="makersuite,vertexai" data-i18n="Allocates a portion of the response length for thinking (min: 0 tokens, low: 10%, medium: 25%, high: 50%, max: 24576 tokens). Auto lets the model decide."> | ||
| 2088 | Allocates a portion of the response length for thinking (min: 0 tokens, low: 10%, medium: 25%, high: 50%, max: 24576 tokens). Auto lets the model decide. | ||
| 2089 | </div> | ||
| 2062 | </div> | 2090 | </div> |
| 2063 | </div> | 2091 | </div> |
| 2064 | <div class="range-block" data-source="claude"> | 2092 | <div class="range-block" data-source="claude"> |
| @@ -2080,9 +2108,7 @@ | |||
| 2080 | </div> | 2108 | </div> |
| 2081 | <label for="claude_use_sysprompt" class="checkbox_label widthFreeExpand"> | 2109 | <label for="claude_use_sysprompt" class="checkbox_label widthFreeExpand"> |
| 2082 | <input id="claude_use_sysprompt" type="checkbox" /> | 2110 | <input id="claude_use_sysprompt" type="checkbox" /> |
| 2083 | <span data-i18n="Use system prompt (Claude 2.1+ only)"> | 2111 | <span data-i18n="Use system prompt">Use system prompt</span> |
| 2084 | Use system prompt (Claude 2.1+ only) | ||
| 2085 | </span> | ||
| 2086 | </label> | 2112 | </label> |
| 2087 | <div class="toggle-description justifyLeft marginBot5"> | 2113 | <div class="toggle-description justifyLeft marginBot5"> |
| 2088 | <span data-i18n="Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt."> | 2114 | <span data-i18n="Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt."> |
| @@ -2494,8 +2520,8 @@ | |||
| 2494 | <option value="search" data-i18n="Search" hidden>A-Z</option> | 2520 | <option value="search" data-i18n="Search" hidden>A-Z</option> |
| 2495 | <option value="asc">A-Z</option> | 2521 | <option value="asc">A-Z</option> |
| 2496 | <option value="desc">Z-A</option> | 2522 | <option value="desc">Z-A</option> |
| 2497 | <option value="date_asc">Date Asc</option> | 2523 | <option data-i18n="Date Asc" value="date_asc">Date Asc</option> |
| 2498 | <option value="date_desc">Date Desc</option> | 2524 | <option data-i18n="Date Desc" value="date_desc">Date Desc</option> |
| 2499 | </select> | 2525 | </select> |
| 2500 | <select id="featherless_category_selection" class="text_pole"> | 2526 | <select id="featherless_category_selection" class="text_pole"> |
| 2501 | <option value="" disabled selected data-i18n="category">category</option> | 2527 | <option value="" disabled selected data-i18n="category">category</option> |
| @@ -2505,7 +2531,7 @@ | |||
| 2505 | <option value="All" data-i18n="All">All</option> | 2531 | <option value="All" data-i18n="All">All</option> |
| 2506 | </select> | 2532 | </select> |
| 2507 | <select id="featherless_class_selection" class="text_pole"> | 2533 | <select id="featherless_class_selection" class="text_pole"> |
| 2508 | <option value="" selected data-i18n="class">All Classes</option> | 2534 | <option value="" selected data-i18n="All Classes">All Classes</option> |
| 2509 | </select> | 2535 | </select> |
| 2510 | <div id="featherless_model_pagination_container" class="flex1"></div> | 2536 | <div id="featherless_model_pagination_container" class="flex1"></div> |
| 2511 | <i id="featherless_model_grid_toggle" class="fa-solid fa-table-cells-large menu_button" data-i18n="[title]Toggle grid view" title="Toggle grid view"></i> | 2537 | <i id="featherless_model_grid_toggle" class="fa-solid fa-table-cells-large menu_button" data-i18n="[title]Toggle grid view" title="Toggle grid view"></i> |
| @@ -2618,8 +2644,8 @@ | |||
| 2618 | </div> | 2644 | </div> |
| 2619 | <div data-tg-type="ollama"> | 2645 | <div data-tg-type="ollama"> |
| 2620 | <div class="flex-container flexFlowColumn"> | 2646 | <div class="flex-container flexFlowColumn"> |
| 2621 | <a href="https://github.com/jmorganca/ollama" target="_blank"> | 2647 | <a href="https://github.com/ollama/ollama" target="_blank"> |
| 2622 | jmorganca/ollama | 2648 | ollama/ollama |
| 2623 | </a> | 2649 | </a> |
| 2624 | </div> | 2650 | </div> |
| 2625 | <div class="flex1"> | 2651 | <div class="flex1"> |
| @@ -2753,16 +2779,18 @@ | |||
| 2753 | <option value="deepseek">DeepSeek</option> | 2779 | <option value="deepseek">DeepSeek</option> |
| 2754 | <option value="groq">Groq</option> | 2780 | <option value="groq">Groq</option> |
| 2755 | <option value="makersuite">Google AI Studio</option> | 2781 | <option value="makersuite">Google AI Studio</option> |
| 2782 | <option value="vertexai">Google Vertex AI (Express mode)</option> | ||
| 2756 | <option value="mistralai">MistralAI</option> | 2783 | <option value="mistralai">MistralAI</option> |
| 2757 | <option value="nanogpt">NanoGPT</option> | 2784 | <option value="nanogpt">NanoGPT</option> |
| 2758 | <option value="openrouter">OpenRouter</option> | 2785 | <option value="openrouter">OpenRouter</option> |
| 2759 | <option value="perplexity">Perplexity</option> | 2786 | <option value="perplexity">Perplexity</option> |
| 2787 | <option value="pollinations">Pollinations</option> | ||
| 2760 | <option value="scale">Scale</option> | 2788 | <option value="scale">Scale</option> |
| 2761 | <option value="windowai">Window AI</option> | 2789 | <option value="windowai">Window AI</option> |
| 2762 | <option value="xai">xAI (Grok)</option> | 2790 | <option value="xai">xAI (Grok)</option> |
| 2763 | </optgroup> | 2791 | </optgroup> |
| 2764 | </select> | 2792 | </select> |
| 2765 | <div class="inline-drawer wide100p" data-source="openai,claude,mistralai,makersuite,deepseek,xai"> | 2793 | <div class="inline-drawer wide100p" data-source="openai,claude,mistralai,makersuite,vertexai,deepseek,xai"> |
| 2766 | <div class="inline-drawer-toggle inline-drawer-header"> | 2794 | <div class="inline-drawer-toggle inline-drawer-header"> |
| 2767 | <b data-i18n="Reverse Proxy">Reverse Proxy</b> | 2795 | <b data-i18n="Reverse Proxy">Reverse Proxy</b> |
| 2768 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | 2796 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> |
| @@ -2808,6 +2836,7 @@ | |||
| 2808 | <input id="openai_reverse_proxy" type="text" class="text_pole" placeholder="https://api.openai.com/v1" /> | 2836 | <input id="openai_reverse_proxy" type="text" class="text_pole" placeholder="https://api.openai.com/v1" /> |
| 2809 | <small class="reverse_proxy_warning"> | 2837 | <small class="reverse_proxy_warning"> |
| 2810 | <span data-i18n="Doesn't work? Try adding">Doesn't work? Try adding</span> <code>/v1</code> <span data-i18n="at the end!">at the end!</span> | 2838 | <span data-i18n="Doesn't work? Try adding">Doesn't work? Try adding</span> <code>/v1</code> <span data-i18n="at the end!">at the end!</span> |
| 2839 | <code>/chat/completions</code> <b data-i18n="suffix will be added automatically.">suffix will be added automatically.</b> | ||
| 2811 | </small> | 2840 | </small> |
| 2812 | </div> | 2841 | </div> |
| 2813 | <div class="range-block-title justifyLeft" data-i18n="Proxy Password"> | 2842 | <div class="range-block-title justifyLeft" data-i18n="Proxy Password"> |
| @@ -2825,7 +2854,7 @@ | |||
| 2825 | </div> | 2854 | </div> |
| 2826 | </div> | 2855 | </div> |
| 2827 | </div> | 2856 | </div> |
| 2828 | <div id="ReverseProxyWarningMessage" data-source="openai,claude,mistralai,makersuite,deepseek,xai"> | 2857 | <div id="ReverseProxyWarningMessage" data-source="openai,claude,mistralai,makersuite,vertexai,deepseek,xai"> |
| 2829 | <div class="reverse_proxy_warning"> | 2858 | <div class="reverse_proxy_warning"> |
| 2830 | <b> | 2859 | <b> |
| 2831 | <div data-i18n="Using a proxy that you're not running yourself is a risk to your data privacy."> | 2860 | <div data-i18n="Using a proxy that you're not running yourself is a risk to your data privacy."> |
| @@ -2884,10 +2913,7 @@ | |||
| 2884 | </optgroup> | 2913 | </optgroup> |
| 2885 | <optgroup label="GPT-4o mini"> | 2914 | <optgroup label="GPT-4o mini"> |
| 2886 | <option value="gpt-4o-mini">gpt-4o-mini</option> | 2915 | <option value="gpt-4o-mini">gpt-4o-mini</option> |
| 2887 | <option value="gpt-4o-2024-11-20">gpt-4o-2024-11-20</option> | 2916 | <option value="gpt-4o-mini-2024-07-18">gpt-4o-mini-2024-07-18</option> |
| 2888 | <option value="gpt-4o-2024-08-06">gpt-4o-2024-08-06</option> | ||
| 2889 | <option value="gpt-4o-2024-05-13">gpt-4o-2024-05-13</option> | ||
| 2890 | <option value="chatgpt-4o-latest">chatgpt-4o-latest</option> | ||
| 2891 | </optgroup> | 2917 | </optgroup> |
| 2892 | <optgroup label="GPT-4.1"> | 2918 | <optgroup label="GPT-4.1"> |
| 2893 | <option value="gpt-4.1">gpt-4.1</option> | 2919 | <option value="gpt-4.1">gpt-4.1</option> |
| @@ -2968,6 +2994,10 @@ | |||
| 2968 | <h4 data-i18n="Claude Model">Claude Model</h4> | 2994 | <h4 data-i18n="Claude Model">Claude Model</h4> |
| 2969 | <select id="model_claude_select"> | 2995 | <select id="model_claude_select"> |
| 2970 | <optgroup label="Versions"> | 2996 | <optgroup label="Versions"> |
| 2997 | <option value="claude-opus-4-0">claude-opus-4-0</option> | ||
| 2998 | <option value="claude-opus-4-20250514">claude-opus-4-20250514</option> | ||
| 2999 | <option value="claude-sonnet-4-0">claude-sonnet-4-0</option> | ||
| 3000 | <option value="claude-sonnet-4-20250514">claude-sonnet-4-20250514</option> | ||
| 2971 | <option value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option> | 3001 | <option value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option> |
| 2972 | <option value="claude-3-7-sonnet-20250219">claude-3-7-sonnet-20250219</option> | 3002 | <option value="claude-3-7-sonnet-20250219">claude-3-7-sonnet-20250219</option> |
| 2973 | <option value="claude-3-5-sonnet-latest">claude-3-5-sonnet-latest</option> | 3003 | <option value="claude-3-5-sonnet-latest">claude-3-5-sonnet-latest</option> |
| @@ -3145,53 +3175,87 @@ | |||
| 3145 | <div> | 3175 | <div> |
| 3146 | <h4 data-i18n="Google Model">Google Model</h4> | 3176 | <h4 data-i18n="Google Model">Google Model</h4> |
| 3147 | <select id="model_google_select"> | 3177 | <select id="model_google_select"> |
| 3148 | <optgroup label="Primary"> | 3178 | <optgroup label="Gemini 2.5"> |
| 3149 | <option value="gemini-2.0-flash">Gemini 2.0 Flash</option> | 3179 | <option value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> |
| 3150 | <option value="gemini-1.5-pro">Gemini 1.5 Pro</option> | 3180 | <option value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> |
| 3151 | <option value="gemini-1.5-flash">Gemini 1.5 Flash</option> | 3181 | <option value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option> |
| 3152 | <option value="gemini-1.0-pro">Gemini 1.0 Pro (Deprecated)</option> | 3182 | <option value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option> |
| 3153 | <option value="gemini-pro">Gemini Pro (1.0) (Deprecated)</option> | 3183 | <option value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> |
| 3154 | <option value="gemini-ultra">Gemini Ultra (1.0)</option> | 3184 | </optgroup> |
| 3155 | <option value="gemini-1.0-ultra-latest">Gemini 1.0 Ultra</option> | 3185 | <optgroup label="Gemini 2.0"> |
| 3186 | <option value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option> | ||
| 3187 | <option value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option> | ||
| 3188 | <option value="gemini-exp-1206">gemini-exp-1206 → 2.5-pro-exp-03-25</option> | ||
| 3189 | <option value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> | ||
| 3190 | <option value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option> | ||
| 3191 | <option value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option> | ||
| 3192 | <option value="gemini-2.0-flash">gemini-2.0-flash</option> | ||
| 3193 | <option value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21 → 2.5-flash-preview-04-17</option> | ||
| 3194 | <option value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219 → 2.5-flash-preview-04-17</option> | ||
| 3195 | <option value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp → 2.5-flash-preview-04-17</option> | ||
| 3196 | <option value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option> | ||
| 3197 | <option value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option> | ||
| 3198 | <option value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option> | ||
| 3199 | </optgroup> | ||
| 3200 | <optgroup label="Gemini 1.5"> | ||
| 3201 | <option value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | ||
| 3202 | <option value="gemini-1.5-pro-002">gemini-1.5-pro-002</option> | ||
| 3203 | <option value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> | ||
| 3204 | <option value="gemini-1.5-pro">gemini-1.5-pro</option> | ||
| 3205 | <option value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> | ||
| 3206 | <option value="gemini-1.5-flash-002">gemini-1.5-flash-002</option> | ||
| 3207 | <option value="gemini-1.5-flash-001">gemini-1.5-flash-001</option> | ||
| 3208 | <option value="gemini-1.5-flash">gemini-1.5-flash</option> | ||
| 3209 | <option value="gemini-1.5-flash-8b-001">gemini-1.5-flash-8b-001</option> | ||
| 3210 | <option value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> | ||
| 3211 | <option value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> | ||
| 3212 | <option value="gemini-1.5-flash-8b">gemini-1.5-flash-8b</option> | ||
| 3156 | </optgroup> | 3213 | </optgroup> |
| 3157 | <optgroup label="Gemma"> | 3214 | <optgroup label="Gemma"> |
| 3158 | <option value="gemma-3-27b-it">Gemma 3 27B</option> | 3215 | <option value="gemma-3-27b-it">gemma-3-27b-it</option> |
| 3216 | <option value="gemma-3-12b-it">gemma-3-12b-it</option> | ||
| 3217 | <option value="gemma-3-4b-it">gemma-3-4b-it</option> | ||
| 3218 | <option value="gemma-3-1b-it">gemma-3-1b-it</option> | ||
| 3159 | </optgroup> | 3219 | </optgroup> |
| 3160 | <optgroup label="Subversions"> | 3220 | <optgroup label="LearnLM"> |
| 3161 | <option value="gemini-2.5-pro-preview-03-25">Gemini 2.5 Pro Preview 2025-03-25</option> | 3221 | <option value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option> |
| 3162 | <option value="gemini-2.5-pro-exp-03-25">Gemini 2.5 Pro Experimental 2025-03-25</option> | 3222 | <option value="learnlm-1.5-pro-experimental">learnlm-1.5-pro-experimental</option> |
| 3163 | <option value="gemini-2.0-pro-exp">Gemini 2.0 Pro Experimental</option> | ||
| 3164 | <option value="gemini-2.0-pro-exp-02-05">Gemini 2.0 Pro Experimental 2025-02-05</option> | ||
| 3165 | <option value="gemini-2.5-flash-preview-04-17">Gemini 2.5 Flash Preview 2025-04-17</option> | ||
| 3166 | <option value="gemini-2.0-flash-lite-preview">Gemini 2.0 Flash-Lite Preview</option> | ||
| 3167 | <option value="gemini-2.0-flash-lite-preview-02-05">Gemini 2.0 Flash-Lite Preview 2025-02-05</option> | ||
| 3168 | <option value="gemini-2.0-flash-001">Gemini 2.0 Flash [001]</option> | ||
| 3169 | <option value="gemini-2.0-flash-thinking-exp">Gemini 2.0 Flash Thinking Experimental</option> | ||
| 3170 | <option value="gemini-2.0-flash-thinking-exp-01-21">Gemini 2.0 Flash Thinking Experimental 2025-01-21</option> | ||
| 3171 | <option value="gemini-2.0-flash-thinking-exp-1219">Gemini 2.0 Flash Thinking Experimental 2024-12-19</option> | ||
| 3172 | <option value="gemini-2.0-flash-exp">Gemini 2.0 Flash Experimental</option> | ||
| 3173 | <option value="gemini-2.0-flash-exp-image-generation">Gemini 2.0 Flash (Image Generation) Experimental</option> | ||
| 3174 | <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option> | ||
| 3175 | <option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option> | ||
| 3176 | <option value="gemini-exp-1206">Gemini Experimental 2024-12-06</option> | ||
| 3177 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experimental 2024-08-01</option> | ||
| 3178 | <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experimental 2024-08-27</option> | ||
| 3179 | <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option> | ||
| 3180 | <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option> | ||
| 3181 | <option value="gemini-1.5-pro-002">Gemini 1.5 Pro [002]</option> | ||
| 3182 | <option value="gemini-1.5-flash-8b">Gemini 1.5 Flash 8B</option> | ||
| 3183 | <option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experimental 2024-08-27</option> | ||
| 3184 | <option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experimental 2024-08-27</option> | ||
| 3185 | <option value="gemini-1.5-flash-8b-exp-0924">Gemini 1.5 Flash 8B Experimental 2024-09-24</option> | ||
| 3186 | <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option> | ||
| 3187 | <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option> | ||
| 3188 | <option value="gemini-1.5-flash-002">Gemini 1.5 Flash [002]</option> | ||
| 3189 | <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest] (Deprecated)</option> | ||
| 3190 | <option value="gemini-1.0-pro-001">Gemini 1.0 Pro (Tuning) [001] (Deprecated)</option> | ||
| 3191 | </optgroup> | 3223 | </optgroup> |
| 3192 | </select> | 3224 | </select> |
| 3193 | </div> | 3225 | </div> |
| 3194 | </form> | 3226 | </form> |
| 3227 | <div id="vertexai_form" data-source="vertexai"> | ||
| 3228 | <h4> | ||
| 3229 | <span data-i18n="Google Vertex AI API Key"> | ||
| 3230 | Google Vertex AI API Key | ||
| 3231 | </span> | ||
| 3232 | <a href="https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview" data-i18n="(Express mode keys only)" target="_blank" rel="noopener noreferrer"> | ||
| 3233 | (Express mode keys only) | ||
| 3234 | </a> | ||
| 3235 | </h4> | ||
| 3236 | <div class="flex-container"> | ||
| 3237 | <input id="api_key_vertexai" name="api_key_vertexai" class="text_pole flex1" value="" type="text" autocomplete="off"> | ||
| 3238 | <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_vertexai"></div> | ||
| 3239 | </div> | ||
| 3240 | <div data-for="api_key_vertexai" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page."> | ||
| 3241 | For privacy reasons, your API key will be hidden after you reload the page. | ||
| 3242 | </div> | ||
| 3243 | <div> | ||
| 3244 | <h4 data-i18n="Google Model">Google Model</h4> | ||
| 3245 | <select id="model_vertexai_select"> | ||
| 3246 | <optgroup label="Gemini 2.5"> | ||
| 3247 | <option value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> | ||
| 3248 | <option value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> | ||
| 3249 | <option value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option> | ||
| 3250 | <option value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> | ||
| 3251 | </optgroup> | ||
| 3252 | <optgroup label="Gemini 2.0"> | ||
| 3253 | <option value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> | ||
| 3254 | <option value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option> | ||
| 3255 | </optgroup> | ||
| 3256 | </select> | ||
| 3257 | </div> | ||
| 3258 | </div> | ||
| 3195 | <form id="mistralai_form" data-source="mistralai" action="javascript:void(null);" method="post" enctype="multipart/form-data"> | 3259 | <form id="mistralai_form" data-source="mistralai" action="javascript:void(null);" method="post" enctype="multipart/form-data"> |
| 3196 | <h4 data-i18n="MistralAI API Key">MistralAI API Key</h4> | 3260 | <h4 data-i18n="MistralAI API Key">MistralAI API Key</h4> |
| 3197 | <div class="flex-container"> | 3261 | <div class="flex-container"> |
| @@ -3221,6 +3285,7 @@ | |||
| 3221 | <option value="codestral-mamba-latest">codestral-mamba-latest</option> | 3285 | <option value="codestral-mamba-latest">codestral-mamba-latest</option> |
| 3222 | <option value="pixtral-12b-latest">pixtral-12b-latest</option> | 3286 | <option value="pixtral-12b-latest">pixtral-12b-latest</option> |
| 3223 | <option value="pixtral-large-latest">pixtral-large-latest</option> | 3287 | <option value="pixtral-large-latest">pixtral-large-latest</option> |
| 3288 | <option value="devstral-small-latest">devstral-small-latest</option> | ||
| 3224 | </optgroup> | 3289 | </optgroup> |
| 3225 | <optgroup label="Sub-versions"> | 3290 | <optgroup label="Sub-versions"> |
| 3226 | <option value="open-mistral-nemo-2407">open-mistral-nemo-2407</option> | 3291 | <option value="open-mistral-nemo-2407">open-mistral-nemo-2407</option> |
| @@ -3235,6 +3300,7 @@ | |||
| 3235 | <option value="mistral-small-2501">mistral-small-2501</option> | 3300 | <option value="mistral-small-2501">mistral-small-2501</option> |
| 3236 | <option value="mistral-small-2503">mistral-small-2503</option> | 3301 | <option value="mistral-small-2503">mistral-small-2503</option> |
| 3237 | <option value="mistral-medium-2312">mistral-medium-2312</option> | 3302 | <option value="mistral-medium-2312">mistral-medium-2312</option> |
| 3303 | <option value="mistral-medium-2505">mistral-medium-2505</option> | ||
| 3238 | <option value="mistral-large-2402">mistral-large-2402</option> | 3304 | <option value="mistral-large-2402">mistral-large-2402</option> |
| 3239 | <option value="mistral-large-2407">mistral-large-2407</option> | 3305 | <option value="mistral-large-2407">mistral-large-2407</option> |
| 3240 | <option value="mistral-large-2411">mistral-large-2411</option> | 3306 | <option value="mistral-large-2411">mistral-large-2411</option> |
| @@ -3248,6 +3314,7 @@ | |||
| 3248 | <option value="codestral-2501">codestral-2501</option> | 3314 | <option value="codestral-2501">codestral-2501</option> |
| 3249 | <option value="pixtral-12b-2409">pixtral-12b-2409</option> | 3315 | <option value="pixtral-12b-2409">pixtral-12b-2409</option> |
| 3250 | <option value="pixtral-large-2411">pixtral-large-2411</option> | 3316 | <option value="pixtral-large-2411">pixtral-large-2411</option> |
| 3317 | <option value="devstral-small-2505">devstral-small-2505</option> | ||
| 3251 | </optgroup> | 3318 | </optgroup> |
| 3252 | <optgroup id="mistralai_other_models" label="Other"></optgroup> | 3319 | <optgroup id="mistralai_other_models" label="Other"></optgroup> |
| 3253 | </select> | 3320 | </select> |
| @@ -3403,6 +3470,7 @@ | |||
| 3403 | <div> | 3470 | <div> |
| 3404 | <small> | 3471 | <small> |
| 3405 | <span data-i18n="Doesn't work? Try adding">Doesn't work? Try adding</span> <code>/v1</code> <span data-i18n="at the end!">at the end!</span> | 3472 | <span data-i18n="Doesn't work? Try adding">Doesn't work? Try adding</span> <code>/v1</code> <span data-i18n="at the end!">at the end!</span> |
| 3473 | <code>/chat/completions</code> <b data-i18n="suffix will be added automatically.">suffix will be added automatically.</b> | ||
| 3406 | </small> | 3474 | </small> |
| 3407 | </div> | 3475 | </div> |
| 3408 | <h4> | 3476 | <h4> |
| @@ -3468,13 +3536,36 @@ | |||
| 3468 | <option value="grok-beta">grok-beta</option> | 3536 | <option value="grok-beta">grok-beta</option> |
| 3469 | </select> | 3537 | </select> |
| 3470 | </div> | 3538 | </div> |
| 3471 | <div id="prompt_post_porcessing_form" data-source="custom,openrouter"> | 3539 | <div id="pollinations_form" data-source="pollinations"> |
| 3472 | <h4 data-i18n="Prompt Post-Processing">Prompt Post-Processing</h4> | 3540 | <h4 data-i18n="Pollinations Model">Pollinations Model</h4> |
| 3541 | <select id="model_pollinations_select"> | ||
| 3542 | <!-- Populated by JavaScript --> | ||
| 3543 | </select> | ||
| 3544 | <div class="info-block hint"> | ||
| 3545 | <a href="https://pollinations.ai/" target="_blank" rel="noopener noreferrer" data-i18n="Provided free of charge by Pollinations.AI"> | ||
| 3546 | Provided free of charge by Pollinations.AI | ||
| 3547 | </a> | ||
| 3548 | <br> | ||
| 3549 | <span data-i18n="Avoid sending sensitive information. Provider's outputs may include ads."> | ||
| 3550 | Avoid sending sensitive information. Provider's outputs may include ads. | ||
| 3551 | </span> | ||
| 3552 | </div> | ||
| 3553 | </div> | ||
| 3554 | <div id="prompt_post_processing_form"> | ||
| 3555 | <h4> | ||
| 3556 | <span data-i18n="Prompt Post-Processing"> | ||
| 3557 | Prompt Post-Processing | ||
| 3558 | </span> | ||
| 3559 | <a href="https://docs.sillytavern.app/usage/api-connections/openai/#prompt-post-processing" class="notes-link" target="_blank"> | ||
| 3560 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 3561 | </a> | ||
| 3562 | </h4> | ||
| 3473 | <select id="custom_prompt_post_processing" class="text_pole" title="Applies additional processing to the prompt before sending it to the API." data-i18n="[title]Applies additional processing to the prompt before sending it to the API."> | 3563 | <select id="custom_prompt_post_processing" class="text_pole" title="Applies additional processing to the prompt before sending it to the API." data-i18n="[title]Applies additional processing to the prompt before sending it to the API."> |
| 3474 | <option data-i18n="prompt_post_processing_none" value="">None</option> | 3564 | <option data-i18n="prompt_post_processing_none" value="">None</option> |
| 3475 | <option data-i18n="prompt_post_processing_merge" value="merge">Merge consecutive roles</option> | 3565 | <option data-i18n="prompt_post_processing_merge" value="merge">Merge consecutive roles</option> |
| 3476 | <option data-i18n="prompt_post_processing_semi" value="semi">Semi-strict (alternating roles)</option> | 3566 | <option data-i18n="prompt_post_processing_semi" value="semi">Semi-strict (alternating roles)</option> |
| 3477 | <option data-i18n="prompt_post_processing_strict" value="strict">Strict (user first, alternating roles)</option> | 3567 | <option data-i18n="prompt_post_processing_strict" value="strict">Strict (user first, alternating roles)</option> |
| 3568 | <option data-i18n="prompt_post_processing_single" value="single">Single user message</option> | ||
| 3478 | </select> | 3569 | </select> |
| 3479 | </div> | 3570 | </div> |
| 3480 | <div class="flex-container flex"> | 3571 | <div class="flex-container flex"> |
| @@ -3502,7 +3593,7 @@ | |||
| 3502 | <div class="drawer-toggle"> | 3593 | <div class="drawer-toggle"> |
| 3503 | <div class="drawer-icon fa-solid fa-font fa-fw closedIcon" title="AI Response Formatting" data-i18n="[title]AI Response Formatting"></div> | 3594 | <div class="drawer-icon fa-solid fa-font fa-fw closedIcon" title="AI Response Formatting" data-i18n="[title]AI Response Formatting"></div> |
| 3504 | </div> | 3595 | </div> |
| 3505 | <div id="AdvancedFormatting" class="drawer-content"> | 3596 | <div id="AdvancedFormatting" class="drawer-content closedDrawer"> |
| 3506 | <div class="flex-container alignItemsBaseline"> | 3597 | <div class="flex-container alignItemsBaseline"> |
| 3507 | <h3 class="margin0 flex1 flex-container alignItemsBaseline"> | 3598 | <h3 class="margin0 flex1 flex-container alignItemsBaseline"> |
| 3508 | <span data-i18n="Advanced Formatting"> | 3599 | <span data-i18n="Advanced Formatting"> |
| @@ -3621,11 +3712,6 @@ | |||
| 3621 | <small data-i18n="Names as Stop Strings">Names as Stop Strings</small> | 3712 | <small data-i18n="Names as Stop Strings">Names as Stop Strings</small> |
| 3622 | </label> | 3713 | </label> |
| 3623 | </div> | 3714 | </div> |
| 3624 | |||
| 3625 | <label class="checkbox_label" title="Includes Post-History Instructions at the end of the prompt, if defined in the character card AND ''Prefer Char. Instructions'' is enabled. THIS IS NOT RECOMMENDED FOR TEXT COMPLETION MODELS, CAN LEAD TO BAD OUTPUT." data-i18n="[title]context_allow_post_history_instructions"> | ||
| 3626 | <input id="context_allow_jailbreak" type="checkbox" /> | ||
| 3627 | <small data-i18n="Allow Post-History Instructions">Allow Post-History Instructions</small> | ||
| 3628 | </label> | ||
| 3629 | </div> | 3715 | </div> |
| 3630 | </div> | 3716 | </div> |
| 3631 | </div> | 3717 | </div> |
| @@ -3827,9 +3913,7 @@ | |||
| 3827 | </label> | 3913 | </label> |
| 3828 | </div> | 3914 | </div> |
| 3829 | </h4> | 3915 | </h4> |
| 3830 | <div id="SystemPromptBlock"> | 3916 | <div id="SystemPromptBlock" class="marginBot10"> |
| 3831 | |||
| 3832 | |||
| 3833 | <div class="flex-container" title="Select your current System Prompt" data-i18n="[title]Select your current System Prompt"> | 3917 | <div class="flex-container" title="Select your current System Prompt" data-i18n="[title]Select your current System Prompt"> |
| 3834 | <select id="sysprompt_select" data-preset-manager-for="sysprompt" class="flex1 text_pole"></select> | 3918 | <select id="sysprompt_select" data-preset-manager-for="sysprompt" class="flex1 text_pole"></select> |
| 3835 | <div class="flex-container margin0 justifyCenter gap3px"> | 3919 | <div class="flex-container margin0 justifyCenter gap3px"> |
| @@ -3851,10 +3935,14 @@ | |||
| 3851 | </label> | 3935 | </label> |
| 3852 | <textarea id="sysprompt_content" class="text_pole textarea_compact autoSetHeight"></textarea> | 3936 | <textarea id="sysprompt_content" class="text_pole textarea_compact autoSetHeight"></textarea> |
| 3853 | </div> | 3937 | </div> |
| 3854 | </div> | ||
| 3855 | 3938 | ||
| 3856 | <div> | 3939 | <div> |
| 3857 | | 3940 | <label for="sysprompt_post_history" class="flex-container"> |
| 3941 | <small data-i18n="Post-History Instructions">Post-History Instructions</small> | ||
| 3942 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="sysprompt_post_history" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 3943 | </label> | ||
| 3944 | <textarea id="sysprompt_post_history" class="text_pole textarea_compact autoSetHeight"></textarea> | ||
| 3945 | </div> | ||
| 3858 | </div> | 3946 | </div> |
| 3859 | 3947 | ||
| 3860 | <div> | 3948 | <div> |
| @@ -4314,20 +4402,32 @@ | |||
| 4314 | <div name="AvatarAndChatDisplay" class="flex-container flexFlowColumn"> | 4402 | <div name="AvatarAndChatDisplay" class="flex-container flexFlowColumn"> |
| 4315 | <div class="flex-container alignItemsBaseline"> | 4403 | <div class="flex-container alignItemsBaseline"> |
| 4316 | <span data-i18n="Avatar Style:">Avatars:</span> | 4404 | <span data-i18n="Avatar Style:">Avatars:</span> |
| 4317 | <select id="avatar_style" class="widthNatural flex1 margin0"> | 4405 | <select id="avatar_style" class="widthNatural flex1 margin0 text_pole"> |
| 4318 | <option value="0" data-i18n="Circle">Circle</option> | 4406 | <option value="0" data-i18n="Circle">Circle</option> |
| 4319 | <option value="2" data-i18n="Square">Square</option> | 4407 | <option value="2" data-i18n="Square">Square</option> |
| 4408 | <option value="3" data-i18n="Rounded">Rounded</option> | ||
| 4320 | <option value="1" data-i18n="Rectangle">Rectangle</option> | 4409 | <option value="1" data-i18n="Rectangle">Rectangle</option> |
| 4321 | </select> | 4410 | </select> |
| 4322 | </div> | 4411 | </div> |
| 4323 | <div class="flex-container alignItemsBaseline"> | 4412 | <div class="flex-container alignItemsBaseline"> |
| 4324 | <span data-i18n="Chat Style:">Chat Style:</span><br> | 4413 | <span data-i18n="Chat Style:">Chat Style:</span> |
| 4325 | <select id="chat_display" class="widthNatural flex1 margin0"> | 4414 | <select id="chat_display" class="widthNatural flex1 margin0 text_pole"> |
| 4326 | <option value="0" data-i18n="Flat">Flat</option> | 4415 | <option value="0" data-i18n="Flat">Flat</option> |
| 4327 | <option value="1" data-i18n="Bubbles">Bubbles</option> | 4416 | <option value="1" data-i18n="Bubbles">Bubbles</option> |
| 4328 | <option value="2" data-i18n="Document">Document</option> | 4417 | <option value="2" data-i18n="Document">Document</option> |
| 4329 | </select> | 4418 | </select> |
| 4330 | </div> | 4419 | </div> |
| 4420 | <div class="flex-container alignItemsBaseline"> | ||
| 4421 | <span data-i18n="Notifications:">Notifications:</span> | ||
| 4422 | <select id="toastr_position" class="widthNatural flex1 margin0 text_pole"> | ||
| 4423 | <option value="toast-top-left" data-i18n="Top Left">Top Left</option> | ||
| 4424 | <option value="toast-top-center" data-i18n="Top Center">Top Center</option> | ||
| 4425 | <option value="toast-top-right" data-i18n="Top Right">Top Right</option> | ||
| 4426 | <option value="toast-bottom-left" data-i18n="Bottom Left">Bottom Left</option> | ||
| 4427 | <option value="toast-bottom-center" data-i18n="Bottom Center">Bottom Center</option> | ||
| 4428 | <option value="toast-bottom-right" data-i18n="Bottom Right">Bottom Right</option> | ||
| 4429 | </select> | ||
| 4430 | </div> | ||
| 4331 | </div> | 4431 | </div> |
| 4332 | <div class="inline-drawer wide100p flexFlowColumn"> | 4432 | <div class="inline-drawer wide100p flexFlowColumn"> |
| 4333 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Specify colors for your theme." data-i18n="[title]Specify colors for your theme."> | 4433 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Specify colors for your theme." data-i18n="[title]Specify colors for your theme."> |
| @@ -4499,10 +4599,11 @@ | |||
| 4499 | <small data-i18n="Tags as Folders">Tags as Folders</small> | 4599 | <small data-i18n="Tags as Folders">Tags as Folders</small> |
| 4500 | <i title="Recent change: Tags must be marked as folders in the Tag Management menu to appear as such. Click here to bring it up." data-i18n="[title]Tags_as_Folders_desc" class="tags_view right_menu_button fa-solid fa-circle-exclamation"></i> | 4600 | <i title="Recent change: Tags must be marked as folders in the Tag Management menu to appear as such. Click here to bring it up." data-i18n="[title]Tags_as_Folders_desc" class="tags_view right_menu_button fa-solid fa-circle-exclamation"></i> |
| 4501 | </label> | 4601 | </label> |
| 4502 | 4602 | <label for="click_to_edit" class="checkbox_label" title="Click the message text in the chat log to edit it." data-i18n="[title]Click the message text in the chat log to edit it."> | |
| 4603 | <input id="click_to_edit" type="checkbox" /> | ||
| 4604 | <small data-i18n="Click to Edit">Click to Edit</small> | ||
| 4605 | </label> | ||
| 4503 | </div> | 4606 | </div> |
| 4504 | |||
| 4505 | |||
| 4506 | </div> | 4607 | </div> |
| 4507 | </div> | 4608 | </div> |
| 4508 | <div name="UserSettingsSecondColumn" id="UI-Customization" class="flex-container flexFlowColumn wide100p flexNoGap flex1"> | 4609 | <div name="UserSettingsSecondColumn" id="UI-Customization" class="flex-container flexFlowColumn wide100p flexNoGap flex1"> |
| @@ -4780,6 +4881,10 @@ | |||
| 4780 | <input id="show_group_chat_queue" type="checkbox" /> | 4881 | <input id="show_group_chat_queue" type="checkbox" /> |
| 4781 | <small data-i18n="Show group chat queue">Show group chat queue</small> | 4882 | <small data-i18n="Show group chat queue">Show group chat queue</small> |
| 4782 | </label> | 4883 | </label> |
| 4884 | <label class="checkbox_label" for="pin_styles" title="Always render style tags from greetings, even if the message is unloaded due to lazy loading." data-i18n="[title]Always render style tags from greetings, even if the message is unloaded due to lazy loading."> | ||
| 4885 | <input id="pin_styles" type="checkbox" /> | ||
| 4886 | <small data-i18n="Pin greeting message styles">Pin greeting message styles</small> | ||
| 4887 | </label> | ||
| 4783 | <div class="inline-drawer wide100p flexFlowColumn"> | 4888 | <div class="inline-drawer wide100p flexFlowColumn"> |
| 4784 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria"> | 4889 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria"> |
| 4785 | <b><span data-i18n="Auto-swipe">Auto-swipe</span></b> | 4890 | <b><span data-i18n="Auto-swipe">Auto-swipe</span></b> |
| @@ -4966,7 +5071,7 @@ | |||
| 4966 | <div id="bg_menu_content" class="bg_list"> | 5071 | <div id="bg_menu_content" class="bg_list"> |
| 4967 | <form id="form_bg_download" class="bg_example no-border no-shadow" action="javascript:void(null);" method="post" enctype="multipart/form-data"> | 5072 | <form id="form_bg_download" class="bg_example no-border no-shadow" action="javascript:void(null);" method="post" enctype="multipart/form-data"> |
| 4968 | <label class="input-file"> | 5073 | <label class="input-file"> |
| 4969 | <input type="file" id="add_bg_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp"> | 5074 | <input type="file" id="add_bg_button" name="avatar" accept="image/*, video/*"> |
| 4970 | <div class="bg_example no-border no-shadow add_bg_but" style="background-image: url('/img/addbg3.png');"></div> | 5075 | <div class="bg_example no-border no-shadow add_bg_but" style="background-image: url('/img/addbg3.png');"></div> |
| 4971 | </label> | 5076 | </label> |
| 4972 | </form> | 5077 | </form> |
| @@ -5332,6 +5437,9 @@ | |||
| 5332 | <option id="import_tags" data-i18n="Import Tags"> | 5437 | <option id="import_tags" data-i18n="Import Tags"> |
| 5333 | Import Tags | 5438 | Import Tags |
| 5334 | </option> | 5439 | </option> |
| 5440 | <option id="set_as_assistant" data-i18n="Set / Unset as Welcome Page Assistant"> | ||
| 5441 | Set / Unset as Welcome Page Assistant | ||
| 5442 | </option> | ||
| 5335 | <!--<option id="dupe_button"> | 5443 | <!--<option id="dupe_button"> |
| 5336 | Duplicate | 5444 | Duplicate |
| 5337 | </option> | 5445 | </option> |
| @@ -5356,9 +5464,10 @@ | |||
| 5356 | </div> | 5464 | </div> |
| 5357 | <hr> | 5465 | <hr> |
| 5358 | <div id="spoiler_free_desc" class="flex-container flexFlowColumn flex1 flexNoGap"> | 5466 | <div id="spoiler_free_desc" class="flex-container flexFlowColumn flex1 flexNoGap"> |
| 5359 | <div id="creators_notes_div" class="title_restorable"> | 5467 | <div id="creators_notes_div" class="title_restorable flexGap5"> |
| 5360 | <span data-i18n="Creator's Notes">Creator's Notes</span> | 5468 | <span class="flex1" data-i18n="Creator's Notes">Creator's Notes</span> |
| 5361 | <small id="creators_note_desc_hidden" data-i18n="Character details are hidden.">Character details are hidden.</small> | 5469 | <small id="creators_note_desc_hidden" data-i18n="Character details are hidden.">Character details are hidden.</small> |
| 5470 | <div id="creators_note_styles_button" class="margin0 menu_button fa-solid fa-palette fa-fw" title="Allow / Forbid the use of global styles for this character." data-i18n="[title]Allow / Forbid the use of global styles for this character."></div> | ||
| 5362 | <div id="spoiler_free_desc_button" class="margin0 menu_button fa-solid fa-eye fa-fw" title="Show / Hide Description and First Message" data-i18n="[title]Show / Hide Description and First Message"></div> | 5471 | <div id="spoiler_free_desc_button" class="margin0 menu_button fa-solid fa-eye fa-fw" title="Show / Hide Description and First Message" data-i18n="[title]Show / Hide Description and First Message"></div> |
| 5363 | </div> | 5472 | </div> |
| 5364 | <div id="creator_notes_spoiler" class="flex1"></div> | 5473 | <div id="creator_notes_spoiler" class="flex1"></div> |
| @@ -5533,7 +5642,7 @@ | |||
| 5533 | <div class="inline-drawer-content"> | 5642 | <div class="inline-drawer-content"> |
| 5534 | <div id="currentGroupMembers" name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1"> | 5643 | <div id="currentGroupMembers" name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1"> |
| 5535 | <div id="rm_group_members_pagination" class="rm_group_members_pagination group_pagination"></div> | 5644 | <div id="rm_group_members_pagination" class="rm_group_members_pagination group_pagination"></div> |
| 5536 | <div id="rm_group_members" class="rm_group_members overflowYAuto flex-container"></div> | 5645 | <div id="rm_group_members" class="rm_group_members overflowYAuto flex-container" group_empty_text="Group is empty." data-i18n="[group_empty_text]Group is empty."></div> |
| 5537 | </div> | 5646 | </div> |
| 5538 | </div> | 5647 | </div> |
| 5539 | </div> | 5648 | </div> |
| @@ -5551,7 +5660,7 @@ | |||
| 5551 | <div class="tags rm_tag_filter"></div> | 5660 | <div class="tags rm_tag_filter"></div> |
| 5552 | </div> | 5661 | </div> |
| 5553 | <div id="rm_group_add_members_pagination" class="group_pagination"></div> | 5662 | <div id="rm_group_add_members_pagination" class="group_pagination"></div> |
| 5554 | <div id="rm_group_add_members" class="overflowYAuto flex-container"></div> | 5663 | <div id="rm_group_add_members" class="overflowYAuto flex-container" no_characters_text="No characters available" data-i18n="[no_characters_text]No characters available"></div> |
| 5555 | </div> | 5664 | </div> |
| 5556 | </div> | 5665 | </div> |
| 5557 | </div> | 5666 | </div> |
| @@ -5968,10 +6077,11 @@ | |||
| 5968 | <div title="Tag as folder" class="tag_as_folder fa-solid fa-folder-open right_menu_button" data-i18n="[title]Use tag as folder"> | 6077 | <div title="Tag as folder" class="tag_as_folder fa-solid fa-folder-open right_menu_button" data-i18n="[title]Use tag as folder"> |
| 5969 | <span class="tag_folder_indicator"></span> | 6078 | <span class="tag_folder_indicator"></span> |
| 5970 | </div> | 6079 | </div> |
| 6080 | <div class="right_menu_button fa-solid fa-eye fa-fw eye-toggle"></div> | ||
| 5971 | <div class="tag_view_color_picker" data-value="color"></div> | 6081 | <div class="tag_view_color_picker" data-value="color"></div> |
| 5972 | <div class="tag_view_color_picker" data-value="color2"></div> | 6082 | <div class="tag_view_color_picker" data-value="color2"></div> |
| 5973 | <div class="tag_view_name" contenteditable="true"></div> | 6083 | <div class="tag_view_name" contenteditable="true"></div> |
| 5974 | <div class="tag_view_counter"><span class="tag_view_counter_value"></span> entries</div> | 6084 | <div class="tag_view_counter"><span class="tag_view_counter_value"></span> <span data-i18n="tag_entries">entries</span></div> |
| 5975 | <div title="Delete tag" class="tag_delete fa-solid fa-trash-can right_menu_button" data-i18n="[title]Delete tag"></div> | 6085 | <div title="Delete tag" class="tag_delete fa-solid fa-trash-can right_menu_button" data-i18n="[title]Delete tag"></div> |
| 5976 | </div> | 6086 | </div> |
| 5977 | </div> | 6087 | </div> |
| @@ -6291,6 +6401,54 @@ | |||
| 6291 | </label> | 6401 | </label> |
| 6292 | </div> | 6402 | </div> |
| 6293 | </div> | 6403 | </div> |
| 6404 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 6405 | <div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable"> | ||
| 6406 | <strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong> | ||
| 6407 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 6408 | </div> | ||
| 6409 | <div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px"> | ||
| 6410 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6411 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6412 | <input type="checkbox" name="matchCharacterDescription" /> | ||
| 6413 | <span data-i18n="Character Description"> | ||
| 6414 | Character Description | ||
| 6415 | </span> | ||
| 6416 | </label> | ||
| 6417 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6418 | <input type="checkbox" name="matchCharacterPersonality" /> | ||
| 6419 | <span data-i18n="Character Personality"> | ||
| 6420 | Character Personality | ||
| 6421 | </span> | ||
| 6422 | </label> | ||
| 6423 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6424 | <input type="checkbox" name="matchScenario" /> | ||
| 6425 | <span data-i18n="Scenario"> | ||
| 6426 | Scenario | ||
| 6427 | </span> | ||
| 6428 | </label> | ||
| 6429 | </small> | ||
| 6430 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6431 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6432 | <input type="checkbox" name="matchPersonaDescription" /> | ||
| 6433 | <span data-i18n="Persona Description"> | ||
| 6434 | Persona Description | ||
| 6435 | </span> | ||
| 6436 | </label> | ||
| 6437 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6438 | <input type="checkbox" name="matchCharacterDepthPrompt" /> | ||
| 6439 | <span data-i18n="Character's Note"> | ||
| 6440 | Character's Note | ||
| 6441 | </span> | ||
| 6442 | </label> | ||
| 6443 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6444 | <input type="checkbox" name="matchCreatorNotes" /> | ||
| 6445 | <span data-i18n="Creator's Notes"> | ||
| 6446 | Creator's Notes | ||
| 6447 | </span> | ||
| 6448 | </label> | ||
| 6449 | </small> | ||
| 6450 | </div> | ||
| 6451 | </div> | ||
| 6294 | </div> | 6452 | </div> |
| 6295 | </div> | 6453 | </div> |
| 6296 | </form> | 6454 | </form> |
| @@ -6305,6 +6463,9 @@ | |||
| 6305 | <div class="wide100p character_name_block"> | 6463 | <div class="wide100p character_name_block"> |
| 6306 | <span class="ch_name"></span> | 6464 | <span class="ch_name"></span> |
| 6307 | <small class="ch_additional_info ch_add_placeholder">+++</small> | 6465 | <small class="ch_additional_info ch_add_placeholder">+++</small> |
| 6466 | <small class="ch_assistant" title="This character will be used as a welcome page assistant." data-i18n="[title]This character will be used as a welcome page assistant."> | ||
| 6467 | <i class="fa-solid fa-sm fa-user-graduate"></i> | ||
| 6468 | </small> | ||
| 6308 | <small class="ch_additional_info character_version"></small> | 6469 | <small class="ch_additional_info character_version"></small> |
| 6309 | <small class="ch_additional_info ch_avatar_url"></small> | 6470 | <small class="ch_additional_info ch_avatar_url"></small> |
| 6310 | </div> | 6471 | </div> |
| @@ -6364,21 +6525,19 @@ | |||
| 6364 | <label for="completion_prompt_manager_popup_entry_form_name"> | 6525 | <label for="completion_prompt_manager_popup_entry_form_name"> |
| 6365 | <span data-i18n="prompt_manager_name">Name</span> | 6526 | <span data-i18n="prompt_manager_name">Name</span> |
| 6366 | </label> | 6527 | </label> |
| 6367 | <div class="text_muted" data-i18n="A name for this prompt.">A name for this prompt.</div> | ||
| 6368 | <input id="completion_prompt_manager_popup_entry_form_name" class="text_pole" type="text" name="name" /> | 6528 | <input id="completion_prompt_manager_popup_entry_form_name" class="text_pole" type="text" name="name" /> |
| 6529 | <div class="text_muted" data-i18n="A name for this prompt.">A name for this prompt.</div> | ||
| 6369 | </div> | 6530 | </div> |
| 6370 | <div class="completion_prompt_manager_popup_entry_form_control flex1"> | 6531 | <div class="completion_prompt_manager_popup_entry_form_control flex1"> |
| 6371 | <label for="completion_prompt_manager_popup_entry_form_role"> | 6532 | <label for="completion_prompt_manager_popup_entry_form_role"> |
| 6372 | <span data-i18n="Role">Role</span> | 6533 | <span data-i18n="Role">Role</span> |
| 6373 | </label> | 6534 | </label> |
| 6374 | <div class="text_muted"> | ||
| 6375 | <span data-i18n="To whom this message will be attributed.">To whom this message will be attributed.</span> | ||
| 6376 | </div> | ||
| 6377 | <select id="completion_prompt_manager_popup_entry_form_role" class="text_pole" name="role"> | 6535 | <select id="completion_prompt_manager_popup_entry_form_role" class="text_pole" name="role"> |
| 6378 | <option data-i18n="System" value="system">System</option> | 6536 | <option data-i18n="System" value="system">System</option> |
| 6379 | <option data-i18n="User" value="user">User</option> | 6537 | <option data-i18n="User" value="user">User</option> |
| 6380 | <option data-i18n="AI Assistant" value="assistant">AI Assistant</option> | 6538 | <option data-i18n="AI Assistant" value="assistant">AI Assistant</option> |
| 6381 | </select> | 6539 | </select> |
| 6540 | <div class="text_muted" data-i18n="To whom this message will be attributed.">To whom this message will be attributed.</div> | ||
| 6382 | </div> | 6541 | </div> |
| 6383 | </div> | 6542 | </div> |
| 6384 | <div class="flex-container gap10px"> | 6543 | <div class="flex-container gap10px"> |
| @@ -6386,18 +6545,26 @@ | |||
| 6386 | <label for="completion_prompt_manager_popup_entry_form_injection_position"> | 6545 | <label for="completion_prompt_manager_popup_entry_form_injection_position"> |
| 6387 | <span data-i18n="prompt_manager_position">Position</span> | 6546 | <span data-i18n="prompt_manager_position">Position</span> |
| 6388 | </label> | 6547 | </label> |
| 6389 | <div class="text_muted" data-i18n="Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.">Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.</div> | ||
| 6390 | <select id="completion_prompt_manager_popup_entry_form_injection_position" class="text_pole" name="injection_position"> | 6548 | <select id="completion_prompt_manager_popup_entry_form_injection_position" class="text_pole" name="injection_position"> |
| 6391 | <option data-i18n="prompt_manager_relative" value="0">Relative</option> | 6549 | <option data-i18n="prompt_manager_relative" value="0">Relative</option> |
| 6392 | <option data-i18n="prompt_manager_in_chat" value="1">In-chat</option> | 6550 | <option data-i18n="prompt_manager_in_chat" value="1">In-chat</option> |
| 6393 | </select> | 6551 | </select> |
| 6552 | <div class="text_muted" data-i18n="Relative (to other prompts in prompt manager) or In-chat @ Depth.">Relative (to other prompts in prompt manager) or In-chat @ Depth.</div> | ||
| 6394 | </div> | 6553 | </div> |
| 6395 | <div id="completion_prompt_manager_depth_block" class="completion_prompt_manager_popup_entry_form_control flex1"> | 6554 | <div id="completion_prompt_manager_depth_block" class="completion_prompt_manager_popup_entry_form_control flex1"> |
| 6396 | <label for="completion_prompt_manager_popup_entry_form_injection_depth"> | 6555 | <label for="completion_prompt_manager_popup_entry_form_injection_depth"> |
| 6397 | <span data-i18n="prompt_manager_depth">Depth</span> | 6556 | <span data-i18n="prompt_manager_depth">Depth</span> |
| 6398 | </label> | 6557 | </label> |
| 6399 | <div class="text_muted" data-i18n="Injection depth. 0 = after the last message, 1 = before the last message, etc.">Injection depth. 0 = after the last message, 1 = before the last message, etc.</div> | ||
| 6400 | <input id="completion_prompt_manager_popup_entry_form_injection_depth" class="text_pole" type="number" name="injection_depth" min="0" max="9999" value="4" /> | 6558 | <input id="completion_prompt_manager_popup_entry_form_injection_depth" class="text_pole" type="number" name="injection_depth" min="0" max="9999" value="4" /> |
| 6559 | <div class="text_muted" data-i18n="0 = after the last message, 1 = before the last message, etc.">0 = after the last message, 1 = before the last message, etc.</div> | ||
| 6560 | </div> | ||
| 6561 | <div id="completion_prompt_manager_order_block" class="completion_prompt_manager_popup_entry_form_control flex1"> | ||
| 6562 | <label for="completion_prompt_manager_popup_entry_form_injection_order"> | ||
| 6563 | <span data-i18n="prompt_manager_order">Order</span> | ||
| 6564 | <i class="fas fa-info-circle" title="Prompt injections from other sources (World Info, Author's Note, etc.) always have a default order of 100." data-i18n="[title]prompt_manager_order_note"></i> | ||
| 6565 | </label> | ||
| 6566 | <input id="completion_prompt_manager_popup_entry_form_injection_order" class="text_pole" type="number" name="injection_order" min="0" max="9999" value="100" /> | ||
| 6567 | <div class="text_muted" data-i18n="Ordered from low/top to high/bottom, and at same order: Assistant, User, System.">Ordered from low/top to high/bottom, and at same order: Assistant, User, System.</div> | ||
| 6401 | </div> | 6568 | </div> |
| 6402 | </div> | 6569 | </div> |
| 6403 | <div class="completion_prompt_manager_popup_entry_form_control"> | 6570 | <div class="completion_prompt_manager_popup_entry_form_control"> |
| @@ -6406,7 +6573,6 @@ | |||
| 6406 | <label for="completion_prompt_manager_popup_entry_form_prompt"> | 6573 | <label for="completion_prompt_manager_popup_entry_form_prompt"> |
| 6407 | <span data-i18n="Prompt">Prompt</span> | 6574 | <span data-i18n="Prompt">Prompt</span> |
| 6408 | </label> | 6575 | </label> |
| 6409 | <div class="text_muted" data-i18n="The prompt to be sent.">The prompt to be sent.</div> | ||
| 6410 | </div> | 6576 | </div> |
| 6411 | <div id="completion_prompt_manager_forbid_overrides_block"> | 6577 | <div id="completion_prompt_manager_forbid_overrides_block"> |
| 6412 | <label class="checkbox_label" for="completion_prompt_manager_popup_entry_form_forbid_overrides" title="This prompt cannot be overridden by character cards, even if overrides are preferred." data-i18n="[title]This prompt cannot be overridden by character cards, even if overrides are preferred."> | 6578 | <label class="checkbox_label" for="completion_prompt_manager_popup_entry_form_forbid_overrides" title="This prompt cannot be overridden by character cards, even if overrides are preferred." data-i18n="[title]This prompt cannot be overridden by character cards, even if overrides are preferred."> |
| @@ -6415,7 +6581,12 @@ | |||
| 6415 | </label> | 6581 | </label> |
| 6416 | </div> | 6582 | </div> |
| 6417 | </div> | 6583 | </div> |
| 6418 | <textarea id="completion_prompt_manager_popup_entry_form_prompt" class="text_pole" name="prompt"> | 6584 | <div id="completion_prompt_manager_popup_entry_source_block"> |
| 6585 | <b data-i18n="Source:">Source:</b> | ||
| 6586 | <span> </span> | ||
| 6587 | <span id="completion_prompt_manager_popup_entry_source"></span> | ||
| 6588 | </div> | ||
| 6589 | <textarea id="completion_prompt_manager_popup_entry_form_prompt" class="text_pole" name="prompt" placeholder="The prompt to be sent." data-i18n="[placeholder]The prompt to be sent."></textarea> | ||
| 6419 | </textarea> | 6590 | </textarea> |
| 6420 | </div> | 6591 | </div> |
| 6421 | <div class="completion_prompt_manager_popup_entry_form_footer"> | 6592 | <div class="completion_prompt_manager_popup_entry_form_footer"> |
| @@ -6658,7 +6829,7 @@ | |||
| 6658 | </div> | 6829 | </div> |
| 6659 | <div class="flex-container wide100pLess70px character_select_container height100p alignitemscenter"> | 6830 | <div class="flex-container wide100pLess70px character_select_container height100p alignitemscenter"> |
| 6660 | <div class="wide100p character_name_block"> | 6831 | <div class="wide100p character_name_block"> |
| 6661 | <span class="ch_name">Go back</span> | 6832 | <span class="ch_name" data-i18n="Go back">Go back</span> |
| 6662 | </div> | 6833 | </div> |
| 6663 | </div> | 6834 | </div> |
| 6664 | </div> | 6835 | </div> |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "يجمع الرسائل المتتالية للنظام في رسالة واحدة (باستثناء الحوارات المثالية). قد يحسن التتابع لبعض النماذج.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "يجمع الرسائل المتتالية للنظام في رسالة واحدة (باستثناء الحوارات المثالية). قد يحسن التتابع لبعض النماذج.", |
| 236 | "Enable function calling": "تمكين استدعاء الوظيفة", | 236 | "Enable function calling": "تمكين استدعاء الوظيفة", |
| 237 | "Send inline images": "إرسال الصور المضمنة", | 237 | "Send inline images": "إرسال الصور المضمنة", |
| 238 | "image_inlining_hint_1": "يرسل الصور في المطالبات إذا كان النموذج يدعمها (على سبيل المثال، GPT-4V، أو Claude 3، أو Lava 13B).\n استخدم ال", | 238 | "image_inlining_hint_1": "يرسل الصور في المطالبات إذا كان النموذج يدعمها .\n استخدم ال", |
| 239 | "image_inlining_hint_2": "الإجراء على أي رسالة أو", | 239 | "image_inlining_hint_2": "الإجراء على أي رسالة أو", |
| 240 | "image_inlining_hint_3": "القائمة لإرفاق ملف صورة للدردشة.", | 240 | "image_inlining_hint_3": "القائمة لإرفاق ملف صورة للدردشة.", |
| 241 | "Inline Image Quality": "جودة الصورة المضمنة", | 241 | "Inline Image Quality": "جودة الصورة المضمنة", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "تعبئة مسبقة للمساعد", | 253 | "Assistant Prefill": "تعبئة مسبقة للمساعد", |
| 254 | "Start Claude's answer with...": "ابدأ إجابة كلود بـ...", | 254 | "Start Claude's answer with...": "ابدأ إجابة كلود بـ...", |
| 255 | "Assistant Impersonation Prefill": "مساعد انتحال الشخصية المسبقة", | 255 | "Assistant Impersonation Prefill": "مساعد انتحال الشخصية المسبقة", |
| 256 | "Use system prompt (Claude 2.1+ only)": "استخدام التعليمة النظامية (فقط كلود 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "إرسال التعليمة النظامية للنماذج المدعومة. إذا تم تعطيلها، يتم إضافة رسالة المستخدم إلى بداية التعليمة.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "إرسال التعليمة النظامية للنماذج المدعومة. إذا تم تعطيلها، يتم إضافة رسالة المستخدم إلى بداية التعليمة.", |
| 258 | "User first message": "الرسالة الأولى للمستخدم", | 257 | "User first message": "الرسالة الأولى للمستخدم", |
| 259 | "Restore User first message": "استعادة الرسالة الأولى للمستخدم", | 258 | "Restore User first message": "استعادة الرسالة الأولى للمستخدم", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "بداية الدردشة", | 410 | "Chat Start": "بداية الدردشة", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "أضف بداية الدردشة وفاصل الأمثلة إلى قائمة سلاسل التوقف.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "أضف بداية الدردشة وفاصل الأمثلة إلى قائمة سلاسل التوقف.", |
| 413 | "Use as Stop Strings": "استخدم كسلاسل التوقف", | 412 | "Use as Stop Strings": "استخدم كسلاسل التوقف", |
| 414 | "context_allow_jailbreak": "يتضمن كسر الحماية في نهاية المطالبة، إذا تم تحديده في بطاقة الشخصية و''Prefer Char. تم تمكين الهروب من السجن.\nلا يُنصح بهذا بالنسبة لنماذج إكمال النص، فقد يؤدي إلى نتائج سيئة.", | ||
| 415 | "Allow Jailbreak": "السماح بالجيلبريك", | 413 | "Allow Jailbreak": "السماح بالجيلبريك", |
| 416 | "Context Order": "ترتيب السياق", | 414 | "Context Order": "ترتيب السياق", |
| 417 | "Summary": "ملخص", | 415 | "Summary": "ملخص", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "تنزيل الدردشة كمستند نصي عادي", | 938 | "Download chat as plain text document": "تنزيل الدردشة كمستند نصي عادي", |
| 941 | "Delete chat file": "حذف ملف الدردشة", | 939 | "Delete chat file": "حذف ملف الدردشة", |
| 942 | "Use tag as folder": "وضع علامة كمجلد", | 940 | "Use tag as folder": "وضع علامة كمجلد", |
| 941 | "Hide on character card": "إخفاء في بطاقة الشخصية", | ||
| 943 | "Delete tag": "حذف العلامة", | 942 | "Delete tag": "حذف العلامة", |
| 944 | "Entry Title/Memo": "عنوان الإدخال/المذكرة", | 943 | "Entry Title/Memo": "عنوان الإدخال/المذكرة", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "حالة دخول وي:\r🔵 ثابت\r🟢 عادي\r🔗 ناقل\r❌ معطل", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "حالة دخول وي:\r🔵 ثابت\r🟢 عادي\r🔗 ناقل\r❌ معطل", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "لمن ستنسب هذه الرسالة؟", | 1009 | "To whom this message will be attributed.": "لمن ستنسب هذه الرسالة؟", |
| 1011 | "AI Assistant": "مساعد الذكاء الاصطناعي", | 1010 | "AI Assistant": "مساعد الذكاء الاصطناعي", |
| 1012 | "prompt_manager_position": "موضع", | 1011 | "prompt_manager_position": "موضع", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "موضع الحقن. بجوار المطالبات الأخرى (نسبية) أو داخل الدردشة (مطلقة).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "موضع الحقن. بجوار المطالبات الأخرى (نسبية) أو داخل الدردشة (مطلقة).", |
| 1014 | "prompt_manager_relative": "نسبي", | 1013 | "prompt_manager_relative": "نسبي", |
| 1015 | "prompt_manager_depth": "عمق", | 1014 | "prompt_manager_depth": "عمق", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "عمق الحقن. 0 = بعد الرسالة الأخيرة، 1 = قبل الرسالة الأخيرة، الخ.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "عمق الحقن. 0 = بعد الرسالة الأخيرة، 1 = قبل الرسالة الأخيرة، الخ.", |
| 1017 | "Prompt": "موضوع", | 1016 | "Prompt": "موضوع", |
| 1018 | "The prompt to be sent.": "المطالبة ليتم إرسالها.", | 1017 | "The prompt to be sent.": "المطالبة ليتم إرسالها.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "لا يمكن تجاوز هذه المطالبة بواسطة بطاقات الأحرف، حتى إذا كان التجاوزات مفضلاً.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "لا يمكن تجاوز هذه المطالبة بواسطة بطاقات الأحرف، حتى إذا كان التجاوزات مفضلاً.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Kombiniert aufeinanderfolgende Systemnachrichten zu einer (ausschließlich Beispiel-Dialoge ausgeschlossen). Kann die Kohärenz für einige Modelle verbessern.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Kombiniert aufeinanderfolgende Systemnachrichten zu einer (ausschließlich Beispiel-Dialoge ausgeschlossen). Kann die Kohärenz für einige Modelle verbessern.", |
| 236 | "Enable function calling": "Funktionsaufruf aktivieren", | 236 | "Enable function calling": "Funktionsaufruf aktivieren", |
| 237 | "Send inline images": "Inline-Bilder senden", | 237 | "Send inline images": "Inline-Bilder senden", |
| 238 | "image_inlining_hint_1": "Sendet Bilder in Eingabeaufforderungen, wenn das Modell dies unterstützt (z. B. GPT-4V, Claude 3 oder Llava 13B).\nVerwenden Sie die", | 238 | "image_inlining_hint_1": "Sendet Bilder in Eingabeaufforderungen, wenn das Modell dies unterstützt.\nVerwenden Sie die", |
| 239 | "image_inlining_hint_2": "Aktion auf eine Nachricht oder die", | 239 | "image_inlining_hint_2": "Aktion auf eine Nachricht oder die", |
| 240 | "image_inlining_hint_3": "Menü, um eine Bilddatei an den Chat anzuhängen.", | 240 | "image_inlining_hint_3": "Menü, um eine Bilddatei an den Chat anzuhängen.", |
| 241 | "Inline Image Quality": "Inline-Bildqualität", | 241 | "Inline Image Quality": "Inline-Bildqualität", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Assistenten-Vorausfüllung", | 253 | "Assistant Prefill": "Assistenten-Vorausfüllung", |
| 254 | "Start Claude's answer with...": "Beginne Claudes Antwort mit...", | 254 | "Start Claude's answer with...": "Beginne Claudes Antwort mit...", |
| 255 | "Assistant Impersonation Prefill": "Identitätswechsel des Assistenten vorab ausfüllen", | 255 | "Assistant Impersonation Prefill": "Identitätswechsel des Assistenten vorab ausfüllen", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Systemprompt verwenden (nur Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Senden Sie die Systemaufforderung für unterstützte Modelle. Wenn deaktiviert, wird die Benutzernachricht am Anfang der Aufforderung hinzugefügt.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Senden Sie die Systemaufforderung für unterstützte Modelle. Wenn deaktiviert, wird die Benutzernachricht am Anfang der Aufforderung hinzugefügt.", |
| 258 | "User first message": "Erste Nachricht des Benutzers", | 257 | "User first message": "Erste Nachricht des Benutzers", |
| 259 | "Restore User first message": "Erste Nachricht des Benutzers wiederherstellen", | 258 | "Restore User first message": "Erste Nachricht des Benutzers wiederherstellen", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Chat-Start", | 410 | "Chat Start": "Chat-Start", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Fügen Sie einer Liste von Stoppzeichenfolgen „Chat-Start“ und „Beispieltrennzeichen“ hinzu.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Fügen Sie einer Liste von Stoppzeichenfolgen „Chat-Start“ und „Beispieltrennzeichen“ hinzu.", |
| 413 | "Use as Stop Strings": "Verwende als Stoppzeichenfolgen", | 412 | "Use as Stop Strings": "Verwende als Stoppzeichenfolgen", |
| 414 | "context_allow_jailbreak": "Schließt Jailbreak am Ende der Eingabeaufforderung ein, wenn dies in der Charakterkarte definiert ist UND „Charakter-Jailbreak bevorzugen“ aktiviert ist.\nDIES WIRD FÜR TEXTVERVOLLSTÄNDIGUNGSMODELLE NICHT EMPFOHLEN, KANN ZU SCHLECHTEN AUSGABEN FÜHREN.", | ||
| 415 | "Allow Jailbreak": "Jailbreak zulassen", | 413 | "Allow Jailbreak": "Jailbreak zulassen", |
| 416 | "Context Order": "Kontextreihenfolge", | 414 | "Context Order": "Kontextreihenfolge", |
| 417 | "Summary": "Zusammenfassung", | 415 | "Summary": "Zusammenfassung", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Chat als einfaches Textdokument herunterladen", | 938 | "Download chat as plain text document": "Chat als einfaches Textdokument herunterladen", |
| 941 | "Delete chat file": "Chatdatei löschen", | 939 | "Delete chat file": "Chatdatei löschen", |
| 942 | "Use tag as folder": "Als Ordner markieren", | 940 | "Use tag as folder": "Als Ordner markieren", |
| 941 | "Hide on character card": "Auf Charakterkarte ausblenden", | ||
| 943 | "Delete tag": "Tag löschen", | 942 | "Delete tag": "Tag löschen", |
| 944 | "Entry Title/Memo": "Eintragstitel/Memo", | 943 | "Entry Title/Memo": "Eintragstitel/Memo", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI-Eintragstatus: 🔵 Konstant 🟢 Normal 🔗 Vektorisiert ❌ Deaktiviert", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI-Eintragstatus: 🔵 Konstant 🟢 Normal 🔗 Vektorisiert ❌ Deaktiviert", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "Wem diese Nachricht zugeschrieben wird.", | 1009 | "To whom this message will be attributed.": "Wem diese Nachricht zugeschrieben wird.", |
| 1011 | "AI Assistant": "KI-Assistent", | 1010 | "AI Assistant": "KI-Assistent", |
| 1012 | "prompt_manager_position": "Position", | 1011 | "prompt_manager_position": "Position", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Injektionsposition. Neben anderen Eingabeaufforderungen (relativ) oder im Chat (absolut).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Neben anderen Eingabeaufforderungen (relativ) oder im Chat (absolut).", |
| 1014 | "prompt_manager_relative": "Relativ", | 1013 | "prompt_manager_relative": "Relativ", |
| 1015 | "prompt_manager_depth": "Tiefe", | 1014 | "prompt_manager_depth": "Tiefe", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Injektionstiefe. 0 = nach der letzten Nachricht, 1 = vor der letzten Nachricht usw.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = nach der letzten Nachricht, 1 = vor der letzten Nachricht usw.", |
| 1017 | "Prompt": "Aufforderung", | 1016 | "Prompt": "Aufforderung", |
| 1018 | "The prompt to be sent.": "Die zu sendende Eingabeaufforderung.", | 1017 | "The prompt to be sent.": "Die zu sendende Eingabeaufforderung.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Diese Eingabeaufforderung kann nicht durch Charakterkarten überschrieben werden, selbst wenn dies bevorzugt wird.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Diese Eingabeaufforderung kann nicht durch Charakterkarten überschrieben werden, selbst wenn dies bevorzugt wird.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensajes del sistema consecutivos en uno solo (excluyendo diálogos de ejemplo). Puede mejorar la coherencia para algunos modelos.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensajes del sistema consecutivos en uno solo (excluyendo diálogos de ejemplo). Puede mejorar la coherencia para algunos modelos.", |
| 236 | "Enable function calling": "Habilitar llamada a función", | 236 | "Enable function calling": "Habilitar llamada a función", |
| 237 | "Send inline images": "Enviar imágenes en línea", | 237 | "Send inline images": "Enviar imágenes en línea", |
| 238 | "image_inlining_hint_1": "Envía imágenes en mensajes si el modelo lo admite (por ejemplo, GPT-4V, Claude 3 o Llava 13B).\n Utilizar el", | 238 | "image_inlining_hint_1": "Envía imágenes en mensajes si el modelo lo admite.\n Utilizar el", |
| 239 | "image_inlining_hint_2": "acción sobre cualquier mensaje o el", | 239 | "image_inlining_hint_2": "acción sobre cualquier mensaje o el", |
| 240 | "image_inlining_hint_3": "menú para adjuntar un archivo de imagen al chat.", | 240 | "image_inlining_hint_3": "menú para adjuntar un archivo de imagen al chat.", |
| 241 | "Inline Image Quality": "Calidad de imagen en línea", | 241 | "Inline Image Quality": "Calidad de imagen en línea", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Prellenado de Asistente", | 253 | "Assistant Prefill": "Prellenado de Asistente", |
| 254 | "Start Claude's answer with...": "Iniciar la respuesta de Claude con...", | 254 | "Start Claude's answer with...": "Iniciar la respuesta de Claude con...", |
| 255 | "Assistant Impersonation Prefill": "Precarga de suplantación de asistente", | 255 | "Assistant Impersonation Prefill": "Precarga de suplantación de asistente", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Usar indicación del sistema (solo para Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar la indicación del sistema para los modelos admitidos. Si está desactivado, el mensaje del usuario se agrega al principio de las indicaciónes.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar la indicación del sistema para los modelos admitidos. Si está desactivado, el mensaje del usuario se agrega al principio de las indicaciónes.", |
| 258 | "User first message": "Primer mensaje del usuario", | 257 | "User first message": "Primer mensaje del usuario", |
| 259 | "Restore User first message": "Restaurar el primer mensaje del usuario", | 258 | "Restore User first message": "Restaurar el primer mensaje del usuario", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Inicio de chat", | 410 | "Chat Start": "Inicio de chat", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Agregue Inicio de chat y Separador de ejemplo a una lista de cadenas de parada.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Agregue Inicio de chat y Separador de ejemplo a una lista de cadenas de parada.", |
| 413 | "Use as Stop Strings": "Usar como Cadenas de Parada", | 412 | "Use as Stop Strings": "Usar como Cadenas de Parada", |
| 414 | "context_allow_jailbreak": "Incluye Jailbreak al final del mensaje, si está definido en la tarjeta de personaje Y está habilitado \"Prefer Char. Jailbreak\".\nESTO NO SE RECOMIENDA PARA MODELOS DE COMPLETO DE TEXTO, PUEDE PRODUCIR UN RESULTADO INCORRECTO.", | ||
| 415 | "Allow Jailbreak": "Permitir Jailbreak", | 413 | "Allow Jailbreak": "Permitir Jailbreak", |
| 416 | "Context Order": "Orden de contexto", | 414 | "Context Order": "Orden de contexto", |
| 417 | "Summary": "Resumen", | 415 | "Summary": "Resumen", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Descargar chat como documento de texto sin formato", | 938 | "Download chat as plain text document": "Descargar chat como documento de texto sin formato", |
| 941 | "Delete chat file": "Eliminar archivo de chat", | 939 | "Delete chat file": "Eliminar archivo de chat", |
| 942 | "Use tag as folder": "Etiquetar como carpeta", | 940 | "Use tag as folder": "Etiquetar como carpeta", |
| 941 | "Hide on character card": "Ocultar en la tarjeta del personaje", | ||
| 943 | "Delete tag": "Eliminar etiqueta", | 942 | "Delete tag": "Eliminar etiqueta", |
| 944 | "Entry Title/Memo": "Título/Memo", | 943 | "Entry Title/Memo": "Título/Memo", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Estado de entrada a WI:\r🔵 Constante\r🟢Normal\r🔗 Vectorizado\r❌ Deshabilitado", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Estado de entrada a WI:\r🔵 Constante\r🟢Normal\r🔗 Vectorizado\r❌ Deshabilitado", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "A quién se le atribuirá este mensaje.", | 1009 | "To whom this message will be attributed.": "A quién se le atribuirá este mensaje.", |
| 1011 | "AI Assistant": "Asistente de IA", | 1010 | "AI Assistant": "Asistente de IA", |
| 1012 | "prompt_manager_position": "Posición", | 1011 | "prompt_manager_position": "Posición", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Posición de inyección. Junto a otras indicaciones (relativa) o en el chat (absoluta).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Junto a otras indicaciones (relativa) o en el chat (absoluta).", |
| 1014 | "prompt_manager_relative": "Relativo", | 1013 | "prompt_manager_relative": "Relativo", |
| 1015 | "prompt_manager_depth": "Profundidad", | 1014 | "prompt_manager_depth": "Profundidad", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Profundidad de inyección. 0 = después del último mensaje, 1 = antes del último mensaje, etc.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = después del último mensaje, 1 = antes del último mensaje, etc.", |
| 1017 | "Prompt": "Indicar", | 1016 | "Prompt": "Indicar", |
| 1018 | "The prompt to be sent.": "El mensaje que se enviará.", | 1017 | "The prompt to be sent.": "El mensaje que se enviará.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Este mensaje no puede ser anulado por tarjetas de personaje, incluso si se prefieren las anulaciones.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Este mensaje no puede ser anulado por tarjetas de personaje, incluso si se prefieren las anulaciones.", |
| @@ -227,7 +227,7 @@ | |||
| 227 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combine les messages système consécutifs en un seul (à l'exclusion des dialogues d'exemple). Peut améliorer la cohérence pour certains modèles.", | 227 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combine les messages système consécutifs en un seul (à l'exclusion des dialogues d'exemple). Peut améliorer la cohérence pour certains modèles.", |
| 228 | "Enable function calling": "Activer l'appel de fonction", | 228 | "Enable function calling": "Activer l'appel de fonction", |
| 229 | "Send inline images": "Envoyer des images en ligne", | 229 | "Send inline images": "Envoyer des images en ligne", |
| 230 | "image_inlining_hint_1": "Envoie des images dans les prompts si le modèle le prend en charge (par exemple GPT-4V, Claude 3 ou Llava 13B).\nUtilisez le", | 230 | "image_inlining_hint_1": "Envoie des images dans les prompts si le modèle le prend en charge.\nUtilisez le", |
| 231 | "image_inlining_hint_2": "action sur n'importe quel message ou le", | 231 | "image_inlining_hint_2": "action sur n'importe quel message ou le", |
| 232 | "image_inlining_hint_3": "menu pour joindre un fichier image au chat.", | 232 | "image_inlining_hint_3": "menu pour joindre un fichier image au chat.", |
| 233 | "Inline Image Quality": "Qualité d'image en ligne", | 233 | "Inline Image Quality": "Qualité d'image en ligne", |
| @@ -240,7 +240,6 @@ | |||
| 240 | "Assistant Prefill": "Pré-remplissage de l'assistant", | 240 | "Assistant Prefill": "Pré-remplissage de l'assistant", |
| 241 | "Start Claude's answer with...": "Commencer la réponse de Claude par...", | 241 | "Start Claude's answer with...": "Commencer la réponse de Claude par...", |
| 242 | "Assistant Impersonation Prefill": "Pré-remplir l'usurpation d'identité de l'assistant", | 242 | "Assistant Impersonation Prefill": "Pré-remplir l'usurpation d'identité de l'assistant", |
| 243 | "Use system prompt (Claude 2.1+ only)": "Utiliser le prompt système (uniquement Claude 2.1+)", | ||
| 244 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Envoyer le prompt système pour les modèles pris en charge. Si désactivé, le message de l'utilisateur est ajouté au début du prompt.", | 243 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Envoyer le prompt système pour les modèles pris en charge. Si désactivé, le message de l'utilisateur est ajouté au début du prompt.", |
| 245 | "New preset": "Nouveau preset", | 244 | "New preset": "Nouveau preset", |
| 246 | "Delete preset": "Supprimer le preset", | 245 | "Delete preset": "Supprimer le preset", |
| @@ -884,6 +883,7 @@ | |||
| 884 | "Download chat as plain text document": "Télécharger la discussion sous forme de document texte brut", | 883 | "Download chat as plain text document": "Télécharger la discussion sous forme de document texte brut", |
| 885 | "Delete chat file": "Supprimer le fichier de discussion", | 884 | "Delete chat file": "Supprimer le fichier de discussion", |
| 886 | "Use tag as folder": "Utiliser les tags comme dossier", | 885 | "Use tag as folder": "Utiliser les tags comme dossier", |
| 886 | "Hide on character card": "Masquer sur la fiche du personnage", | ||
| 887 | "Delete tag": "Supprimer le tag'", | 887 | "Delete tag": "Supprimer le tag'", |
| 888 | "Entry Title/Memo": "Titre de l'entrée/Mémo", | 888 | "Entry Title/Memo": "Titre de l'entrée/Mémo", |
| 889 | "WI_Entry_Status_Constant": "Constante", | 889 | "WI_Entry_Status_Constant": "Constante", |
| @@ -950,7 +950,7 @@ | |||
| 950 | "prompt_manager_position": "Position", | 950 | "prompt_manager_position": "Position", |
| 951 | "prompt_manager_relative": "Relatif", | 951 | "prompt_manager_relative": "Relatif", |
| 952 | "prompt_manager_depth": "Profondeur", | 952 | "prompt_manager_depth": "Profondeur", |
| 953 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Profondeur d'injection. 0 = après le dernier message, 1 = avant le dernier message, etc.", | 953 | "0 = after the last message, 1 = before the last message, etc.": "0 = après le dernier message, 1 = avant le dernier message, etc.", |
| 954 | "Prompt": "Prompt", | 954 | "Prompt": "Prompt", |
| 955 | "The prompt to be sent.": "Le prompt à envoyer.", | 955 | "The prompt to be sent.": "Le prompt à envoyer.", |
| 956 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Ce prompt ne peut pas être remplacé par les cartes de personnage, même si les remplacements sont préférés.", | 956 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Ce prompt ne peut pas être remplacé par les cartes de personnage, même si les remplacements sont préférés.", |
| @@ -1448,7 +1448,6 @@ | |||
| 1448 | "Add Character and User names to a list of stopping strings.": "Ajouter les noms de personnages et d'utilisateurs à une liste de chaînes d'arrêt.", | 1448 | "Add Character and User names to a list of stopping strings.": "Ajouter les noms de personnages et d'utilisateurs à une liste de chaînes d'arrêt.", |
| 1449 | "Names as Stop Strings": "Noms comme chaînes d'arrêt", | 1449 | "Names as Stop Strings": "Noms comme chaînes d'arrêt", |
| 1450 | "context_allow_post_history_instructions": "Inclut les instructions post-historiques à la fin du prompt, si elles sont définies dans la fiche de personnage ET si l'option 'Préférer les instructions de personnage' est activée.\nN'EST PAS RECOMMANDÉ POUR LES MODÈLES DE COMPLÉTION DE TEXTE, CAR IL PEUT ENTRAÎNER DE MAUVAIS RÉSULTATS.", | 1450 | "context_allow_post_history_instructions": "Inclut les instructions post-historiques à la fin du prompt, si elles sont définies dans la fiche de personnage ET si l'option 'Préférer les instructions de personnage' est activée.\nN'EST PAS RECOMMANDÉ POUR LES MODÈLES DE COMPLÉTION DE TEXTE, CAR IL PEUT ENTRAÎNER DE MAUVAIS RÉSULTATS.", |
| 1451 | "Allow Post-History Instructions": "Autoriser les instructions post-histoire", | ||
| 1452 | "Instruct Template": "Modèle d'instruction", | 1451 | "Instruct Template": "Modèle d'instruction", |
| 1453 | "instruct_derived": "Dériver des métadonnées du modèle, si possible.", | 1452 | "instruct_derived": "Dériver des métadonnées du modèle, si possible.", |
| 1454 | "instruct_enabled": "Activer le mode d'instruction", | 1453 | "instruct_enabled": "Activer le mode d'instruction", |
| @@ -1545,7 +1544,7 @@ | |||
| 1545 | "Filter to Characters or Tags": "Filtre sur les personnages ou les tags", | 1544 | "Filter to Characters or Tags": "Filtre sur les personnages ou les tags", |
| 1546 | "Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry": "Changez le filtre Personnages/Tags pour exclure les personnages et tags listés de la correspondance pour cette entrée.", | 1545 | "Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry": "Changez le filtre Personnages/Tags pour exclure les personnages et tags listés de la correspondance pour cette entrée.", |
| 1547 | "Exclude": "Exclure", | 1546 | "Exclude": "Exclure", |
| 1548 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "Position d'injection. Relative (par rapport à d'autres prompts dans le gestionnaire de prompts) ou In-chat @ Depth.", | 1547 | "Relative (to other prompts in prompt manager) or In-chat @ Depth.": "Relative (par rapport à d'autres prompts dans le gestionnaire de prompts) ou In-chat @ Depth.", |
| 1549 | "prompt_manager_in_chat": "In-chat", | 1548 | "prompt_manager_in_chat": "In-chat", |
| 1550 | "The content of this prompt is pulled from elsewhere and cannot be edited here.": "Le contenu de ce message est tiré d'autres sources et ne peut être modifié ici..", | 1549 | "The content of this prompt is pulled from elsewhere and cannot be edited here.": "Le contenu de ce message est tiré d'autres sources et ne peut être modifié ici..", |
| 1551 | "Open checkpoint chat\nShift+Click to replace the existing checkpoint with a new one": "Cliquer pour ouvrir le chat du point de contrôle\nShift+Click pour remplacer le point de contrôle existant par un nouveau.", | 1550 | "Open checkpoint chat\nShift+Click to replace the existing checkpoint with a new one": "Cliquer pour ouvrir le chat du point de contrôle\nShift+Click pour remplacer le point de contrôle existant par un nouveau.", |
| @@ -2043,7 +2042,6 @@ | |||
| 2043 | "Trigger %": "Déclencheur %", | 2042 | "Trigger %": "Déclencheur %", |
| 2044 | "Only chunk on custom boundary": "Only chunk on custom boundary", | 2043 | "Only chunk on custom boundary": "Only chunk on custom boundary", |
| 2045 | "Generate Caption": "Générer une légende", | 2044 | "Generate Caption": "Générer une légende", |
| 2046 | "Use System Prompt": "Utiliser le prompt système:", | ||
| 2047 | "Settings Preset": "Preset de réglages:", | 2045 | "Settings Preset": "Preset de réglages:", |
| 2048 | "System Prompt Name": "Nom du prompt système:", | 2046 | "System Prompt Name": "Nom du prompt système:", |
| 2049 | "Instruct Mode": "Mode Instruction:", | 2047 | "Instruct Mode": "Mode Instruction:", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Sameinar samhliða kerfisskilaboð í eitt (sem er utan umsagna dæmum). Getur bætt samfelldni fyrir sumar módel.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Sameinar samhliða kerfisskilaboð í eitt (sem er utan umsagna dæmum). Getur bætt samfelldni fyrir sumar módel.", |
| 236 | "Enable function calling": "Virkja aðgerðarkall", | 236 | "Enable function calling": "Virkja aðgerðarkall", |
| 237 | "Send inline images": "Senda myndir í línu", | 237 | "Send inline images": "Senda myndir í línu", |
| 238 | "image_inlining_hint_1": "Sendir myndir í skilaboðum ef líkanið styður það (t.d. GPT-4V, Claude 3 eða Llava 13B).\n Nota", | 238 | "image_inlining_hint_1": "Sendir myndir í skilaboðum ef líkanið styður það.\n Nota", |
| 239 | "image_inlining_hint_2": "aðgerð á hvaða skilaboðum sem er eða", | 239 | "image_inlining_hint_2": "aðgerð á hvaða skilaboðum sem er eða", |
| 240 | "image_inlining_hint_3": "valmynd til að hengja myndskrá við spjallið.", | 240 | "image_inlining_hint_3": "valmynd til að hengja myndskrá við spjallið.", |
| 241 | "Inline Image Quality": "Innbyggð myndgæði", | 241 | "Inline Image Quality": "Innbyggð myndgæði", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Fyrirfram fylla viðstoðarmanns", | 253 | "Assistant Prefill": "Fyrirfram fylla viðstoðarmanns", |
| 254 | "Start Claude's answer with...": "Byrjaðu svör Claude með...", | 254 | "Start Claude's answer with...": "Byrjaðu svör Claude með...", |
| 255 | "Assistant Impersonation Prefill": "Forfylling aðstoðarmanns eftirlíkingar", | 255 | "Assistant Impersonation Prefill": "Forfylling aðstoðarmanns eftirlíkingar", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Nota kerfisflug (einungis Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Senda kerfisflug fyrir styðjandi módel. Ef óvirk, er notendaskilaboð bætt við byrjun flugs.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Senda kerfisflug fyrir styðjandi módel. Ef óvirk, er notendaskilaboð bætt við byrjun flugs.", |
| 258 | "User first message": "Fyrstu skilaboð notanda", | 257 | "User first message": "Fyrstu skilaboð notanda", |
| 259 | "Restore User first message": "Endurheimta fyrstu skilaboð notanda", | 258 | "Restore User first message": "Endurheimta fyrstu skilaboð notanda", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Chat Start", | 410 | "Chat Start": "Chat Start", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Bættu Chat Start og Example Separator við lista yfir stöðvunarstrengi.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Bættu Chat Start og Example Separator við lista yfir stöðvunarstrengi.", |
| 413 | "Use as Stop Strings": "Nota sem Stoppa Strengir", | 412 | "Use as Stop Strings": "Nota sem Stoppa Strengir", |
| 414 | "context_allow_jailbreak": "Inniheldur Jailbreak í lok hvetjunnar, ef það er skilgreint á stafkortinu OG ''Velst Char. Jailbreak'' er virkt.\nÞETTA ER EKKI MÆLT FYRIR TEXTAÚRSLUNARGERÐ, GETUR leitt til lélegrar úttaks.", | ||
| 415 | "Allow Jailbreak": "Leyfa jailbreak", | 413 | "Allow Jailbreak": "Leyfa jailbreak", |
| 416 | "Context Order": "Samhengisröð", | 414 | "Context Order": "Samhengisröð", |
| 417 | "Summary": "Samantekt", | 415 | "Summary": "Samantekt", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Niðurhala spjalli sem einfaldan textaskjal", | 938 | "Download chat as plain text document": "Niðurhala spjalli sem einfaldan textaskjal", |
| 941 | "Delete chat file": "Eyða spjallaskrá", | 939 | "Delete chat file": "Eyða spjallaskrá", |
| 942 | "Use tag as folder": "Merktu sem mappa", | 940 | "Use tag as folder": "Merktu sem mappa", |
| 941 | "Hide on character card": "Fela á persónukorti", | ||
| 943 | "Delete tag": "Eyða merki", | 942 | "Delete tag": "Eyða merki", |
| 944 | "Entry Title/Memo": "Titill færslu/Minnisblað", | 943 | "Entry Title/Memo": "Titill færslu/Minnisblað", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI inngangsstaða:\r🔵 Stöðugt\r😢 Venjulegt\r🔗 Vectorized\r❌ Óvirk", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI inngangsstaða:\r🔵 Stöðugt\r😢 Venjulegt\r🔗 Vectorized\r❌ Óvirk", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "Hverjum þessi skilaboð verða eignuð.", | 1009 | "To whom this message will be attributed.": "Hverjum þessi skilaboð verða eignuð.", |
| 1011 | "AI Assistant": "AI aðstoðarmaður", | 1010 | "AI Assistant": "AI aðstoðarmaður", |
| 1012 | "prompt_manager_position": "Staða", | 1011 | "prompt_manager_position": "Staða", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Inndælingarstaða. Við hliðina á öðrum leiðbeiningum (afstætt) eða í spjalli (algert).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Við hliðina á öðrum leiðbeiningum (afstætt) eða í spjalli (algert).", |
| 1014 | "prompt_manager_relative": "Aðstandandi", | 1013 | "prompt_manager_relative": "Aðstandandi", |
| 1015 | "prompt_manager_depth": "Dýpt", | 1014 | "prompt_manager_depth": "Dýpt", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Inndælingardýpt. 0 = eftir síðustu skilaboð, 1 = fyrir síðustu skilaboð o.s.frv.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = eftir síðustu skilaboð, 1 = fyrir síðustu skilaboð o.s.frv.", |
| 1017 | "Prompt": "Ábending", | 1016 | "Prompt": "Ábending", |
| 1018 | "The prompt to be sent.": "Tilvitnunin sem á að senda.", | 1017 | "The prompt to be sent.": "Tilvitnunin sem á að senda.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Ekki er hægt að hnekkja þessari vísbendingu með persónuspjöldum, jafnvel þótt hnekkingar séu æskilegar.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Ekki er hægt að hnekkja þessari vísbendingu með persónuspjöldum, jafnvel þótt hnekkingar séu æskilegar.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina i messaggi di sistema consecutivi in uno solo (escludendo i dialoghi di esempio). Potrebbe migliorare la coerenza per alcuni modelli.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina i messaggi di sistema consecutivi in uno solo (escludendo i dialoghi di esempio). Potrebbe migliorare la coerenza per alcuni modelli.", |
| 236 | "Enable function calling": "Abilita la chiamata alla funzione", | 236 | "Enable function calling": "Abilita la chiamata alla funzione", |
| 237 | "Send inline images": "Invia immagini inline", | 237 | "Send inline images": "Invia immagini inline", |
| 238 | "image_inlining_hint_1": "Invia immagini nei prompt se il modello lo supporta (ad esempio GPT-4V, Claude 3 o Llava 13B).\n Usa il", | 238 | "image_inlining_hint_1": "Invia immagini nei prompt se il modello lo supporta.\n Usa il", |
| 239 | "image_inlining_hint_2": "azione su qualsiasi messaggio o il", | 239 | "image_inlining_hint_2": "azione su qualsiasi messaggio o il", |
| 240 | "image_inlining_hint_3": "menu per allegare un file immagine alla chat.", | 240 | "image_inlining_hint_3": "menu per allegare un file immagine alla chat.", |
| 241 | "Inline Image Quality": "Qualità dell'immagine in linea", | 241 | "Inline Image Quality": "Qualità dell'immagine in linea", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Prefill assistente", | 253 | "Assistant Prefill": "Prefill assistente", |
| 254 | "Start Claude's answer with...": "Inizia la risposta di Claude con...", | 254 | "Start Claude's answer with...": "Inizia la risposta di Claude con...", |
| 255 | "Assistant Impersonation Prefill": "Precompilazione imitazione assistente", | 255 | "Assistant Impersonation Prefill": "Precompilazione imitazione assistente", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Usa prompt di sistema (solo Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Invia il prompt di sistema per i modelli supportati. Se disabilitato, il messaggio dell'utente viene aggiunto all'inizio del prompt.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Invia il prompt di sistema per i modelli supportati. Se disabilitato, il messaggio dell'utente viene aggiunto all'inizio del prompt.", |
| 258 | "User first message": "Primo messaggio dell'utente", | 257 | "User first message": "Primo messaggio dell'utente", |
| 259 | "Restore User first message": "Ripristina il primo messaggio dell'utente", | 258 | "Restore User first message": "Ripristina il primo messaggio dell'utente", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Inizio chat", | 410 | "Chat Start": "Inizio chat", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Aggiungi Inizio chat e Separatore di esempio a un elenco di stringhe di arresto.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Aggiungi Inizio chat e Separatore di esempio a un elenco di stringhe di arresto.", |
| 413 | "Use as Stop Strings": "Usa come stringhe di arresto", | 412 | "Use as Stop Strings": "Usa come stringhe di arresto", |
| 414 | "context_allow_jailbreak": "Include il jailbreak alla fine del prompt, se definito nella carta personaggio E ''Preferisci Char. Il jailbreak'' è abilitato.\nQUESTO NON È CONSIGLIATO PER I MODELLI DI COMPLETAMENTO DEL TESTO, PUÒ PORTARE A UN RISULTATO CATTIVO.", | ||
| 415 | "Allow Jailbreak": "Consenti jailbreak", | 413 | "Allow Jailbreak": "Consenti jailbreak", |
| 416 | "Context Order": "Ordine del contesto", | 414 | "Context Order": "Ordine del contesto", |
| 417 | "Summary": "Riepilogo", | 415 | "Summary": "Riepilogo", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Scarica la chat come documento di testo semplice", | 938 | "Download chat as plain text document": "Scarica la chat come documento di testo semplice", |
| 941 | "Delete chat file": "Elimina il file di chat", | 939 | "Delete chat file": "Elimina il file di chat", |
| 942 | "Use tag as folder": "Contrassegna come cartella", | 940 | "Use tag as folder": "Contrassegna come cartella", |
| 941 | "Hide on character card": "Nascondi sulla scheda del personaggio", | ||
| 943 | "Delete tag": "Elimina il tag", | 942 | "Delete tag": "Elimina il tag", |
| 944 | "Entry Title/Memo": "Titolo/Memo dell'Ingresso", | 943 | "Entry Title/Memo": "Titolo/Memo dell'Ingresso", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Stato della voce WI:\r🔵 Costante\r🟢 Normale\r🔗 Vettorializzato\r❌Disabili", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Stato della voce WI:\r🔵 Costante\r🟢 Normale\r🔗 Vettorializzato\r❌Disabili", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "A chi verrà attribuito questo messaggio.", | 1009 | "To whom this message will be attributed.": "A chi verrà attribuito questo messaggio.", |
| 1011 | "AI Assistant": "Assistente AI", | 1010 | "AI Assistant": "Assistente AI", |
| 1012 | "prompt_manager_position": "Posizione", | 1011 | "prompt_manager_position": "Posizione", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Posizione di iniezione. Accanto ad altri suggerimenti (relativo) o in chat (assoluto).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Accanto ad altri suggerimenti (relativo) o in chat (assoluto).", |
| 1014 | "prompt_manager_relative": "Parente", | 1013 | "prompt_manager_relative": "Parente", |
| 1015 | "prompt_manager_depth": "Profondità", | 1014 | "prompt_manager_depth": "Profondità", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Profondità di iniezione. 0 = dopo l'ultimo messaggio, 1 = prima dell'ultimo messaggio, ecc.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = dopo l'ultimo messaggio, 1 = prima dell'ultimo messaggio, ecc.", |
| 1017 | "Prompt": "Prompt", | 1016 | "Prompt": "Prompt", |
| 1018 | "The prompt to be sent.": "La richiesta da inviare.", | 1017 | "The prompt to be sent.": "La richiesta da inviare.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Questo prompt non può essere sostituito dalle schede personaggio, anche se si preferisce sostituirlo.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Questo prompt non può essere sostituito dalle schede personaggio, anche se si preferisce sostituirlo.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "連続するシステムメッセージを1つに結合します(例のダイアログを除く)。一部のモデルの一貫性を向上させる可能性があります。", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "連続するシステムメッセージを1つに結合します(例のダイアログを除く)。一部のモデルの一貫性を向上させる可能性があります。", |
| 236 | "Enable function calling": "関数呼び出しを有効にする", | 236 | "Enable function calling": "関数呼び出しを有効にする", |
| 237 | "Send inline images": "インライン画像を送信", | 237 | "Send inline images": "インライン画像を送信", |
| 238 | "image_inlining_hint_1": "モデルがサポートしている場合(GPT-4V、Claude 3、Llava 13Bなど)、プロンプトで画像を送信します。", | 238 | "image_inlining_hint_1": "モデルがサポートしている場合、プロンプトで画像を送信します。", |
| 239 | "image_inlining_hint_2": "メッセージに対するアクションまたは", | 239 | "image_inlining_hint_2": "メッセージに対するアクションまたは", |
| 240 | "image_inlining_hint_3": "チャットに画像ファイルを添付するためのメニュー。", | 240 | "image_inlining_hint_3": "チャットに画像ファイルを添付するためのメニュー。", |
| 241 | "Inline Image Quality": "インライン画像品質", | 241 | "Inline Image Quality": "インライン画像品質", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "アシスタントプリフィル", | 253 | "Assistant Prefill": "アシスタントプリフィル", |
| 254 | "Start Claude's answer with...": "クロードの回答を...で始める", | 254 | "Start Claude's answer with...": "クロードの回答を...で始める", |
| 255 | "Assistant Impersonation Prefill": "アシスタントのなりすまし事前入力", | 255 | "Assistant Impersonation Prefill": "アシスタントのなりすまし事前入力", |
| 256 | "Use system prompt (Claude 2.1+ only)": "システムプロンプトを使用します(クロード2.1以降のみ)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "サポートされているモデルのシステムプロンプトを送信します。無効にすると、ユーザーメッセージがプロンプトの先頭に追加されます。", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "サポートされているモデルのシステムプロンプトを送信します。無効にすると、ユーザーメッセージがプロンプトの先頭に追加されます。", |
| 258 | "User first message": "ユーザーの最初のメッセージ", | 257 | "User first message": "ユーザーの最初のメッセージ", |
| 259 | "Restore User first message": "ユーザーの最初のメッセージを復元する", | 258 | "Restore User first message": "ユーザーの最初のメッセージを復元する", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "チャット開始", | 410 | "Chat Start": "チャット開始", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "停止文字列のリストにチャット開始と例の区切り文字を追加します。", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "停止文字列のリストにチャット開始と例の区切り文字を追加します。", |
| 413 | "Use as Stop Strings": "ストップ文字列として使用", | 412 | "Use as Stop Strings": "ストップ文字列として使用", |
| 414 | "context_allow_jailbreak": "文字カードで定義されていて、「文字 Jailbreak を優先」が有効になっている場合は、プロンプトの最後に Jailbreak が含まれます。\nこれはテキスト補完モデルには推奨されません。出力が悪くなる可能性があります。", | ||
| 415 | "Allow Jailbreak": "脱獄を許可する", | 413 | "Allow Jailbreak": "脱獄を許可する", |
| 416 | "Context Order": "コンテキスト順序", | 414 | "Context Order": "コンテキスト順序", |
| 417 | "Summary": "まとめ", | 415 | "Summary": "まとめ", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "プレーンテキストドキュメントとしてチャットをダウンロード", | 938 | "Download chat as plain text document": "プレーンテキストドキュメントとしてチャットをダウンロード", |
| 941 | "Delete chat file": "チャットファイルを削除", | 939 | "Delete chat file": "チャットファイルを削除", |
| 942 | "Use tag as folder": "フォルダとしてタグ付け", | 940 | "Use tag as folder": "フォルダとしてタグ付け", |
| 941 | "Hide on character card": "キャラクターカードで非表示", | ||
| 943 | "Delete tag": "タグを削除", | 942 | "Delete tag": "タグを削除", |
| 944 | "Entry Title/Memo": "エントリータイトル/メモ", | 943 | "Entry Title/Memo": "エントリータイトル/メモ", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI エントリ ステータス: 🔵 定数 🟢 通常 🔗 ベクトル化 ❌ 無効", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI エントリ ステータス: 🔵 定数 🟢 通常 🔗 ベクトル化 ❌ 無効", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "このメッセージの送信者。", | 1009 | "To whom this message will be attributed.": "このメッセージの送信者。", |
| 1011 | "AI Assistant": "AIアシスタント", | 1010 | "AI Assistant": "AIアシスタント", |
| 1012 | "prompt_manager_position": "位置", | 1011 | "prompt_manager_position": "位置", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "挿入位置。他のプロンプトの隣 (相対) またはチャット内 (絶対)。", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "他のプロンプトの隣 (相対) またはチャット内 (絶対)。", |
| 1014 | "prompt_manager_relative": "相対的", | 1013 | "prompt_manager_relative": "相対的", |
| 1015 | "prompt_manager_depth": "深さ", | 1014 | "prompt_manager_depth": "深さ", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "注入の深さ。0 = 最後のメッセージの後、1 = 最後のメッセージの前など。", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = 最後のメッセージの後、1 = 最後のメッセージの前など。", |
| 1017 | "Prompt": "プロンプト", | 1016 | "Prompt": "プロンプト", |
| 1018 | "The prompt to be sent.": "送信されるプロンプト。", | 1017 | "The prompt to be sent.": "送信されるプロンプト。", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "このプロンプトは、オーバーライドが優先される場合でも、キャラクター カードによってオーバーライドすることはできません。", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "このプロンプトは、オーバーライドが優先される場合でも、キャラクター カードによってオーバーライドすることはできません。", |
| @@ -237,7 +237,7 @@ | |||
| 237 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "연속된 시스템 메시지를 하나로 결합합니다(예제 대화 제외). 일부 모델의 일관성을 향상시킬 수 있습니다.", | 237 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "연속된 시스템 메시지를 하나로 결합합니다(예제 대화 제외). 일부 모델의 일관성을 향상시킬 수 있습니다.", |
| 238 | "Enable function calling": "함수 호출 활성화", | 238 | "Enable function calling": "함수 호출 활성화", |
| 239 | "Send inline images": "인라인 이미지 전송", | 239 | "Send inline images": "인라인 이미지 전송", |
| 240 | "image_inlining_hint_1": "모델이 지원하는 경우 메시지로 이미지를 보냅니다(예: GPT-4V, Claude 3 또는 Llava 13B).\n 사용", | 240 | "image_inlining_hint_1": "모델이 지원하는 경우 메시지로 이미지를 보냅니다.\n 사용", |
| 241 | "image_inlining_hint_2": "메시지에 대한 조치 또는", | 241 | "image_inlining_hint_2": "메시지에 대한 조치 또는", |
| 242 | "image_inlining_hint_3": "채팅에 이미지 파일을 첨부하는 메뉴입니다.", | 242 | "image_inlining_hint_3": "채팅에 이미지 파일을 첨부하는 메뉴입니다.", |
| 243 | "Inline Image Quality": "인라인 이미지 품질", | 243 | "Inline Image Quality": "인라인 이미지 품질", |
| @@ -255,7 +255,6 @@ | |||
| 255 | "Assistant Prefill": "어시스턴트 프리필", | 255 | "Assistant Prefill": "어시스턴트 프리필", |
| 256 | "Start Claude's answer with...": "클로드의 답변 시작하기...", | 256 | "Start Claude's answer with...": "클로드의 답변 시작하기...", |
| 257 | "Assistant Impersonation Prefill": "어시스턴트 사칭 프리필", | 257 | "Assistant Impersonation Prefill": "어시스턴트 사칭 프리필", |
| 258 | "Use system prompt (Claude 2.1+ only)": "시스템 프롬프트 사용 (클로드 2.1+ 전용)", | ||
| 259 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "지원되는 모델에 대한 시스템 프롬프트를 보냅니다. 비활성화된 경우 사용자 메시지가 프롬프트의 처음에 추가됩니다.", | 258 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "지원되는 모델에 대한 시스템 프롬프트를 보냅니다. 비활성화된 경우 사용자 메시지가 프롬프트의 처음에 추가됩니다.", |
| 260 | "User first message": "사용자 첫 번째 메시지", | 259 | "User first message": "사용자 첫 번째 메시지", |
| 261 | "Restore User first message": "사용자의 첫 번째 메시지 복원", | 260 | "Restore User first message": "사용자의 첫 번째 메시지 복원", |
| @@ -421,7 +420,6 @@ | |||
| 421 | "Chat Start": "채팅 시작", | 420 | "Chat Start": "채팅 시작", |
| 422 | "Add Chat Start and Example Separator to a list of stopping strings.": "중지 문자열 목록에 채팅 시작 및 예제 구분 기호를 추가합니다.", | 421 | "Add Chat Start and Example Separator to a list of stopping strings.": "중지 문자열 목록에 채팅 시작 및 예제 구분 기호를 추가합니다.", |
| 423 | "Use as Stop Strings": "중지 문자열로 사용", | 422 | "Use as Stop Strings": "중지 문자열로 사용", |
| 424 | "context_allow_jailbreak": "캐릭터 카드에 정의되어 있고 ''Prefer Char. Jailbreak''가 활성화되어 있는 경우 프롬프트 끝에 Jailbreak를 포함합니다.\n이는 텍스트 완성 모델에 권장되지 않으며, 나쁜 출력으로 이어질 수 있습니다.", | ||
| 425 | "Allow Jailbreak": "탈옥 허용", | 423 | "Allow Jailbreak": "탈옥 허용", |
| 426 | "Context Order": "컨텍스트 순서", | 424 | "Context Order": "컨텍스트 순서", |
| 427 | "Summary": "요약", | 425 | "Summary": "요약", |
| @@ -956,6 +954,7 @@ | |||
| 956 | "Download chat as plain text document": "일반 텍스트 문서로 채팅 다운로드", | 954 | "Download chat as plain text document": "일반 텍스트 문서로 채팅 다운로드", |
| 957 | "Delete chat file": "채팅 파일 삭제", | 955 | "Delete chat file": "채팅 파일 삭제", |
| 958 | "Use tag as folder": "폴더로 태그 지정", | 956 | "Use tag as folder": "폴더로 태그 지정", |
| 957 | "Hide on character card": "캐릭터 카드에서 숨기기", | ||
| 959 | "Delete tag": "태그 삭제", | 958 | "Delete tag": "태그 삭제", |
| 960 | "Entry Title/Memo": "항목 제목/메모", | 959 | "Entry Title/Memo": "항목 제목/메모", |
| 961 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI 입국 상태:\r🔵 상시\r🟢 조건 만족시\r🔗 벡터화됨\r❌ 비활성화", | 960 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI 입국 상태:\r🔵 상시\r🟢 조건 만족시\r🔗 벡터화됨\r❌ 비활성화", |
| @@ -1027,11 +1026,11 @@ | |||
| 1027 | "To whom this message will be attributed.": "해당 프롬프트에 부여할 역할은 무엇인가요?", | 1026 | "To whom this message will be attributed.": "해당 프롬프트에 부여할 역할은 무엇인가요?", |
| 1028 | "AI Assistant": "AI 어시스턴트", | 1027 | "AI Assistant": "AI 어시스턴트", |
| 1029 | "prompt_manager_position": "위치", | 1028 | "prompt_manager_position": "위치", |
| 1030 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "주입 위치. 다른 프롬프트 옆(상대적) 또는 채팅 내(절대적).", | 1029 | "Next to other prompts (relative) or in-chat (absolute).": "다른 프롬프트 옆(상대적) 또는 채팅 내(절대적).", |
| 1031 | "prompt_manager_relative": "상대적인", | 1030 | "prompt_manager_relative": "상대적인", |
| 1032 | "prompt_manager_in_chat": "깊이에 따라", | 1031 | "prompt_manager_in_chat": "깊이에 따라", |
| 1033 | "prompt_manager_depth": "깊이", | 1032 | "prompt_manager_depth": "깊이", |
| 1034 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "주입 깊이. 0 = 마지막 메시지 뒤, 1 = 마지막 메시지 앞 등", | 1033 | "0 = after the last message, 1 = before the last message, etc.": "0 = 마지막 메시지 뒤, 1 = 마지막 메시지 앞 등", |
| 1035 | "Prompt": "프롬프트", | 1034 | "Prompt": "프롬프트", |
| 1036 | "The prompt to be sent.": "보내질 프롬프트 내용을 작성하는 부분입니다.", | 1035 | "The prompt to be sent.": "보내질 프롬프트 내용을 작성하는 부분입니다.", |
| 1037 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "이 프롬프트는 고급 정의에서 재정의가 선호되는 경우에도 재정의될 수 없습니다.", | 1036 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "이 프롬프트는 고급 정의에서 재정의가 선호되는 경우에도 재정의될 수 없습니다.", |
| @@ -1501,7 +1500,7 @@ | |||
| 1501 | "enable_functions_desc_1": "다양한 확장 프로그램에서 추가 기능을 제공하기 위한", | 1500 | "enable_functions_desc_1": "다양한 확장 프로그램에서 추가 기능을 제공하기 위한", |
| 1502 | "enable_functions_desc_2": "기능 도구", | 1501 | "enable_functions_desc_2": "기능 도구", |
| 1503 | "enable_functions_desc_3": "를 사용할 수 있게 합니다.", | 1502 | "enable_functions_desc_3": "를 사용할 수 있게 합니다.", |
| 1504 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "삽입 깊이. 상대적인 (프롬프트 관리 목록에 있는 다른 프롬프트들에 비해) 또는 @Depth 깊이에 따라.", | 1503 | "Relative (to other prompts in prompt manager) or In-chat @ Depth.": "상대적인 (프롬프트 관리 목록에 있는 다른 프롬프트들에 비해) 또는 @Depth 깊이에 따라.", |
| 1505 | "Instruct Template": "지시 템플릿", | 1504 | "Instruct Template": "지시 템플릿", |
| 1506 | "System Message Sequences": "시스템 메시지 시퀀스", | 1505 | "System Message Sequences": "시스템 메시지 시퀀스", |
| 1507 | "System Prompt Sequences": "시스템 프롬프트 시퀀스", | 1506 | "System Prompt Sequences": "시스템 프롬프트 시퀀스", |
| @@ -1520,7 +1519,6 @@ | |||
| 1520 | "Always": "항상 추가함", | 1519 | "Always": "항상 추가함", |
| 1521 | "Separators as Stop Strings": "구분 기호를 정지 문자열로 사용하기", | 1520 | "Separators as Stop Strings": "구분 기호를 정지 문자열로 사용하기", |
| 1522 | "Names as Stop Strings": "캐릭터의 이름들을 정지 문자열로 사용하기", | 1521 | "Names as Stop Strings": "캐릭터의 이름들을 정지 문자열로 사용하기", |
| 1523 | "Allow Post-History Instructions": "Post-History 지침 허용", | ||
| 1524 | "Image Captioning": "이미지 캡셔닝", | 1522 | "Image Captioning": "이미지 캡셔닝", |
| 1525 | "Automatically caption images": "자동으로 이미지에 대한 설명 문장으로 나타내기", | 1523 | "Automatically caption images": "자동으로 이미지에 대한 설명 문장으로 나타내기", |
| 1526 | "Edit captions before saving": "저장하기 전에 이미지에 대한 설명 문장 편집하기", | 1524 | "Edit captions before saving": "저장하기 전에 이미지에 대한 설명 문장 편집하기", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combineert opeenvolgende systeemberichten tot één (exclusief voorbeeld dialogen). Kan de coherentie verbeteren voor sommige modellen.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combineert opeenvolgende systeemberichten tot één (exclusief voorbeeld dialogen). Kan de coherentie verbeteren voor sommige modellen.", |
| 236 | "Enable function calling": "Schakel functieaanroepen in", | 236 | "Enable function calling": "Schakel functieaanroepen in", |
| 237 | "Send inline images": "Inline afbeeldingen verzenden", | 237 | "Send inline images": "Inline afbeeldingen verzenden", |
| 238 | "image_inlining_hint_1": "Verzendt afbeeldingen in prompts als het model dit ondersteunt (bijvoorbeeld GPT-4V, Claude 3 of Llava 13B).\n Gebruik de", | 238 | "image_inlining_hint_1": "Verzendt afbeeldingen in prompts als het model dit ondersteunt.\n Gebruik de", |
| 239 | "image_inlining_hint_2": "actie op elk bericht of de", | 239 | "image_inlining_hint_2": "actie op elk bericht of de", |
| 240 | "image_inlining_hint_3": "menu om een afbeeldingsbestand aan de chat toe te voegen.", | 240 | "image_inlining_hint_3": "menu om een afbeeldingsbestand aan de chat toe te voegen.", |
| 241 | "Inline Image Quality": "Inline-beeldkwaliteit", | 241 | "Inline Image Quality": "Inline-beeldkwaliteit", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Assistent Voorvullen", | 253 | "Assistant Prefill": "Assistent Voorvullen", |
| 254 | "Start Claude's answer with...": "Start het antwoord van Claude met...", | 254 | "Start Claude's answer with...": "Start het antwoord van Claude met...", |
| 255 | "Assistant Impersonation Prefill": "Vooraf invullen van assistent-imitatie", | 255 | "Assistant Impersonation Prefill": "Vooraf invullen van assistent-imitatie", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Gebruik systeemprompt (alleen Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Verzend de systeemprompt voor ondersteunde modellen. Als dit is uitgeschakeld, wordt het gebruikersbericht toegevoegd aan het begin van de prompt.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Verzend de systeemprompt voor ondersteunde modellen. Als dit is uitgeschakeld, wordt het gebruikersbericht toegevoegd aan het begin van de prompt.", |
| 258 | "User first message": "Bericht van de gebruiker eerst", | 257 | "User first message": "Bericht van de gebruiker eerst", |
| 259 | "Restore User first message": "Herstel gebruiker eerste bericht", | 258 | "Restore User first message": "Herstel gebruiker eerste bericht", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Chatstart", | 410 | "Chat Start": "Chatstart", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Voeg Chat Start en Voorbeeldscheidingsteken toe aan een lijst met stoptekenreeksen.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Voeg Chat Start en Voorbeeldscheidingsteken toe aan een lijst met stoptekenreeksen.", |
| 413 | "Use as Stop Strings": "Gebruik als stopreeksen", | 412 | "Use as Stop Strings": "Gebruik als stopreeksen", |
| 414 | "context_allow_jailbreak": "Inclusief jailbreak aan het einde van de prompt, indien gedefinieerd in de karakterkaart EN ''Prefer Char. Jailbreak'' is ingeschakeld.\nDIT WORDT NIET AANBEVOLEN VOOR MODELLEN VOOR HET INVOEREN VAN TEKST. KAN TOT SLECHTE UITVOER LEIDEN.", | ||
| 415 | "Allow Jailbreak": "Jailbreak toestaan", | 413 | "Allow Jailbreak": "Jailbreak toestaan", |
| 416 | "Context Order": "Contextvolgorde", | 414 | "Context Order": "Contextvolgorde", |
| 417 | "Summary": "Samenvatting", | 415 | "Summary": "Samenvatting", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Download chat als plat tekstbestand", | 938 | "Download chat as plain text document": "Download chat als plat tekstbestand", |
| 941 | "Delete chat file": "Chatbestand verwijderen", | 939 | "Delete chat file": "Chatbestand verwijderen", |
| 942 | "Use tag as folder": "Taggen als map", | 940 | "Use tag as folder": "Taggen als map", |
| 941 | "Hide on character card": "Verbergen op karakterkaart", | ||
| 943 | "Delete tag": "Tag verwijderen", | 942 | "Delete tag": "Tag verwijderen", |
| 944 | "Entry Title/Memo": "Titel/Memo", | 943 | "Entry Title/Memo": "Titel/Memo", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI-invoerstatus:\r🔵Constant\r🟢 Normaal\r🔗 Gevectoriseerd\r❌ Uitgeschakeld", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI-invoerstatus:\r🔵Constant\r🟢 Normaal\r🔗 Gevectoriseerd\r❌ Uitgeschakeld", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "Aan wie dit bericht wordt toegeschreven.", | 1009 | "To whom this message will be attributed.": "Aan wie dit bericht wordt toegeschreven.", |
| 1011 | "AI Assistant": "AI-assistent", | 1010 | "AI Assistant": "AI-assistent", |
| 1012 | "prompt_manager_position": "Positie", | 1011 | "prompt_manager_position": "Positie", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Injectiepositie. Naast andere prompts (relatief) of in-chat (absoluut).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Naast andere prompts (relatief) of in-chat (absoluut).", |
| 1014 | "prompt_manager_relative": "Familielid", | 1013 | "prompt_manager_relative": "Familielid", |
| 1015 | "prompt_manager_depth": "Diepte", | 1014 | "prompt_manager_depth": "Diepte", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Injectiediepte. 0 = na het laatste bericht, 1 = voor het laatste bericht, etc.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = na het laatste bericht, 1 = voor het laatste bericht, etc.", |
| 1017 | "Prompt": "Prompt", | 1016 | "Prompt": "Prompt", |
| 1018 | "The prompt to be sent.": "De prompt die verzonden moet worden.", | 1017 | "The prompt to be sent.": "De prompt die verzonden moet worden.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Deze prompt kan niet worden overschreven door karakterkaarten, zelfs als overschrijvingen de voorkeur hebben.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Deze prompt kan niet worden overschreven door karakterkaarten, zelfs als overschrijvingen de voorkeur hebben.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensagens do sistema consecutivas em uma (excluindo diálogos de exemplo). Pode melhorar a coerência para alguns modelos.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Combina mensagens do sistema consecutivas em uma (excluindo diálogos de exemplo). Pode melhorar a coerência para alguns modelos.", |
| 236 | "Enable function calling": "Habilitar chamada de função", | 236 | "Enable function calling": "Habilitar chamada de função", |
| 237 | "Send inline images": "Enviar imagens inline", | 237 | "Send inline images": "Enviar imagens inline", |
| 238 | "image_inlining_hint_1": "Envia imagens em prompts se o modelo suportar (por exemplo, GPT-4V, Claude 3 ou Llava 13B).\n Use o", | 238 | "image_inlining_hint_1": "Envia imagens em prompts se o modelo suportar.\n Use o", |
| 239 | "image_inlining_hint_2": "ação em qualquer mensagem ou", | 239 | "image_inlining_hint_2": "ação em qualquer mensagem ou", |
| 240 | "image_inlining_hint_3": "menu para anexar um arquivo de imagem ao chat.", | 240 | "image_inlining_hint_3": "menu para anexar um arquivo de imagem ao chat.", |
| 241 | "Inline Image Quality": "Qualidade de imagem embutida", | 241 | "Inline Image Quality": "Qualidade de imagem embutida", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Preenchimento prévio do assistente", | 253 | "Assistant Prefill": "Preenchimento prévio do assistente", |
| 254 | "Start Claude's answer with...": "Iniciar resposta de Claude com...", | 254 | "Start Claude's answer with...": "Iniciar resposta de Claude com...", |
| 255 | "Assistant Impersonation Prefill": "Pré-preenchimento de representação do assistente", | 255 | "Assistant Impersonation Prefill": "Pré-preenchimento de representação do assistente", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Usar prompt do sistema (apenas Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar o prompt do sistema para modelos suportados. Se desativado, a mensagem do usuário é adicionada ao início do prompt.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Enviar o prompt do sistema para modelos suportados. Se desativado, a mensagem do usuário é adicionada ao início do prompt.", |
| 258 | "User first message": "Primeira mensagem do usuário", | 257 | "User first message": "Primeira mensagem do usuário", |
| 259 | "Restore User first message": "Restaurar a primeira mensagem do usuário", | 258 | "Restore User first message": "Restaurar a primeira mensagem do usuário", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Início do Chat", | 410 | "Chat Start": "Início do Chat", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Adicione o início do bate-papo e o separador de exemplo a uma lista de strings de parada.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Adicione o início do bate-papo e o separador de exemplo a uma lista de strings de parada.", |
| 413 | "Use as Stop Strings": "Usar como Strings de Parada", | 412 | "Use as Stop Strings": "Usar como Strings de Parada", |
| 414 | "context_allow_jailbreak": "Inclui Jailbreak no final do prompt, se definido no cartão de personagem E ''Prefer Char. Jailbreak'' está habilitado.\nISTO NÃO É RECOMENDADO PARA MODELOS DE COMPLEMENTAÇÃO DE TEXTO, PODE LEVAR A UMA SAÍDA RUIM.", | ||
| 415 | "Allow Jailbreak": "Permitir jailbreak", | 413 | "Allow Jailbreak": "Permitir jailbreak", |
| 416 | "Context Order": "Ordem de Contexto", | 414 | "Context Order": "Ordem de Contexto", |
| 417 | "Summary": "Resumo", | 415 | "Summary": "Resumo", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Baixar bate-papo como documento de texto simples", | 938 | "Download chat as plain text document": "Baixar bate-papo como documento de texto simples", |
| 941 | "Delete chat file": "Excluir arquivo de bate-papo", | 939 | "Delete chat file": "Excluir arquivo de bate-papo", |
| 942 | "Use tag as folder": "Marcar como pasta", | 940 | "Use tag as folder": "Marcar como pasta", |
| 941 | "Hide on character card": "Ocultar no cartão do personagem", | ||
| 943 | "Delete tag": "Excluir tag", | 942 | "Delete tag": "Excluir tag", |
| 944 | "Entry Title/Memo": "Título da Entrada/Memo", | 943 | "Entry Title/Memo": "Título da Entrada/Memo", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Status de entrada WI:\r🔵 Constante\r🟢 Normais\r🔗 Vetorizado\r❌ Desativado", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Status de entrada WI:\r🔵 Constante\r🟢 Normais\r🔗 Vetorizado\r❌ Desativado", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "A quem esta mensagem será atribuída.", | 1009 | "To whom this message will be attributed.": "A quem esta mensagem será atribuída.", |
| 1011 | "AI Assistant": "Assistente de IA", | 1010 | "AI Assistant": "Assistente de IA", |
| 1012 | "prompt_manager_position": "Posição", | 1011 | "prompt_manager_position": "Posição", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Posição de injeção. Ao lado de outras solicitações (relativas) ou no chat (absolutas).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Ao lado de outras solicitações (relativas) ou no chat (absolutas).", |
| 1014 | "prompt_manager_relative": "Relativo", | 1013 | "prompt_manager_relative": "Relativo", |
| 1015 | "prompt_manager_depth": "Profundidade", | 1014 | "prompt_manager_depth": "Profundidade", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Profundidade de injeção. 0 = após a última mensagem, 1 = antes da última mensagem, etc.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = após a última mensagem, 1 = antes da última mensagem, etc.", |
| 1017 | "Prompt": "Prompt", | 1016 | "Prompt": "Prompt", |
| 1018 | "The prompt to be sent.": "O prompt a ser enviado.", | 1017 | "The prompt to be sent.": "O prompt a ser enviado.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Este prompt não pode ser substituído por cartas de personagem, mesmo que as substituições sejam preferidas.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Este prompt não pode ser substituído por cartas de personagem, mesmo que as substituições sejam preferidas.", |
| @@ -52,7 +52,7 @@ | |||
| 52 | "Presence Penalty": "Штраф за присутствие", | 52 | "Presence Penalty": "Штраф за присутствие", |
| 53 | "Top A": "Top А", | 53 | "Top A": "Top А", |
| 54 | "Tail Free Sampling": "Tail Free Sampling", | 54 | "Tail Free Sampling": "Tail Free Sampling", |
| 55 | "Rep. Pen. Slope": "Rep. Pen. Slope", | 55 | "Rep. Pen. Slope": "Рост штрафа за повтор к концу промпта", |
| 56 | "Top K": "Top K", | 56 | "Top K": "Top K", |
| 57 | "Top P": "Top P", | 57 | "Top P": "Top P", |
| 58 | "Do Sample": "Включить сэмплинг", | 58 | "Do Sample": "Включить сэмплинг", |
| @@ -162,9 +162,9 @@ | |||
| 162 | "Story String": "Строка истории", | 162 | "Story String": "Строка истории", |
| 163 | "Example Separator": "Разделитель примеров сообщений", | 163 | "Example Separator": "Разделитель примеров сообщений", |
| 164 | "Chat Start": "Начало чата", | 164 | "Chat Start": "Начало чата", |
| 165 | "Activation Regex": "Regex для активации", | 165 | "Activation Regex": "Рег. выражение для активации", |
| 166 | "Instruct Mode": "Режим Instruct", | 166 | "Instruct Mode": "Режим Instruct", |
| 167 | "Wrap Sequences with Newline": "Отделять строки символом новой строки", | 167 | "Wrap Sequences with Newline": "Каждая строка из шаблона на новой строке", |
| 168 | "Include Names": "Добавлять имена", | 168 | "Include Names": "Добавлять имена", |
| 169 | "Force for Groups and Personas": "Также для групп и персон", | 169 | "Force for Groups and Personas": "Также для групп и персон", |
| 170 | "System Prompt": "Системный промпт", | 170 | "System Prompt": "Системный промпт", |
| @@ -299,7 +299,7 @@ | |||
| 299 | "AI Horde": "AI Horde", | 299 | "AI Horde": "AI Horde", |
| 300 | "NovelAI": "NovelAI", | 300 | "NovelAI": "NovelAI", |
| 301 | "OpenAI API key": "Ключ для API OpenAI", | 301 | "OpenAI API key": "Ключ для API OpenAI", |
| 302 | "Trim spaces": "Обрезать пробелы", | 302 | "Trim spaces": "Обрезать пробелы в начале и конце", |
| 303 | "Trim Incomplete Sentences": "Удалять неоконченные предложения", | 303 | "Trim Incomplete Sentences": "Удалять неоконченные предложения", |
| 304 | "Include Newline": "Добавлять новую строку", | 304 | "Include Newline": "Добавлять новую строку", |
| 305 | "Non-markdown strings": "Строки без разметки", | 305 | "Non-markdown strings": "Строки без разметки", |
| @@ -510,7 +510,7 @@ | |||
| 510 | "New preset": "Новый пресет", | 510 | "New preset": "Новый пресет", |
| 511 | "Delete preset": "Удалить пресет", | 511 | "Delete preset": "Удалить пресет", |
| 512 | "API Connections": "Соединения с API", | 512 | "API Connections": "Соединения с API", |
| 513 | "Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "Может помочь с плохими ответами ставя в очередь только подтвержденных работников. Может замедлить время ответа.", | 513 | "Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "Может помочь при плохих ответах, делая запросы только к доверенным рабочим машинам. Может замедлить время ответа.", |
| 514 | "Clear your API key": "Стереть ключ от API", | 514 | "Clear your API key": "Стереть ключ от API", |
| 515 | "Refresh models": "Обновить модели", | 515 | "Refresh models": "Обновить модели", |
| 516 | "Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "Получите свой OpenRouter API токен используя OAuth. У вас будет открыта вкладка openrouter.ai", | 516 | "Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "Получите свой OpenRouter API токен используя OAuth. У вас будет открыта вкладка openrouter.ai", |
| @@ -551,7 +551,7 @@ | |||
| 551 | "Token counts may be inaccurate and provided just for reference.": "Счетчик токенов может быть неточным, используйте как ориентир", | 551 | "Token counts may be inaccurate and provided just for reference.": "Счетчик токенов может быть неточным, используйте как ориентир", |
| 552 | "Click to select a new avatar for this character": "Нажмите чтобы выбрать новый аватар для этого персонажа", | 552 | "Click to select a new avatar for this character": "Нажмите чтобы выбрать новый аватар для этого персонажа", |
| 553 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "Пример:\n [{{user}} is a 28-year-old Romanian cat girl.]", | 553 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "Пример:\n [{{user}} is a 28-year-old Romanian cat girl.]", |
| 554 | "Toggle grid view": "Переключить вид сетки", | 554 | "Toggle grid view": "Сменить вид сетки", |
| 555 | "Add to Favorites": "Добавить в Избранное", | 555 | "Add to Favorites": "Добавить в Избранное", |
| 556 | "Advanced Definition": "Расширенное описание", | 556 | "Advanced Definition": "Расширенное описание", |
| 557 | "Character Lore": "Лор персонажа", | 557 | "Character Lore": "Лор персонажа", |
| @@ -624,7 +624,7 @@ | |||
| 624 | "UI Theme": "Тема UI", | 624 | "UI Theme": "Тема UI", |
| 625 | "This message is invisible for the AI": "Это сообщение невидимо для ИИ", | 625 | "This message is invisible for the AI": "Это сообщение невидимо для ИИ", |
| 626 | "Sampler Priority": "Приоритет сэмплеров", | 626 | "Sampler Priority": "Приоритет сэмплеров", |
| 627 | "Ooba only. Determines the order of samplers.": "Только oobabooga. Определяет порядок сэмплеров.", | 627 | "Ooba only. Determines the order of samplers.": "Только для oobabooga. Определяет порядок сэмплеров.", |
| 628 | "Load default order": "Загрузить стандартный порядок", | 628 | "Load default order": "Загрузить стандартный порядок", |
| 629 | "Max Tokens Second": "Макс. кол-во токенов в секунду", | 629 | "Max Tokens Second": "Макс. кол-во токенов в секунду", |
| 630 | "CFG": "CFG", | 630 | "CFG": "CFG", |
| @@ -661,7 +661,6 @@ | |||
| 661 | "Send inline images": "Отправлять inline-картинки", | 661 | "Send inline images": "Отправлять inline-картинки", |
| 662 | "Assistant Prefill": "Префилл для ассистента", | 662 | "Assistant Prefill": "Префилл для ассистента", |
| 663 | "Start Claude's answer with...": "Начать ответ Клода с...", | 663 | "Start Claude's answer with...": "Начать ответ Клода с...", |
| 664 | "Use system prompt (Claude 2.1+ only)": "Использовать системный промпт (только Claude 2.1+)", | ||
| 665 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Отправлять системный промпт для поддерживаемых моделей. Если отключено, в начало промпта добавляется сообщение пользователя.", | 664 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Отправлять системный промпт для поддерживаемых моделей. Если отключено, в начало промпта добавляется сообщение пользователя.", |
| 666 | "Prompts": "Промпты", | 665 | "Prompts": "Промпты", |
| 667 | "Total Tokens:": "Всего токенов:", | 666 | "Total Tokens:": "Всего токенов:", |
| @@ -695,7 +694,7 @@ | |||
| 695 | "Medium": "Средний", | 694 | "Medium": "Средний", |
| 696 | "Aggressive": "Агрессивный", | 695 | "Aggressive": "Агрессивный", |
| 697 | "Very aggressive": "Очень агрессивный", | 696 | "Very aggressive": "Очень агрессивный", |
| 698 | "Eta_Cutoff_desc": "Eta cutoff - основной параметр специальной техники сэмплинга под названием Eta Sampling. В единицах 1e-4; разумное значение - 3. Установите в 0, чтобы отключить. См. статью Truncation Sampling as Language Model Desmoothing от Хьюитт и др. (2022) для получения подробной информации.", | 697 | "Eta_Cutoff_desc": "Eta cutoff - основной параметр специальной техники сэмплинга под названием Eta Sampling.\nВ единицах 1e-4; разумное значение - 3.\nУстановите в 0, чтобы отключить.\nСм. статью Truncation Sampling as Language Model Desmoothing от Хьюитт и др. (2022) для получения подробной информации.", |
| 699 | "Learn how to contribute your idle GPU cycles to the Horde": "Узнайте, как использовать время простоя вашего GPU для помощи Horde", | 698 | "Learn how to contribute your idle GPU cycles to the Horde": "Узнайте, как использовать время простоя вашего GPU для помощи Horde", |
| 700 | "Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.": "Используйте соответствующий токенизатор для моделей Google через их API. Медленная обработка подсказок, но предлагает намного более точный подсчет токенов.", | 699 | "Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.": "Используйте соответствующий токенизатор для моделей Google через их API. Медленная обработка подсказок, но предлагает намного более точный подсчет токенов.", |
| 701 | "Load koboldcpp order": "Загрузить порядок из koboldcpp", | 700 | "Load koboldcpp order": "Загрузить порядок из koboldcpp", |
| @@ -964,7 +963,7 @@ | |||
| 964 | "char_import_3": "Персонаж с JanitorAI (прямая ссылка или UUID)", | 963 | "char_import_3": "Персонаж с JanitorAI (прямая ссылка или UUID)", |
| 965 | "char_import_4": "Персонаж с Pygmalion.chat (прямая ссылка или UUID)", | 964 | "char_import_4": "Персонаж с Pygmalion.chat (прямая ссылка или UUID)", |
| 966 | "char_import_5": "Персонаж с AICharacterCards.com (прямая ссылка или ID)", | 965 | "char_import_5": "Персонаж с AICharacterCards.com (прямая ссылка или ID)", |
| 967 | "char_import_6": "Прямая ссылка на PNG-файл (чтобы узнать список разрешённых хостов, загляните в", | 966 | "char_import_6": "Прямая ссылка на PNG-файл (список разрешённых хостов находится в", |
| 968 | "char_import_7": ")", | 967 | "char_import_7": ")", |
| 969 | "Grammar String": "Грамматика", | 968 | "Grammar String": "Грамматика", |
| 970 | "GBNF or EBNF, depends on the backend in use. If you're using this you should know which.": "GBNF или EBNF, зависит от бэкенда. Если вы это используете, то, скорее всего, сами знаете, какой именно.", | 969 | "GBNF or EBNF, depends on the backend in use. If you're using this you should know which.": "GBNF или EBNF, зависит от бэкенда. Если вы это используете, то, скорее всего, сами знаете, какой именно.", |
| @@ -1012,14 +1011,14 @@ | |||
| 1012 | "To whom this message will be attributed.": "От чьего лица будет отправляться сообщение.", | 1011 | "To whom this message will be attributed.": "От чьего лица будет отправляться сообщение.", |
| 1013 | "AI Assistant": "ИИ-ассистент", | 1012 | "AI Assistant": "ИИ-ассистент", |
| 1014 | "prompt_manager_position": "Точка инжекта", | 1013 | "prompt_manager_position": "Точка инжекта", |
| 1015 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Как рассчитывать позицию для инжекта. Она может располагаться по отношению к другим промптам (относительная) либо по отношению к чату (абсолютная).", | 1014 | "Next to other prompts (relative) or in-chat (absolute).": "Она может располагаться по отношению к другим промптам (относительная) либо по отношению к чату (абсолютная).", |
| 1016 | "prompt_manager_relative": "Относительная", | 1015 | "prompt_manager_relative": "Относительная", |
| 1017 | "prompt_manager_depth": "Глубина", | 1016 | "prompt_manager_depth": "Глубина", |
| 1018 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Глубина вставки. 0 = после последнего сообщения, 1 = перед последним сообщением, и т.д.", | 1017 | "0 = after the last message, 1 = before the last message, etc.": "0 = после последнего сообщения, 1 = перед последним сообщением, и т.д.", |
| 1019 | "The prompt to be sent.": "Отправляемый ИИ промпт.", | 1018 | "The prompt to be sent.": "Текст промпта.", |
| 1020 | "prompt_manager_forbid_overrides": "Запретить перезапись", | 1019 | "prompt_manager_forbid_overrides": "Запретить перезапись", |
| 1021 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Карточка персонажа не сможет перезаписать этот промпт, даже если настройки отдают приоритет именно ей.", | 1020 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Карточка персонажа не сможет перезаписать этот промпт, даже если настройки отдают приоритет именно ей.", |
| 1022 | "image_inlining_hint_1": "Отправлять картинки как часть промпта, если позволяет модель (такой функционал поддерживают GPT-4V, Claude 3 или Llava 13B). Чтобы добавить в чат изображение, используйте на нужном сообщении действие", | 1021 | "image_inlining_hint_1": "Отправлять картинки как часть промпта, если позволяет модель. Чтобы добавить в чат изображение, используйте на нужном сообщении действие", |
| 1023 | "image_inlining_hint_2": ". Также это можно сделать через меню", | 1022 | "image_inlining_hint_2": ". Также это можно сделать через меню", |
| 1024 | "image_inlining_hint_3": ".", | 1023 | "image_inlining_hint_3": ".", |
| 1025 | "Contest Winners": "Победители конкурса", | 1024 | "Contest Winners": "Победители конкурса", |
| @@ -1232,11 +1231,10 @@ | |||
| 1232 | "Top P & Min P": "Top P & Min P", | 1231 | "Top P & Min P": "Top P & Min P", |
| 1233 | "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.": "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.", | 1232 | "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.": "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.", |
| 1234 | "Helps the model to associate messages with characters.": "Помогает модели связывать сообщения с персонажами.", | 1233 | "Helps the model to associate messages with characters.": "Помогает модели связывать сообщения с персонажами.", |
| 1235 | "character_names_default": "Except for groups and past personas. Otherwise, make sure you provide names in the prompt.", | 1234 | "character_names_default": "Добавлять префиксы для групповых чатов и предыдущих персон. В остальных случаях указывайте имена в промпте иными способами.", |
| 1236 | "Completion": "Completion Object", | 1235 | "Completion": "Completion Object", |
| 1237 | "character_names_completion": "Только латинские буквы, цифры и знак подчёркивания. Работает не для всех бэкендов, в частности для Claude, MistralAI, Google.", | 1236 | "character_names_completion": "Только латинские буквы, цифры и знак подчёркивания. Работает не для всех бэкендов, в частности для Claude, MistralAI, Google.", |
| 1238 | "Use AI21 Tokenizer": "Использовать токенайзер AI21", | 1237 | "Use AI21 Tokenizer": "Использовать токенайзер AI21", |
| 1239 | "Use system prompt": "Использовать системный промпт", | ||
| 1240 | "(Gemini 1.5 Pro/Flash only)": "(только Gemini 1.5 Pro/Flash)", | 1238 | "(Gemini 1.5 Pro/Flash only)": "(только Gemini 1.5 Pro/Flash)", |
| 1241 | "Merges_all_system_messages_desc_1": "Объединяет все системные сообщения до первого не-системного, и отсылает их в поле", | 1239 | "Merges_all_system_messages_desc_1": "Объединяет все системные сообщения до первого не-системного, и отсылает их в поле", |
| 1242 | "Merges_all_system_messages_desc_2": ".", | 1240 | "Merges_all_system_messages_desc_2": ".", |
| @@ -1257,7 +1255,6 @@ | |||
| 1257 | "Peek a password": "Посмотреть пароль", | 1255 | "Peek a password": "Посмотреть пароль", |
| 1258 | "Clear your cookie": "Clear your cookie", | 1256 | "Clear your cookie": "Clear your cookie", |
| 1259 | "Add Chat Start and Example Separator to a list of stopping strings.": "Использовать Начало чата и Разделитель примеров сообщений в качестве стоп-строк.", | 1257 | "Add Chat Start and Example Separator to a list of stopping strings.": "Использовать Начало чата и Разделитель примеров сообщений в качестве стоп-строк.", |
| 1260 | "context_allow_jailbreak": "Если в карточке есть джейлбрейк И ПРИ ЭТОМ включена опция \"Приоритет джейлбрейку из карточки персонажа\", то этот джейлбрейк добавляется в конец промпта.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.", | ||
| 1261 | "Context Order": "Context Order", | 1258 | "Context Order": "Context Order", |
| 1262 | "Summary": "Summary", | 1259 | "Summary": "Summary", |
| 1263 | "Example Dialogues": "Примеры диалогов", | 1260 | "Example Dialogues": "Примеры диалогов", |
| @@ -1278,7 +1275,7 @@ | |||
| 1278 | "Will be inserted as a last prompt line when using system/neutral generation.": "Will be inserted as a last prompt line when using system/neutral generation.", | 1275 | "Will be inserted as a last prompt line when using system/neutral generation.": "Will be inserted as a last prompt line when using system/neutral generation.", |
| 1279 | "If a stop sequence is generated, everything past it will be removed from the output (inclusive).": "Если ИИ генерирует стоп-строку, то всё после неё будет вырезано из ответа (включая и саму стоп-строку).", | 1276 | "If a stop sequence is generated, everything past it will be removed from the output (inclusive).": "Если ИИ генерирует стоп-строку, то всё после неё будет вырезано из ответа (включая и саму стоп-строку).", |
| 1280 | "Will be inserted at the start of the chat history if it doesn't start with a User message.": "Вставляется в начале истории чата, если она начинается не с сообщения пользователя.", | 1277 | "Will be inserted at the start of the chat history if it doesn't start with a User message.": "Вставляется в начале истории чата, если она начинается не с сообщения пользователя.", |
| 1281 | "Global World Info/Lorebook activation settings": "Настройки активации глобального лорбука / Информации о мире", | 1278 | "Global World Info/Lorebook activation settings": "Глобальные настройки активации лорбука / Информации о мире", |
| 1282 | "Click to expand": "Щёлкните, чтобы развернуть", | 1279 | "Click to expand": "Щёлкните, чтобы развернуть", |
| 1283 | "Insertion Strategy": "Как инжектить", | 1280 | "Insertion Strategy": "Как инжектить", |
| 1284 | "Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "Only the entries with the most number of key matches will be selected for Inclusion Group filtering", | 1281 | "Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "Only the entries with the most number of key matches will be selected for Inclusion Group filtering", |
| @@ -1621,7 +1618,7 @@ | |||
| 1621 | "Using a proxy that you're not running yourself is a risk to your data privacy.": "Помните, что используя чужую прокси, вы подвергаете риску конфиденциальность своих данных.", | 1618 | "Using a proxy that you're not running yourself is a risk to your data privacy.": "Помните, что используя чужую прокси, вы подвергаете риску конфиденциальность своих данных.", |
| 1622 | "ANY support requests will be REFUSED if you are using a proxy.": "НЕ РАССЧИТЫВАЙТЕ на нашу поддержку, если используете прокси.", | 1619 | "ANY support requests will be REFUSED if you are using a proxy.": "НЕ РАССЧИТЫВАЙТЕ на нашу поддержку, если используете прокси.", |
| 1623 | "Do not proceed if you do not agree to this!": "Не продолжайте, если не согласны с этими условиями!", | 1620 | "Do not proceed if you do not agree to this!": "Не продолжайте, если не согласны с этими условиями!", |
| 1624 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "Как рассчитывать позицию, на которую вставляется данный промпт. Относительно других промтов в менеджере, либо на опред. глубину в чате.", | 1621 | "Relative (to other prompts in prompt manager) or In-chat @ Depth.": "Относительно других промтов в менеджере, либо на опред. глубину в чате.", |
| 1625 | "prompt_manager_in_chat": "На глубине в чате", | 1622 | "prompt_manager_in_chat": "На глубине в чате", |
| 1626 | "01.AI API Key": "Ключ от API 01.AI", | 1623 | "01.AI API Key": "Ключ от API 01.AI", |
| 1627 | "01.AI Model": "Модель 01.AI", | 1624 | "01.AI Model": "Модель 01.AI", |
| @@ -1647,10 +1644,9 @@ | |||
| 1647 | "mui_reset": "Сброс", | 1644 | "mui_reset": "Сброс", |
| 1648 | "Quick 'Impersonate' button": "Быстрое перевоплощение", | 1645 | "Quick 'Impersonate' button": "Быстрое перевоплощение", |
| 1649 | "Show a button in the input area to ask the AI to impersonate your character for a single message": "Показать в поле ввода кнопку, по нажатии на которую ИИ сгенерирует одно сообщение от лица вашего персонажа.", | 1646 | "Show a button in the input area to ask the AI to impersonate your character for a single message": "Показать в поле ввода кнопку, по нажатии на которую ИИ сгенерирует одно сообщение от лица вашего персонажа.", |
| 1650 | "Separators as Stop Strings": "Разделители как стоп-строки", | 1647 | "Separators as Stop Strings": "Разделители в качестве стоп-строк", |
| 1651 | "Names as Stop Strings": "Имена как стоп-строки", | 1648 | "Names as Stop Strings": "Имена в качестве стоп-строк", |
| 1652 | "Add Character and User names to a list of stopping strings.": "Добавлять имена персонажа и пользователя в список стоп-строк.", | 1649 | "Add Character and User names to a list of stopping strings.": "Добавлять имена персонажа и пользователя в список стоп-строк.", |
| 1653 | "Allow Post-History Instructions": "Разрешить инструкции после истории", | ||
| 1654 | "context_allow_post_history_instructions": "Добавлять в конец промпта инструкции после истории. Работает только при наличии таких инструкций в карточке И при включенной опции ''Приоритет инструкциям из карточек''.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.", | 1650 | "context_allow_post_history_instructions": "Добавлять в конец промпта инструкции после истории. Работает только при наличии таких инструкций в карточке И при включенной опции ''Приоритет инструкциям из карточек''.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.", |
| 1655 | "First User Prefix": "Первый префикс пользователя", | 1651 | "First User Prefix": "Первый префикс пользователя", |
| 1656 | "Inserted before the first User's message.": "Вставляется перед первым сообщением пользователя.", | 1652 | "Inserted before the first User's message.": "Вставляется перед первым сообщением пользователя.", |
| @@ -1916,8 +1912,8 @@ | |||
| 1916 | "Cannot restore GUI preset": "Пресет для Gui восстановить нельзя", | 1912 | "Cannot restore GUI preset": "Пресет для Gui восстановить нельзя", |
| 1917 | "Default preset cannot be restored": "Невозможно восстановить пресет по умолчанию", | 1913 | "Default preset cannot be restored": "Невозможно восстановить пресет по умолчанию", |
| 1918 | "Default template cannot be restored": "Невозможно восстановить шаблон по умолчанию", | 1914 | "Default template cannot be restored": "Невозможно восстановить шаблон по умолчанию", |
| 1919 | "Resetting a <b>default preset</b> will restore the default settings": "Сброс <b>стандартного пресета</b> восстановит настройки по умолчанию.", | 1915 | "Resetting a <b>default preset</b> will restore the default settings.": "Сброс <b>комплектного пресета</b> восстановит настройки по умолчанию.", |
| 1920 | "Resetting a <b>default template</b> will restore the default settings.": "Сброс <b>стандартного шаблона</b> восстановит настройки по умолчанию.", | 1916 | "Resetting a <b>default template</b> will restore the default settings.": "Сброс <b>комплектного шаблона</b> восстановит настройки по умолчанию.", |
| 1921 | "Are you sure?": "Вы уверены?", | 1917 | "Are you sure?": "Вы уверены?", |
| 1922 | "Default preset restored": "Стандартный пресет восстановлен", | 1918 | "Default preset restored": "Стандартный пресет восстановлен", |
| 1923 | "Default template restored": "Стандартный шаблон восстановлен", | 1919 | "Default template restored": "Стандартный шаблон восстановлен", |
| @@ -2048,11 +2044,11 @@ | |||
| 2048 | "prompt_post_processing_merge": "Объединять идущие подряд сообщения с одной ролью", | 2044 | "prompt_post_processing_merge": "Объединять идущие подряд сообщения с одной ролью", |
| 2049 | "prompt_post_processing_semi": "Semi-strict (чередовать роли)", | 2045 | "prompt_post_processing_semi": "Semi-strict (чередовать роли)", |
| 2050 | "prompt_post_processing_strict": "Strict (чередовать роли, сначала пользователь)", | 2046 | "prompt_post_processing_strict": "Strict (чередовать роли, сначала пользователь)", |
| 2051 | "Select Horde models": "Выбрать модель из Horde", | 2047 | "Select Horde models": "Выберите модель из Horde", |
| 2052 | "Model ID (optional)": "Идентификатор модели (необязательно)", | 2048 | "Model ID (optional)": "Идентификатор модели (необязательно)", |
| 2053 | "Derive context size from backend": "Использовать бэкенд для определения размера контекста", | 2049 | "Derive context size from backend": "Использовать бэкенд для определения размера контекста", |
| 2054 | "Rename current preset": "Переименовать пресет", | 2050 | "Rename current preset": "Переименовать пресет", |
| 2055 | "No Worlds active. Click here to select.": "Нет активных миров. Нажмите, чтобы выбрать.", | 2051 | "No Worlds active. Click here to select.": "Активных миров нет, ЛКМ для выбора.", |
| 2056 | "Title/Memo": "Название", | 2052 | "Title/Memo": "Название", |
| 2057 | "Strategy": "Статус", | 2053 | "Strategy": "Статус", |
| 2058 | "Position": "Позиция", | 2054 | "Position": "Позиция", |
| @@ -2171,7 +2167,7 @@ | |||
| 2171 | "instruct_derived": "Считывать из метаданных модели (по возможности)", | 2167 | "instruct_derived": "Считывать из метаданных модели (по возможности)", |
| 2172 | "Confirm token parsing with": "Чтобы убедиться в правильности выделения токенов, используйте", | 2168 | "Confirm token parsing with": "Чтобы убедиться в правильности выделения токенов, используйте", |
| 2173 | "Reasoning Effort": "Рассуждения", | 2169 | "Reasoning Effort": "Рассуждения", |
| 2174 | "Constrains effort on reasoning for reasoning models.": "Регулирует объём внутренних рассуждений модели (reasoning), для моделей которые поддерживают эту возможность.\nНа данный момент поддерживаются три значения: Подробные, Обычные, Поверхностные.\nПри менее подробном рассуждении ответ получается быстрее, а также экономятся токены, уходящие на рассуждения.", | 2170 | "Constrains effort on reasoning for reasoning models.": "Регулирует объём внутренних рассуждений модели (reasoning), для моделей, которые поддерживают эту возможность.\nПри менее подробном рассуждении ответ получается быстрее, а также экономятся токены, уходящие на рассуждения.", |
| 2175 | "openai_reasoning_effort_low": "Поверхностные", | 2171 | "openai_reasoning_effort_low": "Поверхностные", |
| 2176 | "openai_reasoning_effort_medium": "Обычные", | 2172 | "openai_reasoning_effort_medium": "Обычные", |
| 2177 | "openai_reasoning_effort_high": "Подробные", | 2173 | "openai_reasoning_effort_high": "Подробные", |
| @@ -2257,6 +2253,7 @@ | |||
| 2257 | "Manual": "Когда вы скажете", | 2253 | "Manual": "Когда вы скажете", |
| 2258 | "Auto Mode delay": "Задержка авто-режима", | 2254 | "Auto Mode delay": "Задержка авто-режима", |
| 2259 | "Use tag as folder": "Тег-папка", | 2255 | "Use tag as folder": "Тег-папка", |
| 2256 | "Hide on character card": "Скрыть на карточке персонажа", | ||
| 2260 | "All connections to ${0} have been removed.": "Все связи с персонажем ${0} были удалены.", | 2257 | "All connections to ${0} have been removed.": "Все связи с персонажем ${0} были удалены.", |
| 2261 | "Personas Unlocked": "Персоны отвязаны", | 2258 | "Personas Unlocked": "Персоны отвязаны", |
| 2262 | "Remove All Connections": "Удалить все связи", | 2259 | "Remove All Connections": "Удалить все связи", |
| @@ -2276,8 +2273,8 @@ | |||
| 2276 | "Persona Name Not Set": "У персоны отсутствует имя", | 2273 | "Persona Name Not Set": "У персоны отсутствует имя", |
| 2277 | "You must bind a name to this persona before you can set a lorebook.": "Перед привязкой лорбука персоне необходимо присвоить имя.", | 2274 | "You must bind a name to this persona before you can set a lorebook.": "Перед привязкой лорбука персоне необходимо присвоить имя.", |
| 2278 | "Default Persona Removed": "Персона по умолчанию снята", | 2275 | "Default Persona Removed": "Персона по умолчанию снята", |
| 2279 | "Persona is locked to the current character": "Персона закреплена за этим персонажем", | 2276 | "Persona is locked to the current character": "Персона закреплена за текущим персонажем", |
| 2280 | "Persona is locked to the current chat": "Персона закреплена за этим чатом", | 2277 | "Persona is locked to the current chat": "Персона закреплена за текущим чатом", |
| 2281 | "characters": "перс.", | 2278 | "characters": "перс.", |
| 2282 | "character": "персонаж", | 2279 | "character": "персонаж", |
| 2283 | "in this group": "в группе", | 2280 | "in this group": "в группе", |
| @@ -2338,5 +2335,88 @@ | |||
| 2338 | "Reasoning already exists.": "Рассуждения уже присутствуют.", | 2335 | "Reasoning already exists.": "Рассуждения уже присутствуют.", |
| 2339 | "Edit Message": "Редактирование", | 2336 | "Edit Message": "Редактирование", |
| 2340 | "Status check bypassed": "Проверка статуса отключена", | 2337 | "Status check bypassed": "Проверка статуса отключена", |
| 2341 | "Valid": "Работает" | 2338 | "Valid": "Работает", |
| 2339 | "Use Group Scoring": "Использовать Group Scoring", | ||
| 2340 | "Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "До групповых фильтров будут допущены только записи с наибольшим кол-вом совпадений", | ||
| 2341 | "Can be used to automatically activate Quick Replies": "Используется для автоматической активации быстрых ответов (Quick Replies)", | ||
| 2342 | "( None )": "(Отсутствует)", | ||
| 2343 | "Tie this entry to specific characters or characters with specific tags": "Привязать запись к опред. персонажам или персонажам с заданными тегами", | ||
| 2344 | "Move Entry to Another Lorebook": "Переместить запись в другой лорбук", | ||
| 2345 | "There are no other lorebooks to move to.": "Некуда перемещать: не найдено других лорбуков.", | ||
| 2346 | "Select Target Lorebook": "Выберите куда переместить", | ||
| 2347 | "Move '${0}' to:": "Переместить '${0}' в:", | ||
| 2348 | "Please select a target lorebook.": "Выберите лорбук, в который будет перемещена запись.", | ||
| 2349 | "Scan depth cannot be negative": "Глубина сканирования не может быть отрицательной", | ||
| 2350 | "Scan depth cannot exceed ${0}": "Глубина сканирования не может превышать ${0}", | ||
| 2351 | "Select your current Reasoning Template": "Выберите текущий Шаблон рассуждений", | ||
| 2352 | "Delete template": "Удалить шаблон", | ||
| 2353 | "Reasoning Template": "Шаблон рассуждений", | ||
| 2354 | "openai_reasoning_effort_auto": "Авто", | ||
| 2355 | "openai_reasoning_effort_minimum": "Минимальные", | ||
| 2356 | "openai_reasoning_effort_maximum": "Максимальные", | ||
| 2357 | "OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level.": "OpenAI принимает следующее: low (Поверхностные), medium (Обычные), high (Подробные). Minimum (Минимальные) - то же самое, что low. Maximum (Максимальные) - то же самое, что high. При выборе Auto (Авто) значение не отсылается вообще.", | ||
| 2358 | "Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent.": "Резервирует часть ответа для рассуждений (Поверхностные: 10% ответа, Обычные: 25%, Подробные: 50%). Остальные значения зависят от конкретной модели.", | ||
| 2359 | "xAI Model": "Модель xAI", | ||
| 2360 | "xAI API Key": "Ключ от API xAI", | ||
| 2361 | "HuggingFace Token": "Токен HuggingFace", | ||
| 2362 | "Endpoint URL": "Адрес эндпоинта", | ||
| 2363 | "Example: https://****.endpoints.huggingface.cloud": "Пример: https://****.endpoints.huggingface.cloud", | ||
| 2364 | "Featherless Model Selection": "Выбор модели из Featherless", | ||
| 2365 | "category": "категория", | ||
| 2366 | "Top": "Топовые", | ||
| 2367 | "All Classes": "Все классы", | ||
| 2368 | "Date Asc": "Дата, возрастание", | ||
| 2369 | "Date Desc": "Дата, убывание", | ||
| 2370 | "Background Image": "Фоновое изображение", | ||
| 2371 | "Delete the background?": "Удалить фон?", | ||
| 2372 | "Tags_as_Folders_desc": "Чтобы тег отображался как папка, его нужно отметить таковым в меню управления тегами. Нажмите сюда, чтобы открыть его.", | ||
| 2373 | "tag_entries": "раз исп.", | ||
| 2374 | "Multiple personas are connected to this character.\nSelect a persona to use for this chat.": "К этому персонажу привязано несколько персон.\nВыберите персону, которую хотите использовать в этом чате.", | ||
| 2375 | "Select Persona": "Выберите персону", | ||
| 2376 | "Completion Object": "Как часть Completion Object", | ||
| 2377 | "Move ${0} to:": "Переместить '${0}' в:", | ||
| 2378 | "Chat Scenario Override": "Перезапись сценария чата", | ||
| 2379 | "Unique to this chat.": "Действует только в рамках текущего чата.", | ||
| 2380 | "All group members will use the following scenario text instead of what is specified in their character cards.": "Все участники группы будут использовать этот сценарий вместо того, который указан в карточке.", | ||
| 2381 | "Checkpoints inherit the scenario override from their parent, and can be changed individually after that.": "Чекпоинты наследуют сценарий родителя, после отделения его можно менять.", | ||
| 2382 | "Delete Tag": "Удалить тег", | ||
| 2383 | "Do you want to delete the tag": "Вы точно хотите удалить тег", | ||
| 2384 | "If you want to merge all references to this tag into another tag, select it below:": "Если хотите заменить ссылки на этот тег на какой-то другой, то выберите из списка:", | ||
| 2385 | "Open Folder (Show all characters even if not selected)": "Открытая папка (показать всех персонажей, включая невыбранных)", | ||
| 2386 | "Closed Folder (Hide all characters unless selected)": "Закрытая папка (скрыть всех персонажей, кроме выбранных)", | ||
| 2387 | "No Folder": "Не папка", | ||
| 2388 | "Show only favorites": "Показать только избранных персонажей", | ||
| 2389 | "Show only groups": "Показать только группы", | ||
| 2390 | "Show only folders": "Показать только папки", | ||
| 2391 | "Manage tags": "Панель управления тегами", | ||
| 2392 | "Show Tag List": "Показать список тегов", | ||
| 2393 | "Clear all filters": "Сбросить все фильтры", | ||
| 2394 | "There are no items to display.": "Отображать абсолютно нечего.", | ||
| 2395 | "Characters and groups hidden by filters or closed folders": "Персонажи и группы скрыты настройками фильтров либо закрытыми папками", | ||
| 2396 | "Otterly empty": "Всё что можно, всё выдрано", | ||
| 2397 | "Here be dragons": "Список настолько очистился, что в него вернулись драконы", | ||
| 2398 | "Kiwibunga": "Настолько пусто, что киви прилетела посидеть", | ||
| 2399 | "Pump-a-Rum": "Пу-пу-пу", | ||
| 2400 | "Croak it": "Только кваканье лягушек и стрёкот сверчков", | ||
| 2401 | "${0} character hidden.": "Персонажей скрыто: ${0}.", | ||
| 2402 | "${0} characters hidden.": "Персонажей скрыто: ${0}.", | ||
| 2403 | "/ page": "/ стр.", | ||
| 2404 | "Context Length": "Размер контекста", | ||
| 2405 | "Added On": "Добавлена", | ||
| 2406 | "Class": "Класс", | ||
| 2407 | "Bulk_edit_characters": "Массовое редактирование персонажей\n\nЛКМ, чтобы выделить либо отменить выделение персонажа\nShift+ЛКМ, чтобы массово выделить либо отменить выделение персонажей\nПКМ, чтобы выбрать действие", | ||
| 2408 | "Bulk select all characters": "Выбрать всех персонажей", | ||
| 2409 | "Duplicate": "Клонировать", | ||
| 2410 | "Next page": "След. страница", | ||
| 2411 | "Previous page": "Пред. страница", | ||
| 2412 | "Group: ${0}": "Группа: ${0}", | ||
| 2413 | "You deleted a character/chat and arrived back here for safety reasons! Pick another character!": "Вы удалили персонажа или чат, и мы из соображений безопасности перенесли вас на эту страницу! Выберите другого персонажа!", | ||
| 2414 | "Group is empty.": "Группа пуста.", | ||
| 2415 | "No characters available": "Персонажей нет", | ||
| 2416 | "Choose what to export": "Выберите, что экспортировать", | ||
| 2417 | "Text Completion Preset": "Пресет для режима Text Completion", | ||
| 2418 | "Update enabled": "Обновить включенные", | ||
| 2419 | "Could not connect to API": "Не удалось подключиться к API", | ||
| 2420 | "Connected to API": "Соединение с API установлено", | ||
| 2421 | "Go back": "Назад" | ||
| 2342 | } | 2422 | } |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Об'єднує послідовні системні повідомлення в одне (крім прикладів діалогів). Може покращити співпрацю для деяких моделей.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Об'єднує послідовні системні повідомлення в одне (крім прикладів діалогів). Може покращити співпрацю для деяких моделей.", |
| 236 | "Enable function calling": "Увімкнути виклик функцій", | 236 | "Enable function calling": "Увімкнути виклик функцій", |
| 237 | "Send inline images": "Надсилати вбудовані зображення", | 237 | "Send inline images": "Надсилати вбудовані зображення", |
| 238 | "image_inlining_hint_1": "Надсилає зображення у підказках, якщо модель це підтримує (наприклад, GPT-4V, Claude 3 або Llava 13B).\n Використовувати", | 238 | "image_inlining_hint_1": "Надсилає зображення у підказках, якщо модель це підтримує.\n Використовувати", |
| 239 | "image_inlining_hint_2": "дії з будь-яким повідомленням або", | 239 | "image_inlining_hint_2": "дії з будь-яким повідомленням або", |
| 240 | "image_inlining_hint_3": "меню, щоб прикріпити файл зображення до чату.", | 240 | "image_inlining_hint_3": "меню, щоб прикріпити файл зображення до чату.", |
| 241 | "Inline Image Quality": "Якість вбудованого зображення", | 241 | "Inline Image Quality": "Якість вбудованого зображення", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Асистент автозаповнення", | 253 | "Assistant Prefill": "Асистент автозаповнення", |
| 254 | "Start Claude's answer with...": "Почати відповідь Клода з...", | 254 | "Start Claude's answer with...": "Почати відповідь Клода з...", |
| 255 | "Assistant Impersonation Prefill": "Попереднє заповнення уособлення помічника", | 255 | "Assistant Impersonation Prefill": "Попереднє заповнення уособлення помічника", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Використовувати системний промпт (тільки Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Надсилати системний промпт для підтримуваних моделей. Якщо відключено, повідомлення користувача додається в початок промпта.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Надсилати системний промпт для підтримуваних моделей. Якщо відключено, повідомлення користувача додається в початок промпта.", |
| 258 | "User first message": "Перше повідомлення користувача", | 257 | "User first message": "Перше повідомлення користувача", |
| 259 | "Restore User first message": "Відновити перше повідомлення користувача", | 258 | "Restore User first message": "Відновити перше повідомлення користувача", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Початок чату", | 410 | "Chat Start": "Початок чату", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Додайте початок чату та роздільник прикладів до списку рядків зупинки.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Додайте початок чату та роздільник прикладів до списку рядків зупинки.", |
| 413 | "Use as Stop Strings": "Використовувати як рядки зупинки", | 412 | "Use as Stop Strings": "Використовувати як рядки зупинки", |
| 414 | "context_allow_jailbreak": "Включає втечу з в’язниці в кінці підказки, якщо визначено в картці символів ТА «Переважати символ. Втечу з в'язниці'' увімкнено.\nЦЕ НЕ РЕКОМЕНДУЄТЬСЯ ДЛЯ МОДЕЛЕЙ ЗАВЕРШЕННЯ ТЕКСТУ, МОЖЕ ПРИЗВЕСТИ ДО ПОГАНОГО РЕЗУЛЬТАТУ.", | ||
| 415 | "Allow Jailbreak": "Дозволити втечу з в'язниці", | 413 | "Allow Jailbreak": "Дозволити втечу з в'язниці", |
| 416 | "Context Order": "Порядок контексту", | 414 | "Context Order": "Порядок контексту", |
| 417 | "Summary": "Резюме", | 415 | "Summary": "Резюме", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Завантажити чат як документ у форматі простого тексту", | 938 | "Download chat as plain text document": "Завантажити чат як документ у форматі простого тексту", |
| 941 | "Delete chat file": "Видалити файл чату", | 939 | "Delete chat file": "Видалити файл чату", |
| 942 | "Use tag as folder": "Позначити як папку", | 940 | "Use tag as folder": "Позначити як папку", |
| 941 | "Hide on character card": "Сховати на картці персонажа", | ||
| 943 | "Delete tag": "Видалити тег", | 942 | "Delete tag": "Видалити тег", |
| 944 | "Entry Title/Memo": "Заголовок запису", | 943 | "Entry Title/Memo": "Заголовок запису", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Статус вступу до WI:\r🔵 Постійно\r🟢 Нормально\r🔗 Векторизовано\r❌ Вимкнено", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Статус вступу до WI:\r🔵 Постійно\r🟢 Нормально\r🔗 Векторизовано\r❌ Вимкнено", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "Кому буде віднесено це повідомлення.", | 1009 | "To whom this message will be attributed.": "Кому буде віднесено це повідомлення.", |
| 1011 | "AI Assistant": "ШІ помічник", | 1010 | "AI Assistant": "ШІ помічник", |
| 1012 | "prompt_manager_position": "Позиція", | 1011 | "prompt_manager_position": "Позиція", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Позиція ін'єкції. Поруч з іншими підказками (відносні) або в чаті (абсолютні).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Поруч з іншими підказками (відносні) або в чаті (абсолютні).", |
| 1014 | "prompt_manager_relative": "Відносна", | 1013 | "prompt_manager_relative": "Відносна", |
| 1015 | "prompt_manager_depth": "Глибина", | 1014 | "prompt_manager_depth": "Глибина", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Глибина ін'єкції. 0 = після останнього повідомлення, 1 = перед останнім повідомленням тощо.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = після останнього повідомлення, 1 = перед останнім повідомленням тощо.", |
| 1017 | "Prompt": "Запит", | 1016 | "Prompt": "Запит", |
| 1018 | "The prompt to be sent.": "Підказка для надсилання.", | 1017 | "The prompt to be sent.": "Підказка для надсилання.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Це підказка не може бути перевизначено картками символів, навіть якщо перевизначення є кращим.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Це підказка не може бути перевизначено картками символів, навіть якщо перевизначення є кращим.", |
| @@ -235,7 +235,7 @@ | |||
| 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Kết hợp các tin nhắn hệ thống liên tiếp thành một (loại bỏ các đoạn hội thoại mẫu). Có thể cải thiện tính nhất quán cho một số model.", | 235 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Kết hợp các tin nhắn hệ thống liên tiếp thành một (loại bỏ các đoạn hội thoại mẫu). Có thể cải thiện tính nhất quán cho một số model.", |
| 236 | "Enable function calling": "Sử dụng tính năng gọi hàm (function calling)", | 236 | "Enable function calling": "Sử dụng tính năng gọi hàm (function calling)", |
| 237 | "Send inline images": "Gửi hình ảnh nội bộ", | 237 | "Send inline images": "Gửi hình ảnh nội bộ", |
| 238 | "image_inlining_hint_1": "Gửi hình ảnh theo Prompt nếu kiểu máy hỗ trợ (ví dụ: GPT-4V, Claude 3 hoặc Llava 13B).\n Sử dụng", | 238 | "image_inlining_hint_1": "Gửi hình ảnh theo Prompt nếu kiểu máy hỗ trợ.\n Sử dụng", |
| 239 | "image_inlining_hint_2": "hành động đối với bất kỳ tin nhắn nào hoặc", | 239 | "image_inlining_hint_2": "hành động đối với bất kỳ tin nhắn nào hoặc", |
| 240 | "image_inlining_hint_3": "menu để đính kèm tệp hình ảnh vào cuộc trò chuyện.", | 240 | "image_inlining_hint_3": "menu để đính kèm tệp hình ảnh vào cuộc trò chuyện.", |
| 241 | "Inline Image Quality": "Chất lượng hình ảnh nội tuyến", | 241 | "Inline Image Quality": "Chất lượng hình ảnh nội tuyến", |
| @@ -253,7 +253,6 @@ | |||
| 253 | "Assistant Prefill": "Prefill trợ lý", | 253 | "Assistant Prefill": "Prefill trợ lý", |
| 254 | "Start Claude's answer with...": "Claude trả lời bắt đầu bằng...", | 254 | "Start Claude's answer with...": "Claude trả lời bắt đầu bằng...", |
| 255 | "Assistant Impersonation Prefill": "Prefill cho mạo danh trợ lý", | 255 | "Assistant Impersonation Prefill": "Prefill cho mạo danh trợ lý", |
| 256 | "Use system prompt (Claude 2.1+ only)": "Sử dụng prompt hệ thống (Chỉ áp dụng từ Claude 2.1+)", | ||
| 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Gửi yêu cầu hệ thống cho các model được hỗ trợ. Nếu bị vô hiệu hóa, tin nhắn của người dùng sẽ được thêm vào đầu yêu cầu.", | 256 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Gửi yêu cầu hệ thống cho các model được hỗ trợ. Nếu bị vô hiệu hóa, tin nhắn của người dùng sẽ được thêm vào đầu yêu cầu.", |
| 258 | "User first message": "Tin nhắn đầu tiên của người dùng", | 257 | "User first message": "Tin nhắn đầu tiên của người dùng", |
| 259 | "Restore User first message": "Khôi phục tin nhắn đầu tiên của người dùng", | 258 | "Restore User first message": "Khôi phục tin nhắn đầu tiên của người dùng", |
| @@ -411,7 +410,6 @@ | |||
| 411 | "Chat Start": "Bắt đầu Chat", | 410 | "Chat Start": "Bắt đầu Chat", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "Thêm Bắt đầu trò chuyện và Dấu phân cách ví dụ vào danh sách các chuỗi dừng.", | 411 | "Add Chat Start and Example Separator to a list of stopping strings.": "Thêm Bắt đầu trò chuyện và Dấu phân cách ví dụ vào danh sách các chuỗi dừng.", |
| 413 | "Use as Stop Strings": "Sử dụng như chuỗi dừng", | 412 | "Use as Stop Strings": "Sử dụng như chuỗi dừng", |
| 414 | "context_allow_jailbreak": "Bao gồm Bẻ khóa ở cuối Prompt, nếu được xác định trong thẻ ký tự VÀ ''Thích Char. Bẻ khóa'' được bật.\nĐIỀU NÀY KHÔNG ĐƯỢC KHUYẾN NGHỊ CHO CÁC MÔ HÌNH HOÀN THÀNH VĂN BẢN, CÓ THỂ DẪN ĐẾN ĐẦU RA XẤU.", | ||
| 415 | "Allow Jailbreak": "Cho phép bẻ khóa", | 413 | "Allow Jailbreak": "Cho phép bẻ khóa", |
| 416 | "Context Order": "Thứ tự bối cảnh", | 414 | "Context Order": "Thứ tự bối cảnh", |
| 417 | "Summary": "Bản tóm tắt", | 415 | "Summary": "Bản tóm tắt", |
| @@ -940,6 +938,7 @@ | |||
| 940 | "Download chat as plain text document": "Tải xuống cuộc trò chuyện dưới dạng tài liệu văn bản đơn giản", | 938 | "Download chat as plain text document": "Tải xuống cuộc trò chuyện dưới dạng tài liệu văn bản đơn giản", |
| 941 | "Delete chat file": "Xóa tệp trò chuyện", | 939 | "Delete chat file": "Xóa tệp trò chuyện", |
| 942 | "Use tag as folder": "Gắn thẻ dưới dạng thư mục", | 940 | "Use tag as folder": "Gắn thẻ dưới dạng thư mục", |
| 941 | "Hide on character card": "Ẩn trên thẻ nhân vật", | ||
| 943 | "Delete tag": "Xóa tag", | 942 | "Delete tag": "Xóa tag", |
| 944 | "Entry Title/Memo": "Tiêu đề Đăng nhập/Ghi chú", | 943 | "Entry Title/Memo": "Tiêu đề Đăng nhập/Ghi chú", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Trạng thái nhập WI:\r🔵 Hằng số\r🟢 Bình thường\r🔗 Được vector hóa\r❌ Bị vô hiệu hóa", | 944 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "Trạng thái nhập WI:\r🔵 Hằng số\r🟢 Bình thường\r🔗 Được vector hóa\r❌ Bị vô hiệu hóa", |
| @@ -1010,10 +1009,10 @@ | |||
| 1010 | "To whom this message will be attributed.": "Tin nhắn này sẽ được quy cho ai.", | 1009 | "To whom this message will be attributed.": "Tin nhắn này sẽ được quy cho ai.", |
| 1011 | "AI Assistant": "Trợ lý AI", | 1010 | "AI Assistant": "Trợ lý AI", |
| 1012 | "prompt_manager_position": "Chức vụ", | 1011 | "prompt_manager_position": "Chức vụ", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Vị trí tiêm. Bên cạnh các Prompt khác (tương đối) hoặc trong trò chuyện (tuyệt đối).", | 1012 | "Next to other prompts (relative) or in-chat (absolute).": "Bên cạnh các Prompt khác (tương đối) hoặc trong trò chuyện (tuyệt đối).", |
| 1014 | "prompt_manager_relative": "Liên quan đến", | 1013 | "prompt_manager_relative": "Liên quan đến", |
| 1015 | "prompt_manager_depth": "Chiều sâu", | 1014 | "prompt_manager_depth": "Chiều sâu", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Độ sâu phun. 0 = sau tin nhắn cuối cùng, 1 = trước tin nhắn cuối cùng, v.v.", | 1015 | "0 = after the last message, 1 = before the last message, etc.": "0 = sau tin nhắn cuối cùng, 1 = trước tin nhắn cuối cùng, v.v.", |
| 1017 | "Prompt": "Prompt", | 1016 | "Prompt": "Prompt", |
| 1018 | "The prompt to be sent.": "Lời nhắc được gửi đi.", | 1017 | "The prompt to be sent.": "Lời nhắc được gửi đi.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Lời nhắc này không thể bị ghi đè bằng thẻ ký tự, ngay cả khi ưu tiên ghi đè.", | 1018 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Lời nhắc này không thể bị ghi đè bằng thẻ ký tự, ngay cả khi ưu tiên ghi đè.", |
| @@ -259,7 +259,7 @@ | |||
| 259 | "enable_functions_desc_2": "功能工具", | 259 | "enable_functions_desc_2": "功能工具", |
| 260 | "enable_functions_desc_3": "可以被各种扩展利用来提供附加功能。", | 260 | "enable_functions_desc_3": "可以被各种扩展利用来提供附加功能。", |
| 261 | "Send inline images": "发送图片", | 261 | "Send inline images": "发送图片", |
| 262 | "image_inlining_hint_1": "如果模型支持,就可以在提示词中发送图片(例如 GPT-4V、Claude 3 或 Llava 13B)。\n发送消息时,点击", | 262 | "image_inlining_hint_1": "如果模型支持,就可以在提示词中发送图片。\n发送消息时,点击", |
| 263 | "image_inlining_hint_2": "在这里(", | 263 | "image_inlining_hint_2": "在这里(", |
| 264 | "image_inlining_hint_3": ")将图片添加到消息中。", | 264 | "image_inlining_hint_3": ")将图片添加到消息中。", |
| 265 | "Inline Image Quality": "图片画质", | 265 | "Inline Image Quality": "图片画质", |
| @@ -280,7 +280,6 @@ | |||
| 280 | "Expand the editor": "展开编辑器", | 280 | "Expand the editor": "展开编辑器", |
| 281 | "Start Claude's answer with...": "以如下内容开始Claude的回答...", | 281 | "Start Claude's answer with...": "以如下内容开始Claude的回答...", |
| 282 | "Assistant Impersonation Prefill": "AI帮答预填", | 282 | "Assistant Impersonation Prefill": "AI帮答预填", |
| 283 | "Use system prompt (Claude 2.1+ only)": "使用系统提示词(仅适用于Claude 2.1+)", | ||
| 284 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "为支持的模型发送系统提示词。如果禁用,则用户消息将添加到提示词的开头。", | 283 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "为支持的模型发送系统提示词。如果禁用,则用户消息将添加到提示词的开头。", |
| 285 | "Confirm token parsing with": "确认使用以下工具进行词符解析", | 284 | "Confirm token parsing with": "确认使用以下工具进行词符解析", |
| 286 | "Tokenizer": "词符化器", | 285 | "Tokenizer": "词符化器", |
| @@ -504,7 +503,6 @@ | |||
| 504 | "Add Character and User names to a list of stopping strings.": "将角色和用户名添加到停止字符串列表中。", | 503 | "Add Character and User names to a list of stopping strings.": "将角色和用户名添加到停止字符串列表中。", |
| 505 | "Names as Stop Strings": "名称作为终止字符串", | 504 | "Names as Stop Strings": "名称作为终止字符串", |
| 506 | "context_allow_post_history_instructions": "如果在角色卡中定义并且启用了“首选角色卡说明”,则在提示末尾包含后历史说明。\n不建议在文本补全模型中使用此功能,否则会导致输出错误。", | 505 | "context_allow_post_history_instructions": "如果在角色卡中定义并且启用了“首选角色卡说明”,则在提示末尾包含后历史说明。\n不建议在文本补全模型中使用此功能,否则会导致输出错误。", |
| 507 | "Allow Post-History Instructions": "允许后历史说明", | ||
| 508 | "Instruct Template": "指导模板", | 506 | "Instruct Template": "指导模板", |
| 509 | "instruct_derived": "如果可能,从模型元数据中获取", | 507 | "instruct_derived": "如果可能,从模型元数据中获取", |
| 510 | "instruct_bind_to_context": "如果启用,上下文模板将根据所选的指导模板名称或偏好自动选择。", | 508 | "instruct_bind_to_context": "如果启用,上下文模板将根据所选的指导模板名称或偏好自动选择。", |
| @@ -1083,6 +1081,7 @@ | |||
| 1083 | "Delete chat file": "删除聊天文件", | 1081 | "Delete chat file": "删除聊天文件", |
| 1084 | "Drag to reorder tag": "拖动以排序", | 1082 | "Drag to reorder tag": "拖动以排序", |
| 1085 | "Use tag as folder": "标记为文件夹", | 1083 | "Use tag as folder": "标记为文件夹", |
| 1084 | "Hide on character card": "在角色卡上隐藏", | ||
| 1086 | "Delete tag": "删除标签", | 1085 | "Delete tag": "删除标签", |
| 1087 | "Toggle entry's active state.": "切换条目激活状态。", | 1086 | "Toggle entry's active state.": "切换条目激活状态。", |
| 1088 | "Entry Title/Memo": "条目标题/备忘录", | 1087 | "Entry Title/Memo": "条目标题/备忘录", |
| @@ -1169,11 +1168,11 @@ | |||
| 1169 | "To whom this message will be attributed.": "此消息应归于谁。", | 1168 | "To whom this message will be attributed.": "此消息应归于谁。", |
| 1170 | "AI Assistant": "AI助手", | 1169 | "AI Assistant": "AI助手", |
| 1171 | "prompt_manager_position": "位置", | 1170 | "prompt_manager_position": "位置", |
| 1172 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "注入位置。相对(相对于提示管理器中的其他提示)或在聊天中@深度。", | 1171 | "Relative (to other prompts in prompt manager) or In-chat @ Depth.": "相对(相对于提示管理器中的其他提示)或在聊天中@深度。", |
| 1173 | "prompt_manager_relative": "相对", | 1172 | "prompt_manager_relative": "相对", |
| 1174 | "prompt_manager_in_chat": "聊天中", | 1173 | "prompt_manager_in_chat": "聊天中", |
| 1175 | "prompt_manager_depth": "深度", | 1174 | "prompt_manager_depth": "深度", |
| 1176 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "注入深度。“0”为在最后一条消息之后,“1”为在最后一条消息之前,等等。", | 1175 | "0 = after the last message, 1 = before the last message, etc.": "“0”为在最后一条消息之后,“1”为在最后一条消息之前,等等。", |
| 1177 | "The content of this prompt is pulled from elsewhere and cannot be edited here.": "此提示词的内容是从其他地方提取的,无法在此处进行编辑。", | 1176 | "The content of this prompt is pulled from elsewhere and cannot be edited here.": "此提示词的内容是从其他地方提取的,无法在此处进行编辑。", |
| 1178 | "Prompt": "提示词", | 1177 | "Prompt": "提示词", |
| 1179 | "The prompt to be sent.": "要发送的提示词。", | 1178 | "The prompt to be sent.": "要发送的提示词。", |
| @@ -1358,7 +1357,7 @@ | |||
| 1358 | "Image Captioning": "图像描述", | 1357 | "Image Captioning": "图像描述", |
| 1359 | "Source": "来源", | 1358 | "Source": "来源", |
| 1360 | "Local": "本地", | 1359 | "Local": "本地", |
| 1361 | "Multimodal (OpenAI / Anthropic / llama / Google)": "多模式(OpenAI / Anthropic / llama / Google)", | 1360 | "Multimodal (OpenAI / Anthropic / llama / Google)": "多模态(OpenAI / Anthropic / llama / Google)", |
| 1362 | "Extras": "更多", | 1361 | "Extras": "更多", |
| 1363 | "Horde": "Horde", | 1362 | "Horde": "Horde", |
| 1364 | "API": "API", | 1363 | "API": "API", |
| @@ -1588,8 +1587,8 @@ | |||
| 1588 | "sd_function_tool_txt": "Use function tool", | 1587 | "sd_function_tool_txt": "Use function tool", |
| 1589 | "sd_interactive_mode": "发送消息时自动生成图像,例如“给我发一张猫的照片”。", | 1588 | "sd_interactive_mode": "发送消息时自动生成图像,例如“给我发一张猫的照片”。", |
| 1590 | "sd_interactive_mode_txt": "交互模式", | 1589 | "sd_interactive_mode_txt": "交互模式", |
| 1591 | "sd_multimodal_captioning": "使用多模式字幕根据用户和角色的头像生成提示词。", | 1590 | "sd_multimodal_captioning": "使用多模态字幕根据用户和角色的头像生成提示词。", |
| 1592 | "sd_multimodal_captioning_txt": "使用多模式字幕来描绘肖像", | 1591 | "sd_multimodal_captioning_txt": "使用多模态字幕来描绘肖像", |
| 1593 | "sd_free_extend": "使用当前选择的 LLM 自动扩展自由模式主题提示(不是肖像或背景)。", | 1592 | "sd_free_extend": "使用当前选择的 LLM 自动扩展自由模式主题提示(不是肖像或背景)。", |
| 1594 | "sd_free_extend_txt": "延长自由模式提示", | 1593 | "sd_free_extend_txt": "延长自由模式提示", |
| 1595 | "sd_free_extend_small": "(交互/命令)", | 1594 | "sd_free_extend_small": "(交互/命令)", |
| @@ -2109,5 +2108,25 @@ | |||
| 2109 | "Title/Memo": "标题(备忘)", | 2108 | "Title/Memo": "标题(备忘)", |
| 2110 | "Strategy": "触发策略", | 2109 | "Strategy": "触发策略", |
| 2111 | "Position": "插入位置", | 2110 | "Position": "插入位置", |
| 2112 | "Trigger %": "触发概率%" | 2111 | "Trigger %": "触发概率%", |
| 2112 | "Generate Caption": "生成图片描述", | ||
| 2113 | "(DEPRECATED)": "(已弃用)", | ||
| 2114 | "[Currently loaded]": "[当前加载]", | ||
| 2115 | "Change Persona Image": "更改角色图片", | ||
| 2116 | "Delete Persona": "删除角色", | ||
| 2117 | "Duplicate Persona": "复制角色", | ||
| 2118 | "Enter a name for this persona:": "输入角色名", | ||
| 2119 | "Enable web search": "启用联网搜索", | ||
| 2120 | "Current Persona": "当前角色", | ||
| 2121 | "Global Settings": "全局设置", | ||
| 2122 | "Select a model": "选择模型", | ||
| 2123 | "Thinking...": "思考中", | ||
| 2124 | "Valid": "有效", | ||
| 2125 | "Rename Persona": "重命名角色", | ||
| 2126 | "Sort By: Name (Z-A)": "排序: 名称(Z-A)", | ||
| 2127 | "Sort By: Name (A-Z)": "排序: 名称(A-Z)", | ||
| 2128 | "Sort By: Date (Oldest First)": "排序: 日期(从最远到最新)", | ||
| 2129 | "Sort By: Date (Newest First)": "排序: 日期(从最新到最远)", | ||
| 2130 | "Set the reasoning block of a message. Returns the reasoning block content.": "设置消息的推理块。返回推理块内容。", | ||
| 2131 | "Select providers. No selection = all providers.": "选择服务商。未选择 = 所有服务商。" | ||
| 2113 | } | 2132 | } |
| @@ -236,7 +236,7 @@ | |||
| 236 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "將連續的系統訊息合併為一個(不包括對話範例)。可能會提高某些模型的一致性。", | 236 | "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "將連續的系統訊息合併為一個(不包括對話範例)。可能會提高某些模型的一致性。", |
| 237 | "Enable function calling": "啟用函式呼叫", | 237 | "Enable function calling": "啟用函式呼叫", |
| 238 | "Send inline images": "傳送內嵌圖片", | 238 | "Send inline images": "傳送內嵌圖片", |
| 239 | "image_inlining_hint_1": "如果模型支援(例如:GPT-4V、Claude 3 或 Llava 13B),則在提示詞中傳送圖片。\n使用任何訊息上的", | 239 | "image_inlining_hint_1": "如果模型支援,則在提示詞中傳送圖片。\n使用任何訊息上的", |
| 240 | "image_inlining_hint_2": "動作或", | 240 | "image_inlining_hint_2": "動作或", |
| 241 | "image_inlining_hint_3": "選單來附加圖片文件到聊天中。", | 241 | "image_inlining_hint_3": "選單來附加圖片文件到聊天中。", |
| 242 | "Inline Image Quality": "內嵌圖片品質", | 242 | "Inline Image Quality": "內嵌圖片品質", |
| @@ -254,7 +254,6 @@ | |||
| 254 | "Assistant Prefill": "預先填充助理訊息", | 254 | "Assistant Prefill": "預先填充助理訊息", |
| 255 | "Start Claude's answer with...": "開始 Claude 的回答⋯", | 255 | "Start Claude's answer with...": "開始 Claude 的回答⋯", |
| 256 | "Assistant Impersonation Prefill": "助理扮演時的預先填充", | 256 | "Assistant Impersonation Prefill": "助理扮演時的預先填充", |
| 257 | "Use system prompt (Claude 2.1+ only)": "使用系統提示詞(僅限 Claude 2.1+)", | ||
| 258 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "為支援的模型傳送系統提示詞。停用時,使用者訊息將新增到提示詞的開頭。", | 257 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "為支援的模型傳送系統提示詞。停用時,使用者訊息將新增到提示詞的開頭。", |
| 259 | "User first message": "使用者第一則訊息", | 258 | "User first message": "使用者第一則訊息", |
| 260 | "Restore User first message": "還原使用者第一則訊息", | 259 | "Restore User first message": "還原使用者第一則訊息", |
| @@ -399,7 +398,7 @@ | |||
| 399 | "Applies additional processing to the prompt before sending it to the API.": "這個選項會在將提示詞送往 API 之前,對它進行額外的處理。", | 398 | "Applies additional processing to the prompt before sending it to the API.": "這個選項會在將提示詞送往 API 之前,對它進行額外的處理。", |
| 400 | "Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "透過傳送簡短的測試訊息來驗證您的 API 連線。請注意,您將因此獲得榮譽!", | 399 | "Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "透過傳送簡短的測試訊息來驗證您的 API 連線。請注意,您將因此獲得榮譽!", |
| 401 | "Test Message": "測試訊息", | 400 | "Test Message": "測試訊息", |
| 402 | "Auto-connect to Last Server": "自動連接至上次使用的伺服器", | 401 | "Auto-connect to Last Server": "自動連線至上次使用的伺服器", |
| 403 | "Missing key": "❌ 鑰匙遺失", | 402 | "Missing key": "❌ 鑰匙遺失", |
| 404 | "Key saved": "✔️ 金鑰已儲存", | 403 | "Key saved": "✔️ 金鑰已儲存", |
| 405 | "View hidden API keys": "檢視隱藏的 API 金鑰", | 404 | "View hidden API keys": "檢視隱藏的 API 金鑰", |
| @@ -412,7 +411,6 @@ | |||
| 412 | "Chat Start": "聊天開始符號", | 411 | "Chat Start": "聊天開始符號", |
| 413 | "Add Chat Start and Example Separator to a list of stopping strings.": "將聊天開始和範例分隔符號加入終止字串中。", | 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "將聊天開始和範例分隔符號加入終止字串中。", |
| 414 | "Use as Stop Strings": "用作停止字串", | 413 | "Use as Stop Strings": "用作停止字串", |
| 415 | "context_allow_jailbreak": "如果在角色卡中定義了越獄,且啟用了「角色卡越獄優先」,則會在提示詞的結尾加入越獄內容。\n這不建議用於文字完成模型,因為可能導致不良的輸出結果。", | ||
| 416 | "Allow Jailbreak": "允許越獄", | 414 | "Allow Jailbreak": "允許越獄", |
| 417 | "Context Order": "上下文順序", | 415 | "Context Order": "上下文順序", |
| 418 | "Summary": "摘要", | 416 | "Summary": "摘要", |
| @@ -771,7 +769,7 @@ | |||
| 771 | "Name": "名稱", | 769 | "Name": "名稱", |
| 772 | "Enter your name": "輸入您的名字", | 770 | "Enter your name": "輸入您的名字", |
| 773 | "Click to set a new User Name": "設定新的使用者名稱", | 771 | "Click to set a new User Name": "設定新的使用者名稱", |
| 774 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "綁定目前所選的使用者角色至本次聊天。再次點選則可移除綁定。", | 772 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "鎖定目前所選的使用者角色至本次聊天。再次點選將移除鎖定。", |
| 775 | "Click to set user name for all messages": "設定所有訊息的使用者名稱", | 773 | "Click to set user name for all messages": "設定所有訊息的使用者名稱", |
| 776 | "Persona Description": "使用者角色描述", | 774 | "Persona Description": "使用者角色描述", |
| 777 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "範例:[{{user}} 是一個 28 歲的羅馬尼亞貓娘。]", | 775 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "範例:[{{user}} 是一個 28 歲的羅馬尼亞貓娘。]", |
| @@ -941,6 +939,7 @@ | |||
| 941 | "Delete chat file": "刪除聊天檔案", | 939 | "Delete chat file": "刪除聊天檔案", |
| 942 | "Drag to reorder tag": "拖動以重新排序標籤", | 940 | "Drag to reorder tag": "拖動以重新排序標籤", |
| 943 | "Use tag as folder": "將標籤作為資料夾", | 941 | "Use tag as folder": "將標籤作為資料夾", |
| 942 | "Hide on character card": "在角色卡上隱藏標籤", | ||
| 944 | "Delete tag": "刪除標籤", | 943 | "Delete tag": "刪除標籤", |
| 945 | "Entry Title/Memo": "條目標題/備註", | 944 | "Entry Title/Memo": "條目標題/備註", |
| 946 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "世界資訊條目狀態:🔵常數 🟢正常 🔗向量 ❌停用", | 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "世界資訊條目狀態:🔵常數 🟢正常 🔗向量 ❌停用", |
| @@ -963,8 +962,8 @@ | |||
| 963 | "Order": "順序", | 962 | "Order": "順序", |
| 964 | "Trigger %:": "觸發%:", | 963 | "Trigger %:": "觸發%:", |
| 965 | "Probability": "機率", | 964 | "Probability": "機率", |
| 966 | "Duplicate world info entry": "複製世界資訊物件", | 965 | "Duplicate world info entry": "複製世界資訊條目", |
| 967 | "Delete world info entry": "刪除世界資訊物件", | 966 | "Delete world info entry": "刪除世界資訊條目", |
| 968 | "Comma separated (required)": "逗號分隔(必填)", | 967 | "Comma separated (required)": "逗號分隔(必填)", |
| 969 | "Primary Keywords": "主要關鍵字", | 968 | "Primary Keywords": "主要關鍵字", |
| 970 | "Keywords or Regexes": "關鍵字或正規表示式", | 969 | "Keywords or Regexes": "關鍵字或正規表示式", |
| @@ -1011,10 +1010,10 @@ | |||
| 1011 | "To whom this message will be attributed.": "此訊息所屬的角色。", | 1010 | "To whom this message will be attributed.": "此訊息所屬的角色。", |
| 1012 | "AI Assistant": "人工智慧助手", | 1011 | "AI Assistant": "人工智慧助手", |
| 1013 | "prompt_manager_position": "位置", | 1012 | "prompt_manager_position": "位置", |
| 1014 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "注入位置。與其他提示詞相鄰(相對位置)或在聊天中(絕對位置)。", | 1013 | "Next to other prompts (relative) or in-chat (absolute).": "與其他提示詞相鄰(相對位置)或在聊天中(絕對位置)。", |
| 1015 | "prompt_manager_relative": "相對位置", | 1014 | "prompt_manager_relative": "相對位置", |
| 1016 | "prompt_manager_depth": "深度", | 1015 | "prompt_manager_depth": "深度", |
| 1017 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "注入深度。0 = 在最後一則訊息之後,1 = 在最後一則訊息之前,以此類推。", | 1016 | "0 = after the last message, 1 = before the last message, etc.": "0 = 在最後一則訊息之後,1 = 在最後一則訊息之前,以此類推。", |
| 1018 | "Prompt": "提示詞", | 1017 | "Prompt": "提示詞", |
| 1019 | "The prompt to be sent.": "要傳送的提示詞。", | 1018 | "The prompt to be sent.": "要傳送的提示詞。", |
| 1020 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "即使啟用優先覆寫,此提示詞也不能被角色卡片覆寫。", | 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "即使啟用優先覆寫,此提示詞也不能被角色卡片覆寫。", |
| @@ -1049,7 +1048,7 @@ | |||
| 1049 | "welcome_message_part_4": "在聊天輸入框內輸入", | 1048 | "welcome_message_part_4": "在聊天輸入框內輸入", |
| 1050 | "welcome_message_part_5": "來顯示巨集或命令列表。", | 1049 | "welcome_message_part_5": "來顯示巨集或命令列表。", |
| 1051 | "welcome_message_part_6": "加入", | 1050 | "welcome_message_part_6": "加入", |
| 1052 | "Discord server": "不和諧伺服器", | 1051 | "Discord server": "Discord 伺服器", |
| 1053 | "welcome_message_part_7": "取得公告和資訊。", | 1052 | "welcome_message_part_7": "取得公告和資訊。", |
| 1054 | "SillyTavern is aimed at advanced users.": "SillyTavern 專為進階使用者設計", | 1053 | "SillyTavern is aimed at advanced users.": "SillyTavern 專為進階使用者設計", |
| 1055 | "If you're new to this, enable the simplified UI mode below.": "如果您是新手,請啟用下方的簡易 UI 模式", | 1054 | "If you're new to this, enable the simplified UI mode below.": "如果您是新手,請啟用下方的簡易 UI 模式", |
| @@ -1247,7 +1246,7 @@ | |||
| 1247 | "ext_regex_replace_string_placeholder": "使用 {{match}} 來包含來自尋找正規表示式的匹配文字或 $1、$2 等捕獲組。", | 1246 | "ext_regex_replace_string_placeholder": "使用 {{match}} 來包含來自尋找正規表示式的匹配文字或 $1、$2 等捕獲組。", |
| 1248 | "Trim Out": "修剪掉", | 1247 | "Trim Out": "修剪掉", |
| 1249 | "ext_regex_trim_placeholder": "在取代之前,全域修剪正規表示式匹配中的任何不需要的部分。每個元素用輸入鍵分隔。", | 1248 | "ext_regex_trim_placeholder": "在取代之前,全域修剪正規表示式匹配中的任何不需要的部分。每個元素用輸入鍵分隔。", |
| 1250 | "ext_regex_affects": "影響物件", | 1249 | "ext_regex_affects": "影響條目", |
| 1251 | "ext_regex_user_input": "使用者輸入", | 1250 | "ext_regex_user_input": "使用者輸入", |
| 1252 | "ext_regex_ai_output": "AI 輸出", | 1251 | "ext_regex_ai_output": "AI 輸出", |
| 1253 | "Slash Commands": "斜線命令", | 1252 | "Slash Commands": "斜線命令", |
| @@ -1555,7 +1554,6 @@ | |||
| 1555 | "All": "全部", | 1554 | "All": "全部", |
| 1556 | "Allow fallback models": "允許回退模型", | 1555 | "Allow fallback models": "允許回退模型", |
| 1557 | "Allow fallback providers": "允許回退供應商", | 1556 | "Allow fallback providers": "允許回退供應商", |
| 1558 | "Allow Post-History Instructions": "允許聊天歷史後指示", | ||
| 1559 | "Allow reverse proxy": "允許反向代理", | 1557 | "Allow reverse proxy": "允許反向代理", |
| 1560 | "Alternate Greeting #": "備選問候語 #", | 1558 | "Alternate Greeting #": "備選問候語 #", |
| 1561 | "alternate_greetings_hint_1": "點選", | 1559 | "alternate_greetings_hint_1": "點選", |
| @@ -1652,7 +1650,7 @@ | |||
| 1652 | "Image Captioning": "圖片註解", | 1650 | "Image Captioning": "圖片註解", |
| 1653 | "Generate Caption": "產生圖片註解", | 1651 | "Generate Caption": "產生圖片註解", |
| 1654 | "Injection Position": "插入位置", | 1652 | "Injection Position": "插入位置", |
| 1655 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "插入位置(與提示詞管理器中的其他提示相比)或聊天中的深度位置。", | 1653 | "Relative (to other prompts in prompt manager) or In-chat @ Depth.": "插入位置(與提示詞管理器中的其他提示相比)或聊天中的深度位置。", |
| 1656 | "Injection Template": "插入範本", | 1654 | "Injection Template": "插入範本", |
| 1657 | "Insert#": "插入#", | 1655 | "Insert#": "插入#", |
| 1658 | "Instruct Sequences": "指令序列", | 1656 | "Instruct Sequences": "指令序列", |
| @@ -2270,8 +2268,8 @@ | |||
| 2270 | "(Leave empty to auto-generate)": "(留空將自動命名)", | 2268 | "(Leave empty to auto-generate)": "(留空將自動命名)", |
| 2271 | "The currently existing checkpoint will be unlinked and replaced with the new checkpoint, but can still be found in the Chat Management.": "此檢查點將取消連結並替換為新的檢查點,但仍可在「管理聊天檔案」中找到。", | 2269 | "The currently existing checkpoint will be unlinked and replaced with the new checkpoint, but can still be found in the Chat Management.": "此檢查點將取消連結並替換為新的檢查點,但仍可在「管理聊天檔案」中找到。", |
| 2272 | "Enter the Git URL of the extension to install": "輸入欲安裝的擴充功能 Git URL", | 2270 | "Enter the Git URL of the extension to install": "輸入欲安裝的擴充功能 Git URL", |
| 2273 | "Disclaimer:": "免責宣告:", | 2271 | "Disclaimer:": "免責聲明:", |
| 2274 | "Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.": "請注意,使用外部擴充功能可能會導致意想不到的副作用並存在安全風險。在匯入前,請務必確保您信任其來源。我們對於第三方擴充功能所引起的任何損害概不負責。", | 2272 | "Please be aware that using external extensions can have unintended side effects and may pose security risks. Always make sure you trust the source before importing an extension. We are not responsible for any damage caused by third-party extensions.": "請注意,使用外部擴充功能可能會導致意想不到的副作用並存在安全風險。匯入前,請務必確保您信任其來源。我們對於第三方擴充功能所引起的任何損害概不負責。", |
| 2275 | "Prompt Itemization": "提示詞項目化", | 2273 | "Prompt Itemization": "提示詞項目化", |
| 2276 | "API/Model": "API/模型", | 2274 | "API/Model": "API/模型", |
| 2277 | "Preset": "預設設定檔", | 2275 | "Preset": "預設設定檔", |
| @@ -2321,11 +2319,11 @@ | |||
| 2321 | "Only Show Last Message in Chat (Requires Prome to be enabled).": "僅顯示聊天中的最後一條訊息(需啟用 Prome)。", | 2319 | "Only Show Last Message in Chat (Requires Prome to be enabled).": "僅顯示聊天中的最後一條訊息(需啟用 Prome)。", |
| 2322 | "Emulates the character card of a character to be a sprite. (Requires Prome to be enabled).": "將角色的角色卡圖片模擬為角色立繪(需啟用 Prome)。", | 2320 | "Emulates the character card of a character to be a sprite. (Requires Prome to be enabled).": "將角色的角色卡圖片模擬為角色立繪(需啟用 Prome)。", |
| 2323 | "Shakes the character sprite when the character is speaking (Only works if Streaming is enabled in Preset Settings).": "當角色說話時,震動角色的立繪(僅在預設設定檔中啟用「串流」時有效)。", | 2321 | "Shakes the character sprite when the character is speaking (Only works if Streaming is enabled in Preset Settings).": "當角色說話時,震動角色的立繪(僅在預設設定檔中啟用「串流」時有效)。", |
| 2324 | "Focuses the current speaking character in chat. (Requires Prome to be enabled).": "聚焦聊天中目前正在說話的角色(要啟用 Prome)。", | 2322 | "Focuses the current speaking character in chat. (Requires Prome to be enabled).": "聚焦聊天中目前正在說話的角色(需啟用 Prome)。", |
| 2325 | "Darkens non-speaking (unfocused) characters. (Requires Prome to be enabled).": "使未說話(未聚焦)的角色變暗(需啟用 Prome)。", | 2323 | "Darkens non-speaking (unfocused) characters. (Requires Prome to be enabled).": "使未說話(未聚焦)的角色變暗(需啟用 Prome)。", |
| 2326 | "Auto-hides characters from the screen that haven't been in the conversation for a while up to X characters. (Requires Prome to be enabled).": "自動隱藏未參與會話一段時間的角色,最多 X 個角色(需啟用 Prome)。", | 2324 | "Auto-hides characters from the screen that haven't been in the conversation for a while up to X characters. (Requires Prome to be enabled).": "自動隱藏未參與會話一段時間的角色,最多 X 個角色(需啟用 Prome)。", |
| 2327 | "Enables the ability to use a user sprite for your persona.": "啟用後,將為使用者的角色使用角色立繪功能。", | 2325 | "Enables the ability to use a user sprite for your persona.": "啟用後,將為使用者的角色使用角色立繪功能。", |
| 2328 | "Applies the world tint to character sprites (Requires Prome to be enabled. This will override your character tint settings).": "將世界色調應用於角色立繪(需啟用 Prome,這將覆蓋角色的色調設定)。", | 2326 | "Applies the world tint to character sprites (Requires Prome to be enabled. This will override your character tint settings).": "將世界色調應用於角色立繪(需啟用 Prome,這將覆蓋角色色調設定)。", |
| 2329 | "Tints the world background.": "為世界背景新增色調。", | 2327 | "Tints the world background.": "為世界背景新增色調。", |
| 2330 | "Tints the character sprites.": "為角色立繪新增色調(需啟用 Prome)。", | 2328 | "Tints the character sprites.": "為角色立繪新增色調(需啟用 Prome)。", |
| 2331 | "Auto-Hide Sprites": "自動隱藏立繪", | 2329 | "Auto-Hide Sprites": "自動隱藏立繪", |
| @@ -2608,7 +2606,7 @@ | |||
| 2608 | "Revert all settings to default (not the default profile, just the default that comes with the extension). Your other profiles won't be affected.": "將所有設定恢復為預設值(並非恢復至「預設設定檔」,而是擴充功能隨附的原始預設值)。其他設定檔將不受影響。", | 2606 | "Revert all settings to default (not the default profile, just the default that comes with the extension). Your other profiles won't be affected.": "將所有設定恢復為預設值(並非恢復至「預設設定檔」,而是擴充功能隨附的原始預設值)。其他設定檔將不受影響。", |
| 2609 | "Limit the number of messages to send in regular prompts to this number (-1 for no limit). Message memories will still be sent.": "限制常規提示中傳送的訊息數量至此數值(-1 表示無限制)。訊息記憶仍將一併傳送。", | 2607 | "Limit the number of messages to send in regular prompts to this number (-1 for no limit). Message memories will still be sent.": "限制常規提示中傳送的訊息數量至此數值(-1 表示無限制)。訊息記憶仍將一併傳送。", |
| 2610 | "Whether memory is enabled by default for new chats.": "是否在新對話中預設啟用記憶。", | 2608 | "Whether memory is enabled by default for new chats.": "是否在新對話中預設啟用記憶。", |
| 2611 | "Summarize Chat": "摘要對話", | 2609 | "Summarize Chat": "聊天摘要", |
| 2612 | "Choose settings for the chat summarization. All message inclusion/exclusion settings from the main config profile are used, in addition to the following options.": "選擇聊天摘要的設定。摘要時將使用主要設定檔中的所有訊息包含/排除規則,並可額外設定以下選項。", | 2610 | "Choose settings for the chat summarization. All message inclusion/exclusion settings from the main config profile are used, in addition to the following options.": "選擇聊天摘要的設定。摘要時將使用主要設定檔中的所有訊息包含/排除規則,並可額外設定以下選項。", |
| 2613 | "Currently preparing to summarize:": "目前正在準備摘要:", | 2611 | "Currently preparing to summarize:": "目前正在準備摘要:", |
| 2614 | "Summarize messages with no existing summary": "摘要尚無摘要的訊息", | 2612 | "Summarize messages with no existing summary": "摘要尚無摘要的訊息", |
| @@ -2619,9 +2617,130 @@ | |||
| 2619 | "Type the folder name of the theme you want to apply.": "輸入您想套用的主題資料夾名稱。", | 2617 | "Type the folder name of the theme you want to apply.": "輸入您想套用的主題資料夾名稱。", |
| 2620 | "Place your theme data in a folder.": "請將主題資料存於該資料夾內。", | 2618 | "Place your theme data in a folder.": "請將主題資料存於該資料夾內。", |
| 2621 | "Unsure where to start? Type ": "不確定如何開始?輸入:", | 2619 | "Unsure where to start? Type ": "不確定如何開始?輸入:", |
| 2622 | " to apply the default Google Messages theme or click ": " 即可使用預設主題 Google Messages,或點擊", | 2620 | " to apply the default Google Messages theme or click ": " 即可使用預設主題 Google Messages,或點選", |
| 2623 | "here": "這裡", | 2621 | "here": "這裡", |
| 2624 | " to learn how to create your own theme.": " 以學習如何創建個人化主題。", | 2622 | " to learn how to create your own theme.": " 以了解如何創建個人化主題。", |
| 2625 | "Guinevere (UI Theme Extension)": "Guinevere(進階自定義 UI 主題)", | 2623 | "Guinevere (UI Theme Extension)": "Guinevere(進階自定義 UI 主題)", |
| 2626 | "and Guinaifen.": "和 Guinaifen(桂乃芬)呈獻。" | 2624 | "and Guinaifen.": "和 Guinaifen(桂乃芬)呈獻。", |
| 2625 | "(Requires Prome to be enabled)": "(需啟用 Prome)", | ||
| 2626 | "[ None ]": "[無]", | ||
| 2627 | "Group is empty.": "群組為空。", | ||
| 2628 | "No characters available": "無可用角色", | ||
| 2629 | "Adds a shadow to the character sprite.": "為角色立繪新增陰影。", | ||
| 2630 | "Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%). Other options are model-dependent.": "分配部分回應長度用於推理功能(低:10%、中:25%、高:50%)。其他選項依模型而異。", | ||
| 2631 | "Attach a file or image to a current chat.": "附加檔案或圖片至目前的聊天。", | ||
| 2632 | "Change Persona Image": "變更使用者角色頭像", | ||
| 2633 | "Click to lock your selected persona to the current character. Click again to remove the lock.": "點選以將所選使用者角色鎖定目前聊天的角色。再次點選以解除鎖定。", | ||
| 2634 | "Click to select this as default persona for the new chats. Click again to remove it.": "點選以將此設為新聊天的預設使用者角色,再次點選可取消設定。", | ||
| 2635 | "Connected Personas": "已連結的使用者角色", | ||
| 2636 | "Create a new prompt": "新增新提示詞", | ||
| 2637 | "Delete a prompt": "刪除提示詞", | ||
| 2638 | "Delete Persona": "刪除使用者角色", | ||
| 2639 | "Duplicate Persona": "複製使用者角色", | ||
| 2640 | "Expand and zoom": "展開並縮放", | ||
| 2641 | "Move Entry to Another Lorebook": "將條目移動到其他知識書", | ||
| 2642 | "Persona is locked to the current character": "使用者角色已鎖定至目前角色", | ||
| 2643 | "Persona is locked to the current chat": "使用者角色已鎖定至目前聊天", | ||
| 2644 | "Rename a prompt": "重新命名提示詞", | ||
| 2645 | "Rename Persona": "重新命名使用者角色", | ||
| 2646 | "Select your current Reasoning Template": "選擇你目前使用的推理範本", | ||
| 2647 | "Toggles sprite scaling for character sprites.": "切換角色立繪的縮放比例", | ||
| 2648 | "When multiple personas are connected to a character, a popup will appear to select which one to use.": "當多個使用者角色連接至一個角色時,將顯示選擇彈窗。", | ||
| 2649 | "When using LLM or WebLLM classifier, only show and use expressions that have sprites assigned to them.": "使用 LLM 或 WebLLM 分類器時,僅顯示並使用已指派的表情立繪。", | ||
| 2650 | "Whenever a persona is selected, it will be locked and automatically selected when the chat is opened.": "若已選擇使用者角色,將在開啟聊天時自動進行鎖定。", | ||
| 2651 | "Additional Matching Sources": "額外匹配來源", | ||
| 2652 | "All Classes": "所有類別", | ||
| 2653 | "Allow multiple persona connections per character": "允許每個角色連接多個使用者角色", | ||
| 2654 | "Allows the model to return image attachments.": "允許模型返回圖片附件。", | ||
| 2655 | "Auto-Hide Sprite Settings": "自動隱藏立繪設定", | ||
| 2656 | "Auto-lock a chosen persona to the chat": "自動鎖定使用者角色至聊天中", | ||
| 2657 | "Character": "角色", | ||
| 2658 | "Character Personality": "角色個性", | ||
| 2659 | "Character Tint/Share World Tint With Characters requires Prome to be enabled.": "角色著色/與角色共享世界著色功能需啟用 Prome。", | ||
| 2660 | "Chat": "聊天", | ||
| 2661 | "Click_space": "點選", | ||
| 2662 | "Connections": "連接", | ||
| 2663 | "Context": "上下文", | ||
| 2664 | "Current Persona": "目前使用者角色", | ||
| 2665 | "Date Asc": "日期升序", | ||
| 2666 | "Date Desc": "日期降序", | ||
| 2667 | "Enable Sprite Scale": "啟用立繪縮放", | ||
| 2668 | "Enable web search": "啟用網路搜尋", | ||
| 2669 | "Filter expressions for available sprites": "篩選可用的立繪表情", | ||
| 2670 | "Focus Settings": "焦點設定", | ||
| 2671 | "General Sprite Settings": "通用立繪設定", | ||
| 2672 | "Global Settings": "全域設定", | ||
| 2673 | "Go back": "返回", | ||
| 2674 | "Hide Sheld": "隱藏聊天欄位(#Sheld)", | ||
| 2675 | "in this group": "在此群組中", | ||
| 2676 | "Letterbox Configuration (Requires Prome to be enabled)": "信箱設定(需啟用 Prome)", | ||
| 2677 | "openai_reasoning_effort_auto": "自動", | ||
| 2678 | "openai_reasoning_effort_maximum": "最大", | ||
| 2679 | "openai_reasoning_effort_minimum": "最小", | ||
| 2680 | "openrouter_web_search_fee": "需付費。每次提示詞將額外收取 0.02 美元費用。", | ||
| 2681 | "Pooled order": "合併順序", | ||
| 2682 | "Request inline images": "請求內嵌圖片", | ||
| 2683 | "Request inline images_desc_2": "與以下功能不相容:函數調用、網路搜尋、系統提示詞。", | ||
| 2684 | "Response": "回應", | ||
| 2685 | "Secondary Embedding endpoint URL": "次要嵌入端點 URL", | ||
| 2686 | "Set the size scale of the character sprites.": "設定角色立繪的大小比例。", | ||
| 2687 | "Sprite Scale": "立繪縮放", | ||
| 2688 | "Sprite Shadow Settings": "立繪陰影設定", | ||
| 2689 | "tag_entries": "條目", | ||
| 2690 | "Use search capabilities provided by the backend.": "使用後端提供的搜尋功能。", | ||
| 2691 | "Use secondary URL": "使用次要 URL", | ||
| 2692 | "User Sprite Settings": "[測試版] 使用者立繪設定", | ||
| 2693 | "xAI API Key": "xAI API 密鑰", | ||
| 2694 | "xAI Model": "xAI 模型", | ||
| 2695 | "關閉": "關閉", | ||
| 2696 | "Reset custom sampler selection": "重設自定取樣器選擇", | ||
| 2697 | "Here you can toggle the display of individual samplers. (WIP)": "可在此切換各取樣器的顯示狀態(開發中)", | ||
| 2698 | "Tie this entry to specific characters or characters with specific tags": "將此項綁定至特定角色或標籤", | ||
| 2699 | "There are no other lorebooks to move to.": "暫無其他知識書可供移動。", | ||
| 2700 | "Select Target Lorebook": "選擇目標知識書", | ||
| 2701 | "Move '${0}' to:": "將「${0}」移動至:", | ||
| 2702 | "Please select a target lorebook.": "請選擇目標知識書。", | ||
| 2703 | "Scan depth cannot be negative": "掃描深度不能為負值", | ||
| 2704 | "Scan depth cannot exceed ${0}": "掃描深度不能超過 ${0}", | ||
| 2705 | "Reasoning Template": "推理範本", | ||
| 2706 | "OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level.": "OpenAI 支援程度:低、中、高。Minimum 與 Maximum 分別等同於低與高。選擇 Auto(自動)不會傳送努力等級。", | ||
| 2707 | "Branch or tag name (optional)": "分支/標籤名稱(可留空)", | ||
| 2708 | "Update enabled": "僅更新啟用項目", | ||
| 2709 | "Sort: Loading Order": "排序:載入順序", | ||
| 2710 | "Sort: Display Name": "排序:顯示名稱", | ||
| 2711 | "Multiple personas are connected to this character.\nSelect a persona to use for this chat.": "此角色已綁定多個使用者角色,請選擇用於本次對話的角色。", | ||
| 2712 | "Select Persona": "選擇使用者角色", | ||
| 2713 | "Move ${0} to:": "將 ${0} 移至:", | ||
| 2714 | "Delete Tag": "刪除標籤", | ||
| 2715 | "Do you want to delete the tag": "確定要刪除此標籤嗎?", | ||
| 2716 | "If you want to merge all references to this tag into another tag, select it below:": "若想將所有引用合併至其他標籤,請於下方選擇目標標籤:", | ||
| 2717 | "Open Folder (Show all characters even if not selected)": "開啟資料夾(顯示所有角色,即使未被選取)", | ||
| 2718 | "Closed Folder (Hide all characters unless selected)": "關閉資料夾(僅顯示選取的角色)", | ||
| 2719 | "No Folder": "無資料夾", | ||
| 2720 | "Show only favorites": "僅顯示最愛角色", | ||
| 2721 | "Show only groups": "僅顯示群組", | ||
| 2722 | "Show only folders": "僅顯示資料夾", | ||
| 2723 | "Manage tags": "標籤管理", | ||
| 2724 | "Show Tag List": "顯示標籤列表", | ||
| 2725 | "Clear all filters": "清除所有篩選器", | ||
| 2726 | "There are no items to display.": "暫無可顯示的項目。", | ||
| 2727 | "Characters and groups hidden by filters or closed folders": "部分角色與群組因篩選或關閉資料夾而未顯示", | ||
| 2728 | "Otterly empty": "萬獺俱寂", | ||
| 2729 | "Here be dragons": "此處有龍", | ||
| 2730 | "Kiwibunga": "這是鴿子嗎?", | ||
| 2731 | "Pump-a-Rum": "啪,沒了。", | ||
| 2732 | "Croak it": "PLAY 蝦咪 GAME?", | ||
| 2733 | "${0} character hidden.": "隱藏了 ${0} 名角色。", | ||
| 2734 | "${0} characters hidden.": "隱藏了 ${0} 名角色。", | ||
| 2735 | "/ page": "/頁", | ||
| 2736 | "Context Length": "上下文長度", | ||
| 2737 | "Added On": "新增日期", | ||
| 2738 | "Class": "分類", | ||
| 2739 | "Next page": "下一頁", | ||
| 2740 | "Previous page": "上一頁", | ||
| 2741 | "Group: ${0}": "群組:${0}", | ||
| 2742 | "You deleted a character/chat and arrived back here for safety reasons! Pick another character!": "角色或對話已被刪除。系統為安全考量導回此頁,請重新選擇角色。", | ||
| 2743 | "Could not connect to API": "無法連線至 API", | ||
| 2744 | "Connected to API": "已成功連線至 API", | ||
| 2745 | "help_macros_charDepthPrompt": "角色的 @ 深度註記" | ||
| 2627 | } | 2746 | } |
| @@ -50,6 +50,7 @@ import { | |||
| 50 | importWorldInfo, | 50 | importWorldInfo, |
| 51 | wi_anchor_position, | 51 | wi_anchor_position, |
| 52 | world_info_include_names, | 52 | world_info_include_names, |
| 53 | initWorldInfo, | ||
| 53 | } from './scripts/world-info.js'; | 54 | } from './scripts/world-info.js'; |
| 54 | 55 | ||
| 55 | import { | 56 | import { |
| @@ -96,6 +97,7 @@ import { | |||
| 96 | forceCharacterEditorTokenize, | 97 | forceCharacterEditorTokenize, |
| 97 | applyPowerUserSettings, | 98 | applyPowerUserSettings, |
| 98 | generatedTextFiltered, | 99 | generatedTextFiltered, |
| 100 | applyStylePins, | ||
| 99 | } from './scripts/power-user.js'; | 101 | } from './scripts/power-user.js'; |
| 100 | 102 | ||
| 101 | import { | 103 | import { |
| @@ -142,6 +144,7 @@ import { | |||
| 142 | getHordeModels, | 144 | getHordeModels, |
| 143 | adjustHordeGenerationParams, | 145 | adjustHordeGenerationParams, |
| 144 | MIN_LENGTH, | 146 | MIN_LENGTH, |
| 147 | initHorde, | ||
| 145 | } from './scripts/horde.js'; | 148 | } from './scripts/horde.js'; |
| 146 | 149 | ||
| 147 | import { | 150 | import { |
| @@ -174,10 +177,13 @@ import { | |||
| 174 | saveBase64AsFile, | 177 | saveBase64AsFile, |
| 175 | uuidv4, | 178 | uuidv4, |
| 176 | equalsIgnoreCaseAndAccents, | 179 | equalsIgnoreCaseAndAccents, |
| 180 | localizePagination, | ||
| 181 | renderPaginationDropdown, | ||
| 182 | paginationDropdownChangeHandler, | ||
| 177 | } from './scripts/utils.js'; | 183 | } from './scripts/utils.js'; |
| 178 | import { debounce_timeout, IGNORE_SYMBOL } from './scripts/constants.js'; | 184 | import { debounce_timeout, IGNORE_SYMBOL } from './scripts/constants.js'; |
| 179 | 185 | ||
| 180 | import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js'; | 186 | import { cancelDebouncedMetadataSave, doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js'; |
| 181 | import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js'; | 187 | import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js'; |
| 182 | import { | 188 | import { |
| 183 | tag_map, | 189 | tag_map, |
| @@ -245,7 +251,7 @@ import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_set | |||
| 245 | import { hideLoader, showLoader } from './scripts/loader.js'; | 251 | import { hideLoader, showLoader } from './scripts/loader.js'; |
| 246 | import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js'; | 252 | import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js'; |
| 247 | import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels, loadGenericModels } from './scripts/textgen-models.js'; | 253 | import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels, loadGenericModels } from './scripts/textgen-models.js'; |
| 248 | import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js'; | 254 | import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat, formatCreatorNotes, initChatUtilities } from './scripts/chats.js'; |
| 249 | import { getPresetManager, initPresetManager } from './scripts/preset-manager.js'; | 255 | import { getPresetManager, initPresetManager } from './scripts/preset-manager.js'; |
| 250 | import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js'; | 256 | import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js'; |
| 251 | import { currentUser, setUserControls } from './scripts/user.js'; | 257 | import { currentUser, setUserControls } from './scripts/user.js'; |
| @@ -276,6 +282,7 @@ import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js'; | |||
| 276 | import { getContext } from './scripts/st-context.js'; | 282 | import { getContext } from './scripts/st-context.js'; |
| 277 | import { extractReasoningFromData, initReasoning, parseReasoningInSwipes, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js'; | 283 | import { extractReasoningFromData, initReasoning, parseReasoningInSwipes, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js'; |
| 278 | import { accountStorage } from './scripts/util/AccountStorage.js'; | 284 | import { accountStorage } from './scripts/util/AccountStorage.js'; |
| 285 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard, getPermanentAssistantAvatar } from './scripts/welcome-screen.js'; | ||
| 279 | 286 | ||
| 280 | // API OBJECT FOR EXTERNAL WIRING | 287 | // API OBJECT FOR EXTERNAL WIRING |
| 281 | globalThis.SillyTavern = { | 288 | globalThis.SillyTavern = { |
| @@ -306,19 +313,28 @@ await new Promise((resolve) => { | |||
| 306 | } | 313 | } |
| 307 | }); | 314 | }); |
| 308 | 315 | ||
| 309 | showLoader(); | ||
| 310 | |||
| 311 | // Configure toast library: | 316 | // Configure toast library: |
| 312 | toastr.options.escapeHtml = true; // Prevent raw HTML inserts | 317 | toastr.options = { |
| 313 | toastr.options.timeOut = 4000; // How long the toast will display without user interaction | 318 | closeButton: false, |
| 314 | toastr.options.extendedTimeOut = 10000; // How long the toast will display after a user hovers over it | 319 | progressBar: false, |
| 315 | toastr.options.progressBar = true; // Visually indicate how long before a toast expires. | 320 | showDuration: 250, |
| 316 | toastr.options.closeButton = true; // enable a close button | 321 | hideDuration: 250, |
| 317 | toastr.options.positionClass = 'toast-top-center'; // Where to position the toast container | 322 | timeOut: 4000, |
| 318 | toastr.options.onHidden = () => { | 323 | extendedTimeOut: 10000, |
| 324 | showEasing: 'linear', | ||
| 325 | hideEasing: 'linear', | ||
| 326 | showMethod: 'fadeIn', | ||
| 327 | hideMethod: 'fadeOut', | ||
| 328 | escapeHtml: true, | ||
| 329 | onHidden: function () { | ||
| 319 | // If we have any dialog still open, the last "hidden" toastr will remove the toastr-container. We need to keep it alive inside the dialog though | 330 | // If we have any dialog still open, the last "hidden" toastr will remove the toastr-container. We need to keep it alive inside the dialog though |
| 320 | // so the toasts still show up inside there. | 331 | // so the toasts still show up inside there. |
| 321 | fixToastrForDialogs(); | 332 | fixToastrForDialogs(); |
| 333 | }, | ||
| 334 | onShown: function () { | ||
| 335 | // Set tooltip to the notification message | ||
| 336 | $(this).attr('title', t`Tap to close`); | ||
| 337 | }, | ||
| 322 | }; | 338 | }; |
| 323 | 339 | ||
| 324 | // Allow target="_blank" in links | 340 | // Allow target="_blank" in links |
| @@ -363,7 +379,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => { | |||
| 363 | 379 | ||
| 364 | // Replace line breaks with <br> in unknown elements | 380 | // Replace line breaks with <br> in unknown elements |
| 365 | if (node instanceof HTMLUnknownElement) { | 381 | if (node instanceof HTMLUnknownElement) { |
| 366 | node.innerHTML = node.innerHTML.replaceAll('\n', '<br>'); | 382 | node.innerHTML = node.innerHTML.trim().replaceAll('\n', '<br>'); |
| 367 | } | 383 | } |
| 368 | 384 | ||
| 369 | const isMediaAllowed = isExternalMediaAllowed(); | 385 | const isMediaAllowed = isExternalMediaAllowed(); |
| @@ -446,6 +462,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => { | |||
| 446 | }); | 462 | }); |
| 447 | 463 | ||
| 448 | // Event source init | 464 | // Event source init |
| 465 | //MARK: event_types | ||
| 449 | export const event_types = { | 466 | export const event_types = { |
| 450 | APP_READY: 'app_ready', | 467 | APP_READY: 'app_ready', |
| 451 | EXTRAS_CONNECTED: 'extras_connected', | 468 | EXTRAS_CONNECTED: 'extras_connected', |
| @@ -523,6 +540,7 @@ export const event_types = { | |||
| 523 | CONNECTION_PROFILE_UPDATED: 'connection_profile_updated', | 540 | CONNECTION_PROFILE_UPDATED: 'connection_profile_updated', |
| 524 | TOOL_CALLS_PERFORMED: 'tool_calls_performed', | 541 | TOOL_CALLS_PERFORMED: 'tool_calls_performed', |
| 525 | TOOL_CALLS_RENDERED: 'tool_calls_rendered', | 542 | TOOL_CALLS_RENDERED: 'tool_calls_rendered', |
| 543 | CHARACTER_MANAGEMENT_DROPDOWN: 'charManagementDropdown', | ||
| 526 | }; | 544 | }; |
| 527 | 545 | ||
| 528 | export const eventSource = new EventEmitter([event_types.APP_READY]); | 546 | export const eventSource = new EventEmitter([event_types.APP_READY]); |
| @@ -537,7 +555,7 @@ console.debug('Character context menu initialized', characterContextMenu); | |||
| 537 | // Markdown converter | 555 | // Markdown converter |
| 538 | export let mesForShowdownParse; //intended to be used as a context to compare showdown strings against | 556 | export let mesForShowdownParse; //intended to be used as a context to compare showdown strings against |
| 539 | /** @type {import('showdown').Converter} */ | 557 | /** @type {import('showdown').Converter} */ |
| 540 | let converter; | 558 | export let converter; |
| 541 | 559 | ||
| 542 | // array for prompt token calculations | 560 | // array for prompt token calculations |
| 543 | console.debug('initializing Prompt Itemization Array on Startup'); | 561 | console.debug('initializing Prompt Itemization Array on Startup'); |
| @@ -557,7 +575,7 @@ let chat_create_date = ''; | |||
| 557 | let firstRun = false; | 575 | let firstRun = false; |
| 558 | let settingsReady = false; | 576 | let settingsReady = false; |
| 559 | let currentVersion = '0.0.0'; | 577 | let currentVersion = '0.0.0'; |
| 560 | let displayVersion = 'SillyTavern'; | 578 | export let displayVersion = 'SillyTavern'; |
| 561 | 579 | ||
| 562 | let generatedPromptCache = ''; | 580 | let generatedPromptCache = ''; |
| 563 | let generation_started = new Date(); | 581 | let generation_started = new Date(); |
| @@ -630,6 +648,7 @@ export const system_message_types = { | |||
| 630 | MACROS: 'macros', | 648 | MACROS: 'macros', |
| 631 | WELCOME_PROMPT: 'welcome_prompt', | 649 | WELCOME_PROMPT: 'welcome_prompt', |
| 632 | ASSISTANT_NOTE: 'assistant_note', | 650 | ASSISTANT_NOTE: 'assistant_note', |
| 651 | ASSISTANT_MESSAGE: 'assistant_message', | ||
| 633 | }; | 652 | }; |
| 634 | 653 | ||
| 635 | /** | 654 | /** |
| @@ -731,6 +750,7 @@ async function getSystemMessages() { | |||
| 731 | force_avatar: system_avatar, | 750 | force_avatar: system_avatar, |
| 732 | is_user: false, | 751 | is_user: false, |
| 733 | is_system: true, | 752 | is_system: true, |
| 753 | uses_system_ui: true, | ||
| 734 | mes: await renderTemplateAsync('welcomePrompt'), | 754 | mes: await renderTemplateAsync('welcomePrompt'), |
| 735 | extra: { | 755 | extra: { |
| 736 | isSmallSys: true, | 756 | isSmallSys: true, |
| @@ -935,7 +955,7 @@ $.ajaxPrefilter((options, originalOptions, xhr) => { | |||
| 935 | export async function pingServer() { | 955 | export async function pingServer() { |
| 936 | try { | 956 | try { |
| 937 | const result = await fetch('api/ping', { | 957 | const result = await fetch('api/ping', { |
| 938 | method: 'GET', | 958 | method: 'POST', |
| 939 | headers: getRequestHeaders(), | 959 | headers: getRequestHeaders(), |
| 940 | }); | 960 | }); |
| 941 | 961 | ||
| @@ -950,17 +970,18 @@ export async function pingServer() { | |||
| 950 | } | 970 | } |
| 951 | } | 971 | } |
| 952 | 972 | ||
| 973 | //MARK: firstLoadInit | ||
| 953 | async function firstLoadInit() { | 974 | async function firstLoadInit() { |
| 954 | try { | 975 | try { |
| 955 | const tokenResponse = await fetch('/csrf-token'); | 976 | const tokenResponse = await fetch('/csrf-token'); |
| 956 | const tokenData = await tokenResponse.json(); | 977 | const tokenData = await tokenResponse.json(); |
| 957 | token = tokenData.token; | 978 | token = tokenData.token; |
| 958 | } catch { | 979 | } catch { |
| 959 | hideLoader(); | ||
| 960 | toastr.error(t`Couldn't get CSRF token. Please refresh the page.`, t`Error`, { timeOut: 0, extendedTimeOut: 0, preventDuplicates: true }); | 980 | toastr.error(t`Couldn't get CSRF token. Please refresh the page.`, t`Error`, { timeOut: 0, extendedTimeOut: 0, preventDuplicates: true }); |
| 961 | throw new Error('Initialization failed'); | 981 | throw new Error('Initialization failed'); |
| 962 | } | 982 | } |
| 963 | 983 | ||
| 984 | showLoader(); | ||
| 964 | initLibraryShims(); | 985 | initLibraryShims(); |
| 965 | addShowdownPatch(showdown); | 986 | addShowdownPatch(showdown); |
| 966 | reloadMarkdownProcessor(); | 987 | reloadMarkdownProcessor(); |
| @@ -968,6 +989,7 @@ async function firstLoadInit() { | |||
| 968 | await getClientVersion(); | 989 | await getClientVersion(); |
| 969 | await readSecretState(); | 990 | await readSecretState(); |
| 970 | await initLocales(); | 991 | await initLocales(); |
| 992 | initChatUtilities(); | ||
| 971 | initDefaultSlashCommands(); | 993 | initDefaultSlashCommands(); |
| 972 | initTextGenModels(); | 994 | initTextGenModels(); |
| 973 | initOpenAI(); | 995 | initOpenAI(); |
| @@ -977,8 +999,6 @@ async function firstLoadInit() { | |||
| 977 | ToolManager.initToolSlashCommands(); | 999 | ToolManager.initToolSlashCommands(); |
| 978 | await initPresetManager(); | 1000 | await initPresetManager(); |
| 979 | await getSystemMessages(); | 1001 | await getSystemMessages(); |
| 980 | sendSystemMessage(system_message_types.WELCOME); | ||
| 981 | sendSystemMessage(system_message_types.WELCOME_PROMPT); | ||
| 982 | await getSettings(); | 1002 | await getSettings(); |
| 983 | initKeyboard(); | 1003 | initKeyboard(); |
| 984 | initDynamicStyles(); | 1004 | initDynamicStyles(); |
| @@ -992,6 +1012,8 @@ async function firstLoadInit() { | |||
| 992 | initBackgrounds(); | 1012 | initBackgrounds(); |
| 993 | initAuthorsNote(); | 1013 | initAuthorsNote(); |
| 994 | await initPersonas(); | 1014 | await initPersonas(); |
| 1015 | initWorldInfo(); | ||
| 1016 | initHorde(); | ||
| 995 | initRossMods(); | 1017 | initRossMods(); |
| 996 | initStats(); | 1018 | initStats(); |
| 997 | initCfg(); | 1019 | initCfg(); |
| @@ -1001,7 +1023,10 @@ async function firstLoadInit() { | |||
| 1001 | initSettingsSearch(); | 1023 | initSettingsSearch(); |
| 1002 | initBulkEdit(); | 1024 | initBulkEdit(); |
| 1003 | initReasoning(); | 1025 | initReasoning(); |
| 1026 | initWelcomeScreen(); | ||
| 1004 | await initScrapers(); | 1027 | await initScrapers(); |
| 1028 | initCustomSelectedSamplers(); | ||
| 1029 | addDebugFunctions(); | ||
| 1005 | doDailyExtensionUpdatesCheck(); | 1030 | doDailyExtensionUpdatesCheck(); |
| 1006 | await hideLoader(); | 1031 | await hideLoader(); |
| 1007 | await fixViewport(); | 1032 | await fixViewport(); |
| @@ -1421,30 +1446,26 @@ function getBackBlock() { | |||
| 1421 | return template; | 1446 | return template; |
| 1422 | } | 1447 | } |
| 1423 | 1448 | ||
| 1424 | function getEmptyBlock() { | 1449 | async function getEmptyBlock() { |
| 1425 | const icons = ['fa-dragon', 'fa-otter', 'fa-kiwi-bird', 'fa-crow', 'fa-frog']; | 1450 | const icons = ['fa-dragon', 'fa-otter', 'fa-kiwi-bird', 'fa-crow', 'fa-frog']; |
| 1426 | const texts = ['Here be dragons', 'Otterly empty', 'Kiwibunga', 'Pump-a-Rum', 'Croak it']; | 1451 | const texts = [t`Here be dragons`, t`Otterly empty`, t`Kiwibunga`, t`Pump-a-Rum`, t`Croak it`]; |
| 1427 | const roll = new Date().getMinutes() % icons.length; | 1452 | const roll = new Date().getMinutes() % icons.length; |
| 1428 | const emptyBlock = ` | 1453 | const params = { |
| 1429 | <div class="text_block empty_block"> | 1454 | text: texts[roll], |
| 1430 | <i class="fa-solid ${icons[roll]} fa-4x"></i> | 1455 | icon: icons[roll], |
| 1431 | <h1>${texts[roll]}</h1> | 1456 | }; |
| 1432 | <p>There are no items to display.</p> | 1457 | const emptyBlock = await renderTemplateAsync('emptyBlock', params); |
| 1433 | </div>`; | ||
| 1434 | return $(emptyBlock); | 1458 | return $(emptyBlock); |
| 1435 | } | 1459 | } |
| 1436 | 1460 | ||
| 1437 | /** | 1461 | /** |
| 1438 | * @param {number} hidden Number of hidden characters | 1462 | * @param {number} hidden Number of hidden characters |
| 1439 | */ | 1463 | */ |
| 1440 | function getHiddenBlock(hidden) { | 1464 | async function getHiddenBlock(hidden) { |
| 1441 | const hiddenBlock = ` | 1465 | const params = { |
| 1442 | <div class="text_block hidden_block"> | 1466 | text: (hidden > 1 ? t`${hidden} characters hidden.` : t`${hidden} character hidden.`), |
| 1443 | <small> | 1467 | }; |
| 1444 | <p>${hidden} ${hidden > 1 ? 'characters' : 'character'} hidden.</p> | 1468 | const hiddenBlock = await renderTemplateAsync('hiddenBlock', params); |
| 1445 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Characters and groups hidden by filters or closed folders" title="Characters and groups hidden by filters or closed folders"></div> | ||
| 1446 | </small> | ||
| 1447 | </div>`; | ||
| 1448 | return $(hiddenBlock); | 1469 | return $(hiddenBlock); |
| 1449 | } | 1470 | } |
| 1450 | 1471 | ||
| @@ -1466,6 +1487,11 @@ function getCharacterBlock(item, id) { | |||
| 1466 | template.toggleClass('is_fav', item.fav || item.fav == 'true'); | 1487 | template.toggleClass('is_fav', item.fav || item.fav == 'true'); |
| 1467 | template.find('.ch_fav').val(item.fav); | 1488 | template.find('.ch_fav').val(item.fav); |
| 1468 | 1489 | ||
| 1490 | const isAssistant = item.avatar === getPermanentAssistantAvatar(); | ||
| 1491 | if (!isAssistant) { | ||
| 1492 | template.find('.ch_assistant').remove(); | ||
| 1493 | } | ||
| 1494 | |||
| 1469 | const description = item.data?.creator_notes || ''; | 1495 | const description = item.data?.creator_notes || ''; |
| 1470 | if (description) { | 1496 | if (description) { |
| 1471 | template.find('.ch_description').text(description); | 1497 | template.find('.ch_description').text(description); |
| @@ -1485,7 +1511,7 @@ function getCharacterBlock(item, id) { | |||
| 1485 | 1511 | ||
| 1486 | // Display inline tags | 1512 | // Display inline tags |
| 1487 | const tagsElement = template.find('.tags'); | 1513 | const tagsElement = template.find('.tags'); |
| 1488 | printTagList(tagsElement, { forEntityOrKey: id }); | 1514 | printTagList(tagsElement, { forEntityOrKey: id, tagOptions: { isCharacterList: true } }); |
| 1489 | 1515 | ||
| 1490 | // Add to the list | 1516 | // Add to the list |
| 1491 | return template; | 1517 | return template; |
| @@ -1524,10 +1550,11 @@ export async function printCharacters(fullRefresh = false) { | |||
| 1524 | 1550 | ||
| 1525 | const entities = getEntitiesList({ doFilter: true }); | 1551 | const entities = getEntitiesList({ doFilter: true }); |
| 1526 | 1552 | ||
| 1553 | const pageSize = Number(accountStorage.getItem(storageKey)) || per_page_default; | ||
| 1554 | const sizeChangerOptions = [10, 25, 50, 100, 250, 500, 1000]; | ||
| 1527 | $('#rm_print_characters_pagination').pagination({ | 1555 | $('#rm_print_characters_pagination').pagination({ |
| 1528 | dataSource: entities, | 1556 | dataSource: entities, |
| 1529 | pageSize: Number(accountStorage.getItem(storageKey)) || per_page_default, | 1557 | pageSize, |
| 1530 | sizeChangerOptions: [10, 25, 50, 100, 250, 500, 1000], | ||
| 1531 | pageRange: 1, | 1558 | pageRange: 1, |
| 1532 | pageNumber: saveCharactersPage || 1, | 1559 | pageNumber: saveCharactersPage || 1, |
| 1533 | position: 'top', | 1560 | position: 'top', |
| @@ -1536,14 +1563,16 @@ export async function printCharacters(fullRefresh = false) { | |||
| 1536 | prevText: '<', | 1563 | prevText: '<', |
| 1537 | nextText: '>', | 1564 | nextText: '>', |
| 1538 | formatNavigator: PAGINATION_TEMPLATE, | 1565 | formatNavigator: PAGINATION_TEMPLATE, |
| 1566 | formatSizeChanger: renderPaginationDropdown(pageSize, sizeChangerOptions), | ||
| 1539 | showNavigator: true, | 1567 | showNavigator: true, |
| 1540 | callback: function (/** @type {Entity[]} */ data) { | 1568 | callback: async function (/** @type {Entity[]} */ data) { |
| 1541 | $(listId).empty(); | 1569 | $(listId).empty(); |
| 1542 | if (power_user.bogus_folders && isBogusFolderOpen()) { | 1570 | if (power_user.bogus_folders && isBogusFolderOpen()) { |
| 1543 | $(listId).append(getBackBlock()); | 1571 | $(listId).append(getBackBlock()); |
| 1544 | } | 1572 | } |
| 1545 | if (!data.length) { | 1573 | if (!data.length) { |
| 1546 | $(listId).append(getEmptyBlock()); | 1574 | const emptyBlock = await getEmptyBlock(); |
| 1575 | $(listId).append(emptyBlock); | ||
| 1547 | } | 1576 | } |
| 1548 | let displayCount = 0; | 1577 | let displayCount = 0; |
| 1549 | for (const i of data) { | 1578 | for (const i of data) { |
| @@ -1564,13 +1593,16 @@ export async function printCharacters(fullRefresh = false) { | |||
| 1564 | 1593 | ||
| 1565 | const hidden = (characters.length + groups.length) - displayCount; | 1594 | const hidden = (characters.length + groups.length) - displayCount; |
| 1566 | if (hidden > 0 && entitiesFilter.hasAnyFilter()) { | 1595 | if (hidden > 0 && entitiesFilter.hasAnyFilter()) { |
| 1567 | $(listId).append(getHiddenBlock(hidden)); | 1596 | const hiddenBlock = await getHiddenBlock(hidden); |
| 1597 | $(listId).append(hiddenBlock); | ||
| 1568 | } | 1598 | } |
| 1599 | localizePagination($('#rm_print_characters_pagination')); | ||
| 1569 | 1600 | ||
| 1570 | eventSource.emit(event_types.CHARACTER_PAGE_LOADED); | 1601 | eventSource.emit(event_types.CHARACTER_PAGE_LOADED); |
| 1571 | }, | 1602 | }, |
| 1572 | afterSizeSelectorChange: function (e) { | 1603 | afterSizeSelectorChange: function (e, size) { |
| 1573 | accountStorage.setItem(storageKey, e.target.value); | 1604 | accountStorage.setItem(storageKey, e.target.value); |
| 1605 | paginationDropdownChangeHandler(e, size); | ||
| 1574 | }, | 1606 | }, |
| 1575 | afterPaging: function (e) { | 1607 | afterPaging: function (e) { |
| 1576 | saveCharactersPage = e; | 1608 | saveCharactersPage = e; |
| @@ -1911,6 +1943,7 @@ export async function showMoreMessages(messagesToLoad = null) { | |||
| 1911 | $('#chat').scrollTop(newHeight - prevHeight); | 1943 | $('#chat').scrollTop(newHeight - prevHeight); |
| 1912 | } | 1944 | } |
| 1913 | 1945 | ||
| 1946 | applyStylePins(); | ||
| 1914 | await eventSource.emit(event_types.MORE_MESSAGES_LOADED); | 1947 | await eventSource.emit(event_types.MORE_MESSAGES_LOADED); |
| 1915 | } | 1948 | } |
| 1916 | 1949 | ||
| @@ -1948,6 +1981,7 @@ export async function printMessages() { | |||
| 1948 | hideSwipeButtons(); | 1981 | hideSwipeButtons(); |
| 1949 | showSwipeButtons(); | 1982 | showSwipeButtons(); |
| 1950 | scrollChatToBottom(); | 1983 | scrollChatToBottom(); |
| 1984 | applyStylePins(); | ||
| 1951 | 1985 | ||
| 1952 | function incrementAndCheck() { | 1986 | function incrementAndCheck() { |
| 1953 | imagesLoaded++; | 1987 | imagesLoaded++; |
| @@ -1957,7 +1991,20 @@ export async function printMessages() { | |||
| 1957 | } | 1991 | } |
| 1958 | } | 1992 | } |
| 1959 | 1993 | ||
| 1994 | /** | ||
| 1995 | * Cancels the debounced chat save if it is currently pending. | ||
| 1996 | */ | ||
| 1997 | export function cancelDebouncedChatSave() { | ||
| 1998 | if (chatSaveTimeout) { | ||
| 1999 | console.debug('Debounced chat save cancelled'); | ||
| 2000 | clearTimeout(chatSaveTimeout); | ||
| 2001 | chatSaveTimeout = null; | ||
| 2002 | } | ||
| 2003 | } | ||
| 2004 | |||
| 1960 | export async function clearChat() { | 2005 | export async function clearChat() { |
| 2006 | cancelDebouncedChatSave(); | ||
| 2007 | cancelDebouncedMetadataSave(); | ||
| 1961 | closeMessageEditor(); | 2008 | closeMessageEditor(); |
| 1962 | extension_prompts = {}; | 2009 | extension_prompts = {}; |
| 1963 | if (is_delete_mode) { | 2010 | if (is_delete_mode) { |
| @@ -2026,7 +2073,7 @@ export async function sendTextareaMessage() { | |||
| 2026 | } | 2073 | } |
| 2027 | 2074 | ||
| 2028 | if (textareaText && !selected_group && this_chid === undefined && name2 !== neutralCharacterName) { | 2075 | if (textareaText && !selected_group && this_chid === undefined && name2 !== neutralCharacterName) { |
| 2029 | await newAssistantChat(); | 2076 | await newAssistantChat({ temporary: false }); |
| 2030 | } | 2077 | } |
| 2031 | 2078 | ||
| 2032 | Generate(generateType); | 2079 | Generate(generateType); |
| @@ -2197,7 +2244,7 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san | |||
| 2197 | }; | 2244 | }; |
| 2198 | mes = encodeStyleTags(mes); | 2245 | mes = encodeStyleTags(mes); |
| 2199 | mes = DOMPurify.sanitize(mes, config); | 2246 | mes = DOMPurify.sanitize(mes, config); |
| 2200 | mes = decodeStyleTags(mes); | 2247 | mes = decodeStyleTags(mes, { prefix: '.mes_text ' }); |
| 2201 | 2248 | ||
| 2202 | return mes; | 2249 | return mes; |
| 2203 | } | 2250 | } |
| @@ -2277,6 +2324,7 @@ function getMessageFromTemplate({ | |||
| 2277 | timestamp, | 2324 | timestamp, |
| 2278 | tokenCount, | 2325 | tokenCount, |
| 2279 | extra, | 2326 | extra, |
| 2327 | type, | ||
| 2280 | }) { | 2328 | }) { |
| 2281 | const mes = messageTemplate.clone(); | 2329 | const mes = messageTemplate.clone(); |
| 2282 | mes.attr({ | 2330 | mes.attr({ |
| @@ -2288,6 +2336,7 @@ function getMessageFromTemplate({ | |||
| 2288 | 'bookmark_link': bookmarkLink, | 2336 | 'bookmark_link': bookmarkLink, |
| 2289 | 'force_avatar': !!forceAvatar, | 2337 | 'force_avatar': !!forceAvatar, |
| 2290 | 'timestamp': timestamp, | 2338 | 'timestamp': timestamp, |
| 2339 | ...(type ? { type } : {}), | ||
| 2291 | }); | 2340 | }); |
| 2292 | mes.find('.avatar img').attr('src', avatarImg); | 2341 | mes.find('.avatar img').attr('src', avatarImg); |
| 2293 | mes.find('.ch_name .name_text').text(characterName); | 2342 | mes.find('.ch_name .name_text').text(characterName); |
| @@ -2499,6 +2548,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | |||
| 2499 | timestamp: timestamp, | 2548 | timestamp: timestamp, |
| 2500 | extra: mes.extra, | 2549 | extra: mes.extra, |
| 2501 | tokenCount: mes.extra?.token_count ?? 0, | 2550 | tokenCount: mes.extra?.token_count ?? 0, |
| 2551 | type: mes.extra?.type ?? '', | ||
| 2502 | ...formatGenerationTimer(mes.gen_started, mes.gen_finished, mes.extra?.token_count, mes.extra?.reasoning_duration, mes.extra?.time_to_first_token), | 2552 | ...formatGenerationTimer(mes.gen_started, mes.gen_finished, mes.extra?.token_count, mes.extra?.reasoning_duration, mes.extra?.time_to_first_token), |
| 2503 | }; | 2553 | }; |
| 2504 | 2554 | ||
| @@ -2751,6 +2801,7 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re | |||
| 2751 | environment.charVersion = fields.version || ''; | 2801 | environment.charVersion = fields.version || ''; |
| 2752 | environment.char_version = fields.version || ''; | 2802 | environment.char_version = fields.version || ''; |
| 2753 | environment.charDepthPrompt = fields.charDepthPrompt || ''; | 2803 | environment.charDepthPrompt = fields.charDepthPrompt || ''; |
| 2804 | environment.creatorNotes = fields.creatorNotes || ''; | ||
| 2754 | } | 2805 | } |
| 2755 | 2806 | ||
| 2756 | // Must be substituted last so that they're replaced inside {{description}} | 2807 | // Must be substituted last so that they're replaced inside {{description}} |
| @@ -2867,7 +2918,14 @@ export async function processCommands(message) { | |||
| 2867 | return true; | 2918 | return true; |
| 2868 | } | 2919 | } |
| 2869 | 2920 | ||
| 2870 | export function sendSystemMessage(type, text, extra = {}) { | 2921 | /** |
| 2922 | * Gets a system message by type. | ||
| 2923 | * @param {string} type Type of system message | ||
| 2924 | * @param {string} [text] Text to be sent | ||
| 2925 | * @param {object} [extra] Additional data to be added to the message | ||
| 2926 | * @returns {object} System message object | ||
| 2927 | */ | ||
| 2928 | export function getSystemMessageByType(type, text, extra = {}) { | ||
| 2871 | const systemMessage = system_messages[type]; | 2929 | const systemMessage = system_messages[type]; |
| 2872 | 2930 | ||
| 2873 | if (!systemMessage) { | 2931 | if (!systemMessage) { |
| @@ -2890,7 +2948,17 @@ export function sendSystemMessage(type, text, extra = {}) { | |||
| 2890 | 2948 | ||
| 2891 | newMessage.extra = Object.assign(newMessage.extra, extra); | 2949 | newMessage.extra = Object.assign(newMessage.extra, extra); |
| 2892 | newMessage.extra.type = type; | 2950 | newMessage.extra.type = type; |
| 2951 | return newMessage; | ||
| 2952 | } | ||
| 2893 | 2953 | ||
| 2954 | /** | ||
| 2955 | * Sends a system message to the chat. | ||
| 2956 | * @param {string} type Type of system message | ||
| 2957 | * @param {string} [text] Text to be sent | ||
| 2958 | * @param {object} [extra] Additional data to be added to the message | ||
| 2959 | */ | ||
| 2960 | export function sendSystemMessage(type, text, extra = {}) { | ||
| 2961 | const newMessage = getSystemMessageByType(type, text, extra); | ||
| 2894 | chat.push(newMessage); | 2962 | chat.push(newMessage); |
| 2895 | addOneMessage(newMessage); | 2963 | addOneMessage(newMessage); |
| 2896 | is_send_press = false; | 2964 | is_send_press = false; |
| @@ -3129,6 +3197,7 @@ export function baseChatReplace(value, name1, name2) { | |||
| 3129 | * @property {string} jailbreak Jailbreak instructions | 3197 | * @property {string} jailbreak Jailbreak instructions |
| 3130 | * @property {string} version Character version | 3198 | * @property {string} version Character version |
| 3131 | * @property {string} charDepthPrompt Character depth note | 3199 | * @property {string} charDepthPrompt Character depth note |
| 3200 | * @property {string} creatorNotes Character creator notes | ||
| 3132 | * @returns {CharacterCardFields} Character card fields | 3201 | * @returns {CharacterCardFields} Character card fields |
| 3133 | */ | 3202 | */ |
| 3134 | export function getCharacterCardFields({ chid = null } = {}) { | 3203 | export function getCharacterCardFields({ chid = null } = {}) { |
| @@ -3144,6 +3213,7 @@ export function getCharacterCardFields({ chid = null } = {}) { | |||
| 3144 | jailbreak: '', | 3213 | jailbreak: '', |
| 3145 | version: '', | 3214 | version: '', |
| 3146 | charDepthPrompt: '', | 3215 | charDepthPrompt: '', |
| 3216 | creatorNotes: '', | ||
| 3147 | }; | 3217 | }; |
| 3148 | result.persona = baseChatReplace(power_user.persona_description?.trim(), name1, name2); | 3218 | result.persona = baseChatReplace(power_user.persona_description?.trim(), name1, name2); |
| 3149 | 3219 | ||
| @@ -3162,6 +3232,7 @@ export function getCharacterCardFields({ chid = null } = {}) { | |||
| 3162 | result.jailbreak = power_user.prefer_character_jailbreak ? baseChatReplace(character.data?.post_history_instructions?.trim(), name1, name2) : ''; | 3232 | result.jailbreak = power_user.prefer_character_jailbreak ? baseChatReplace(character.data?.post_history_instructions?.trim(), name1, name2) : ''; |
| 3163 | result.version = character.data?.character_version ?? ''; | 3233 | result.version = character.data?.character_version ?? ''; |
| 3164 | result.charDepthPrompt = baseChatReplace(character.data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2); | 3234 | result.charDepthPrompt = baseChatReplace(character.data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2); |
| 3235 | result.creatorNotes = baseChatReplace(character.data?.creator_notes?.trim(), name1, name2); | ||
| 3165 | 3236 | ||
| 3166 | if (selected_group) { | 3237 | if (selected_group) { |
| 3167 | const groupCards = getGroupCharacterCards(selected_group, Number(currentChid)); | 3238 | const groupCards = getGroupCharacterCards(selected_group, Number(currentChid)); |
| @@ -3802,6 +3873,7 @@ function removeLastMessage() { | |||
| 3802 | } | 3873 | } |
| 3803 | 3874 | ||
| 3804 | /** | 3875 | /** |
| 3876 | * MARK:Generate() | ||
| 3805 | * Runs a generation using the current chat context. | 3877 | * Runs a generation using the current chat context. |
| 3806 | * @param {string} type Generation type | 3878 | * @param {string} type Generation type |
| 3807 | * @param {GenerateOptions} options Generation options | 3879 | * @param {GenerateOptions} options Generation options |
| @@ -3989,11 +4061,14 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3989 | system, | 4061 | system, |
| 3990 | jailbreak, | 4062 | jailbreak, |
| 3991 | charDepthPrompt, | 4063 | charDepthPrompt, |
| 4064 | creatorNotes, | ||
| 3992 | } = getCharacterCardFields(); | 4065 | } = getCharacterCardFields(); |
| 3993 | 4066 | ||
| 3994 | if (main_api !== 'openai') { | 4067 | if (main_api !== 'openai') { |
| 3995 | if (power_user.sysprompt.enabled) { | 4068 | if (power_user.sysprompt.enabled) { |
| 3996 | system = power_user.prefer_character_prompt && system ? system : baseChatReplace(power_user.sysprompt.content, name1, name2); | 4069 | system = power_user.prefer_character_prompt && system |
| 4070 | ? substituteParams(system, name1, name2, (power_user.sysprompt.content ?? '')) | ||
| 4071 | : baseChatReplace(power_user.sysprompt.content, name1, name2); | ||
| 3997 | system = isInstruct ? formatInstructModeSystemPrompt(substituteParams(system, name1, name2, power_user.sysprompt.content)) : system; | 4072 | system = isInstruct ? formatInstructModeSystemPrompt(substituteParams(system, name1, name2, power_user.sysprompt.content)) : system; |
| 3998 | } else { | 4073 | } else { |
| 3999 | // Nullify if it's not enabled | 4074 | // Nullify if it's not enabled |
| @@ -4121,7 +4196,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4121 | 4196 | ||
| 4122 | console.log(`Core/all messages: ${coreChat.length}/${chat.length}`); | 4197 | console.log(`Core/all messages: ${coreChat.length}/${chat.length}`); |
| 4123 | 4198 | ||
| 4124 | // kingbri MARK: - Make sure the prompt bias isn't the same as the user bias | ||
| 4125 | if ((promptBias && !isUserPromptBias) || power_user.always_force_name2 || main_api == 'novel') { | 4199 | if ((promptBias && !isUserPromptBias) || power_user.always_force_name2 || main_api == 'novel') { |
| 4126 | force_name2 = true; | 4200 | force_name2 = true; |
| 4127 | } | 4201 | } |
| @@ -4143,7 +4217,15 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4143 | // Make quiet prompt available for WIAN | 4217 | // Make quiet prompt available for WIAN |
| 4144 | setExtensionPrompt('QUIET_PROMPT', quiet_prompt || '', extension_prompt_types.IN_PROMPT, 0, true); | 4218 | setExtensionPrompt('QUIET_PROMPT', quiet_prompt || '', extension_prompt_types.IN_PROMPT, 0, true); |
| 4145 | const chatForWI = coreChat.map(x => world_info_include_names ? `${x.name}: ${x.mes}` : x.mes).reverse(); | 4219 | const chatForWI = coreChat.map(x => world_info_include_names ? `${x.name}: ${x.mes}` : x.mes).reverse(); |
| 4146 | const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(chatForWI, this_max_context, dryRun); | 4220 | const globalScanData = { |
| 4221 | personaDescription: persona, | ||
| 4222 | characterDescription: description, | ||
| 4223 | characterPersonality: personality, | ||
| 4224 | characterDepthPrompt: charDepthPrompt, | ||
| 4225 | scenario: scenario, | ||
| 4226 | creatorNotes: creatorNotes, | ||
| 4227 | }; | ||
| 4228 | const { worldInfoString, worldInfoBefore, worldInfoAfter, worldInfoExamples, worldInfoDepth } = await getWorldInfoPrompt(chatForWI, this_max_context, dryRun, globalScanData); | ||
| 4147 | setExtensionPrompt('QUIET_PROMPT', '', extension_prompt_types.IN_PROMPT, 0, true); | 4229 | setExtensionPrompt('QUIET_PROMPT', '', extension_prompt_types.IN_PROMPT, 0, true); |
| 4148 | 4230 | ||
| 4149 | // Add message example WI | 4231 | // Add message example WI |
| @@ -4192,11 +4274,13 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4192 | injectedIndices = await doChatInject(coreChat, isContinue); | 4274 | injectedIndices = await doChatInject(coreChat, isContinue); |
| 4193 | } | 4275 | } |
| 4194 | 4276 | ||
| 4195 | // Insert character jailbreak as the last user message (if exists, allowed, preferred, and not using Chat Completion) | 4277 | if (main_api !== 'openai' && power_user.sysprompt.enabled) { |
| 4196 | if (power_user.context.allow_jailbreak && power_user.prefer_character_jailbreak && main_api !== 'openai' && jailbreak) { | 4278 | jailbreak = power_user.prefer_character_jailbreak && jailbreak |
| 4197 | // Set "original" explicity to empty string since there's no original | 4279 | ? substituteParams(jailbreak, name1, name2, (power_user.sysprompt.post_history ?? '')) |
| 4198 | jailbreak = substituteParams(jailbreak, name1, name2, ''); | 4280 | : baseChatReplace(power_user.sysprompt.post_history, name1, name2); |
| 4199 | 4281 | ||
| 4282 | // Only inject the jb if there is one | ||
| 4283 | if (jailbreak) { | ||
| 4200 | // When continuing generation of previous output, last user message precedes the message to continue | 4284 | // When continuing generation of previous output, last user message precedes the message to continue |
| 4201 | if (isContinue) { | 4285 | if (isContinue) { |
| 4202 | coreChat.splice(coreChat.length - 1, 0, { mes: jailbreak, is_user: true }); | 4286 | coreChat.splice(coreChat.length - 1, 0, { mes: jailbreak, is_user: true }); |
| @@ -4205,6 +4289,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4205 | coreChat.push({ mes: jailbreak, is_user: true }); | 4289 | coreChat.push({ mes: jailbreak, is_user: true }); |
| 4206 | } | 4290 | } |
| 4207 | } | 4291 | } |
| 4292 | } | ||
| 4208 | 4293 | ||
| 4209 | let chat2 = []; | 4294 | let chat2 = []; |
| 4210 | let continue_mag = ''; | 4295 | let continue_mag = ''; |
| @@ -4235,12 +4320,20 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4235 | 4320 | ||
| 4236 | // Do not suffix the message for continuation | 4321 | // Do not suffix the message for continuation |
| 4237 | if (i === 0 && isContinue) { | 4322 | if (i === 0 && isContinue) { |
| 4323 | // Pick something that's very unlikely to be in a message | ||
| 4324 | const FORMAT_TOKEN = '\u0000\ufffc\u0000\ufffd'; | ||
| 4325 | |||
| 4238 | if (isInstruct) { | 4326 | if (isInstruct) { |
| 4327 | const originalMessage = String(coreChat[j].mes ?? ''); | ||
| 4328 | coreChat[j].mes = originalMessage.replaceAll(FORMAT_TOKEN, '') + FORMAT_TOKEN; | ||
| 4239 | // Reformat with the last output sequence (if any) | 4329 | // Reformat with the last output sequence (if any) |
| 4240 | chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.LAST); | 4330 | chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.LAST); |
| 4331 | coreChat[j].mes = originalMessage; | ||
| 4241 | } | 4332 | } |
| 4242 | 4333 | ||
| 4243 | chat2[i] = chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length); | 4334 | chat2[i] = chat2[i].includes(FORMAT_TOKEN) |
| 4335 | ? chat2[i].slice(0, chat2[i].lastIndexOf(FORMAT_TOKEN)) | ||
| 4336 | : chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length); | ||
| 4244 | continue_mag = coreChat[j].mes; | 4337 | continue_mag = coreChat[j].mes; |
| 4245 | } | 4338 | } |
| 4246 | 4339 | ||
| @@ -4771,7 +4864,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4771 | name2: name2, | 4864 | name2: name2, |
| 4772 | charDescription: description, | 4865 | charDescription: description, |
| 4773 | charPersonality: personality, | 4866 | charPersonality: personality, |
| 4774 | Scenario: scenario, | 4867 | scenario: scenario, |
| 4775 | worldInfoBefore: worldInfoBefore, | 4868 | worldInfoBefore: worldInfoBefore, |
| 4776 | worldInfoAfter: worldInfoAfter, | 4869 | worldInfoAfter: worldInfoAfter, |
| 4777 | extensionPrompts: extension_prompts, | 4870 | extensionPrompts: extension_prompts, |
| @@ -4854,6 +4947,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4854 | userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''), | 4947 | userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''), |
| 4855 | tokenizer: getFriendlyTokenizerName(main_api).tokenizerName || '', | 4948 | tokenizer: getFriendlyTokenizerName(main_api).tokenizerName || '', |
| 4856 | presetName: getPresetManager()?.getSelectedPresetName() || '', | 4949 | presetName: getPresetManager()?.getSelectedPresetName() || '', |
| 4950 | messagesCount: main_api !== 'openai' ? mesSend.length : oaiMessages.length, | ||
| 4951 | examplesCount: main_api !== 'openai' ? (pinExmString ? mesExamplesArray.length : count_exm_add) : oaiMessageExamples.length, | ||
| 4857 | }; | 4952 | }; |
| 4858 | 4953 | ||
| 4859 | //console.log(additionalPromptStuff); | 4954 | //console.log(additionalPromptStuff); |
| @@ -5083,6 +5178,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 5083 | throw exception; | 5178 | throw exception; |
| 5084 | } | 5179 | } |
| 5085 | } | 5180 | } |
| 5181 | //MARK: Generate() ends | ||
| 5086 | 5182 | ||
| 5087 | /** | 5183 | /** |
| 5088 | * Stops the generation and any streaming if it is currently running. | 5184 | * Stops the generation and any streaming if it is currently running. |
| @@ -5537,6 +5633,8 @@ export async function itemizedParams(itemizedPrompts, thisPromptSet, incomingMes | |||
| 5537 | modelUsed: chat[incomingMesId]?.extra?.model, | 5633 | modelUsed: chat[incomingMesId]?.extra?.model, |
| 5538 | apiUsed: chat[incomingMesId]?.extra?.api, | 5634 | apiUsed: chat[incomingMesId]?.extra?.api, |
| 5539 | presetName: itemizedPrompts[thisPromptSet].presetName || t`(Unknown)`, | 5635 | presetName: itemizedPrompts[thisPromptSet].presetName || t`(Unknown)`, |
| 5636 | messagesCount: String(itemizedPrompts[thisPromptSet].messagesCount ?? ''), | ||
| 5637 | examplesCount: String(itemizedPrompts[thisPromptSet].examplesCount ?? ''), | ||
| 5540 | }; | 5638 | }; |
| 5541 | 5639 | ||
| 5542 | const getFriendlyName = (value) => $(`#rm_api_block select option[value="${value}"]`).first().text() || value; | 5640 | const getFriendlyName = (value) => $(`#rm_api_block select option[value="${value}"]`).first().text() || value; |
| @@ -5855,6 +5953,7 @@ function extractImageFromData(data, { mainApi = null, chatCompletionSource = nul | |||
| 5855 | switch (mainApi ?? main_api) { | 5953 | switch (mainApi ?? main_api) { |
| 5856 | case 'openai': { | 5954 | case 'openai': { |
| 5857 | switch (chatCompletionSource ?? oai_settings.chat_completion_source) { | 5955 | switch (chatCompletionSource ?? oai_settings.chat_completion_source) { |
| 5956 | case chat_completion_sources.VERTEXAI: | ||
| 5858 | case chat_completion_sources.MAKERSUITE: { | 5957 | case chat_completion_sources.MAKERSUITE: { |
| 5859 | const inlineData = data?.responseContent?.parts?.find(x => x.inlineData)?.inlineData; | 5958 | const inlineData = data?.responseContent?.parts?.find(x => x.inlineData)?.inlineData; |
| 5860 | if (inlineData) { | 5959 | if (inlineData) { |
| @@ -6857,11 +6956,7 @@ export function saveChatDebounced() { | |||
| 6857 | const chid = this_chid; | 6956 | const chid = this_chid; |
| 6858 | const selectedGroup = selected_group; | 6957 | const selectedGroup = selected_group; |
| 6859 | 6958 | ||
| 6860 | if (chatSaveTimeout) { | 6959 | cancelDebouncedChatSave(); |
| 6861 | console.debug('Clearing chat save timeout'); | ||
| 6862 | clearTimeout(chatSaveTimeout); | ||
| 6863 | chatSaveTimeout = null; | ||
| 6864 | } | ||
| 6865 | 6960 | ||
| 6866 | chatSaveTimeout = setTimeout(async () => { | 6961 | chatSaveTimeout = setTimeout(async () => { |
| 6867 | if (selectedGroup !== selected_group) { | 6962 | if (selectedGroup !== selected_group) { |
| @@ -6955,15 +7050,23 @@ export async function saveChat({ chatName, withMetadata, mesId, force = false } | |||
| 6955 | throw new Error(result.statusText); | 7050 | throw new Error(result.statusText); |
| 6956 | } | 7051 | } |
| 6957 | 7052 | ||
| 6958 | const forceSaveConfirmed = await Popup.show.confirm( | 7053 | const popupResult = await Popup.show.input( |
| 6959 | t`ERROR: Chat integrity check failed.`, | 7054 | t`ERROR: Chat integrity check failed while saving the file.`, |
| 6960 | t`Continuing the operation may result in data loss. Would you like to overwrite the chat file anyway? Pressing "NO" will cancel the save operation.`, | 7055 | t`<p>After you click OK, the page will be reloaded to prevent data corruption.</p> |
| 6961 | { okButton: t`Yes, overwrite`, cancelButton: t`No, cancel` }, | 7056 | <p>To confirm an overwrite (and potentially <b>LOSE YOUR DATA</b>), enter <code>OVERWRITE</code> (in all caps) in the box below before clicking OK.</p>`, |
| 6962 | ) === POPUP_RESULT.AFFIRMATIVE; | 7057 | '', |
| 7058 | { okButton: 'OK', cancelButton: false }, | ||
| 7059 | ); | ||
| 7060 | |||
| 7061 | const forceSaveConfirmed = popupResult === 'OVERWRITE'; | ||
| 6963 | 7062 | ||
| 6964 | if (forceSaveConfirmed) { | 7063 | if (!forceSaveConfirmed) { |
| 6965 | await saveChat({ chatName, withMetadata, mesId, force: true }); | 7064 | console.warn('Chat integrity check failed, and user did not confirm the overwrite. Reloading the page.'); |
| 7065 | window.location.reload(); | ||
| 7066 | return; | ||
| 6966 | } | 7067 | } |
| 7068 | |||
| 7069 | await saveChat({ chatName, withMetadata, mesId, force: true }); | ||
| 6967 | } catch (error) { | 7070 | } catch (error) { |
| 6968 | console.error(error); | 7071 | console.error(error); |
| 6969 | toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Chat could not be saved`); | 7072 | toastr.error(t`Check the server connection and reload the page to prevent data loss.`, t`Chat could not be saved`); |
| @@ -7219,6 +7322,7 @@ function getFirstMessage() { | |||
| 7219 | } | 7322 | } |
| 7220 | 7323 | ||
| 7221 | export async function openCharacterChat(file_name) { | 7324 | export async function openCharacterChat(file_name) { |
| 7325 | await waitUntilCondition(() => !isChatSaving, debounce_timeout.extended, 10); | ||
| 7222 | await clearChat(); | 7326 | await clearChat(); |
| 7223 | characters[this_chid]['chat'] = file_name; | 7327 | characters[this_chid]['chat'] = file_name; |
| 7224 | chat.length = 0; | 7328 | chat.length = 0; |
| @@ -7387,7 +7491,7 @@ function reloadLoop() { | |||
| 7387 | } | 7491 | } |
| 7388 | } | 7492 | } |
| 7389 | 7493 | ||
| 7390 | //***************SETTINGS****************// | 7494 | //MARK: getSettings() |
| 7391 | /////////////////////////////////////////// | 7495 | /////////////////////////////////////////// |
| 7392 | export async function getSettings() { | 7496 | export async function getSettings() { |
| 7393 | const response = await fetch('/api/settings/get', { | 7497 | const response = await fetch('/api/settings/get', { |
| @@ -7581,6 +7685,7 @@ function selectKoboldGuiPreset() { | |||
| 7581 | .trigger('change'); | 7685 | .trigger('change'); |
| 7582 | } | 7686 | } |
| 7583 | 7687 | ||
| 7688 | //MARK: saveSettings() | ||
| 7584 | export async function saveSettings(loopCounter = 0) { | 7689 | export async function saveSettings(loopCounter = 0) { |
| 7585 | if (!settingsReady) { | 7690 | if (!settingsReady) { |
| 7586 | console.warn('Settings not ready, scheduling another save'); | 7691 | console.warn('Settings not ready, scheduling another save'); |
| @@ -8155,7 +8260,7 @@ export function select_selected_character(chid, { switchMenu = true } = {}) { | |||
| 8155 | $('#description_textarea').val(characters[chid].description); | 8260 | $('#description_textarea').val(characters[chid].description); |
| 8156 | $('#character_world').val(characters[chid].data?.extensions?.world || ''); | 8261 | $('#character_world').val(characters[chid].data?.extensions?.world || ''); |
| 8157 | $('#creator_notes_textarea').val(characters[chid].data?.creator_notes || characters[chid].creatorcomment); | 8262 | $('#creator_notes_textarea').val(characters[chid].data?.creator_notes || characters[chid].creatorcomment); |
| 8158 | $('#creator_notes_spoiler').html(DOMPurify.sanitize(converter.makeHtml(substituteParams(characters[chid].data?.creator_notes) || characters[chid].creatorcomment), { MESSAGE_SANITIZE: true })); | 8263 | $('#creator_notes_spoiler').html(formatCreatorNotes(characters[chid].data?.creator_notes || characters[chid].creatorcomment, characters[chid].avatar)); |
| 8159 | $('#character_version_textarea').val(characters[chid].data?.character_version || ''); | 8264 | $('#character_version_textarea').val(characters[chid].data?.character_version || ''); |
| 8160 | $('#system_prompt_textarea').val(characters[chid].data?.system_prompt || ''); | 8265 | $('#system_prompt_textarea').val(characters[chid].data?.system_prompt || ''); |
| 8161 | $('#post_history_instructions_textarea').val(characters[chid].data?.post_history_instructions || ''); | 8266 | $('#post_history_instructions_textarea').val(characters[chid].data?.post_history_instructions || ''); |
| @@ -8236,7 +8341,7 @@ function select_rm_create({ switchMenu = true } = {}) { | |||
| 8236 | $('#description_textarea').val(create_save.description); | 8341 | $('#description_textarea').val(create_save.description); |
| 8237 | $('#character_world').val(create_save.world); | 8342 | $('#character_world').val(create_save.world); |
| 8238 | $('#creator_notes_textarea').val(create_save.creator_notes); | 8343 | $('#creator_notes_textarea').val(create_save.creator_notes); |
| 8239 | $('#creator_notes_spoiler').html(DOMPurify.sanitize(converter.makeHtml(create_save.creator_notes), { MESSAGE_SANITIZE: true })); | 8344 | $('#creator_notes_spoiler').html(formatCreatorNotes(create_save.creator_notes, '')); |
| 8240 | $('#post_history_instructions_textarea').val(create_save.post_history_instructions); | 8345 | $('#post_history_instructions_textarea').val(create_save.post_history_instructions); |
| 8241 | $('#system_prompt_textarea').val(create_save.system_prompt); | 8346 | $('#system_prompt_textarea').val(create_save.system_prompt); |
| 8242 | $('#tags_textarea').val(create_save.tags); | 8347 | $('#tags_textarea').val(create_save.tags); |
| @@ -8390,15 +8495,15 @@ export function callPopup(text, type, inputValue = '', { okButton, rows, wide, w | |||
| 8390 | function getOkButtonText() { | 8495 | function getOkButtonText() { |
| 8391 | if (['text', 'char_not_selected'].includes(popup_type)) { | 8496 | if (['text', 'char_not_selected'].includes(popup_type)) { |
| 8392 | $dialoguePopupCancel.css('display', 'none'); | 8497 | $dialoguePopupCancel.css('display', 'none'); |
| 8393 | return okButton ?? 'Ok'; | 8498 | return okButton ?? t`Ok`; |
| 8394 | } else if (['delete_extension'].includes(popup_type)) { | 8499 | } else if (['delete_extension'].includes(popup_type)) { |
| 8395 | return okButton ?? 'Ok'; | 8500 | return okButton ?? t`Ok`; |
| 8396 | } else if (['new_chat', 'confirm'].includes(popup_type)) { | 8501 | } else if (['new_chat', 'confirm'].includes(popup_type)) { |
| 8397 | return okButton ?? 'Yes'; | 8502 | return okButton ?? t`Yes`; |
| 8398 | } else if (['input'].includes(popup_type)) { | 8503 | } else if (['input'].includes(popup_type)) { |
| 8399 | return okButton ?? t`Save`; | 8504 | return okButton ?? t`Save`; |
| 8400 | } | 8505 | } |
| 8401 | return okButton ?? 'Delete'; | 8506 | return okButton ?? t`Delete`; |
| 8402 | } | 8507 | } |
| 8403 | 8508 | ||
| 8404 | dialogueCloseStop = true; | 8509 | dialogueCloseStop = true; |
| @@ -8565,11 +8670,7 @@ export async function saveChatConditional() { | |||
| 8565 | } | 8670 | } |
| 8566 | 8671 | ||
| 8567 | try { | 8672 | try { |
| 8568 | if (chatSaveTimeout) { | 8673 | cancelDebouncedChatSave(); |
| 8569 | console.debug('Debounced chat save canceled'); | ||
| 8570 | clearTimeout(chatSaveTimeout); | ||
| 8571 | chatSaveTimeout = null; | ||
| 8572 | } | ||
| 8573 | 8674 | ||
| 8574 | isChatSaving = true; | 8675 | isChatSaving = true; |
| 8575 | 8676 | ||
| @@ -9104,7 +9205,7 @@ function formatSwipeCounter(current, total) { | |||
| 9104 | * @param {string} [params.source] The source of the swipe event. | 9205 | * @param {string} [params.source] The source of the swipe event. |
| 9105 | * @param {boolean} [params.repeated] Is the swipe event repeated. | 9206 | * @param {boolean} [params.repeated] Is the swipe event repeated. |
| 9106 | */ | 9207 | */ |
| 9107 | function swipe_left(_event, { source, repeated } = {}) { | 9208 | export function swipe_left(_event, { source, repeated } = {}) { |
| 9108 | if (chat.length - 1 === Number(this_edit_mes_id)) { | 9209 | if (chat.length - 1 === Number(this_edit_mes_id)) { |
| 9109 | closeMessageEditor(); | 9210 | closeMessageEditor(); |
| 9110 | } | 9211 | } |
| @@ -9252,7 +9353,8 @@ function swipe_left(_event, { source, repeated } = {}) { | |||
| 9252 | * @param {string} [params.source] The source of the swipe event. | 9353 | * @param {string} [params.source] The source of the swipe event. |
| 9253 | * @param {boolean} [params.repeated] Is the swipe event repeated. | 9354 | * @param {boolean} [params.repeated] Is the swipe event repeated. |
| 9254 | */ | 9355 | */ |
| 9255 | function swipe_right(_event, { source, repeated } = {}) { | 9356 | //MARK: swipe_right |
| 9357 | export function swipe_right(_event, { source, repeated } = {}) { | ||
| 9256 | if (chat.length - 1 === Number(this_edit_mes_id)) { | 9358 | if (chat.length - 1 === Number(this_edit_mes_id)) { |
| 9257 | closeMessageEditor(); | 9359 | closeMessageEditor(); |
| 9258 | } | 9360 | } |
| @@ -9828,6 +9930,7 @@ export async function doNewChat({ deleteCurrentChat = false } = {}) { | |||
| 9828 | } | 9930 | } |
| 9829 | 9931 | ||
| 9830 | //Fix it; New chat doesn't create while open create character menu | 9932 | //Fix it; New chat doesn't create while open create character menu |
| 9933 | await waitUntilCondition(() => !isChatSaving, debounce_timeout.extended, 10); | ||
| 9831 | await clearChat(); | 9934 | await clearChat(); |
| 9832 | chat.length = 0; | 9935 | chat.length = 0; |
| 9833 | 9936 | ||
| @@ -10060,8 +10163,17 @@ async function removeCharacterFromUI() { | |||
| 10060 | saveSettingsDebounced(); | 10163 | saveSettingsDebounced(); |
| 10061 | } | 10164 | } |
| 10062 | 10165 | ||
| 10063 | async function newAssistantChat() { | 10166 | /** |
| 10167 | * Creates a new assistant chat. | ||
| 10168 | * @param {object} params - Parameters for the new assistant chat | ||
| 10169 | * @param {boolean} [params.temporary=false] I need a temporary secretary | ||
| 10170 | * @returns {Promise<void>} - A promise that resolves when the new assistant chat is created | ||
| 10171 | */ | ||
| 10172 | export async function newAssistantChat({ temporary = false } = {}) { | ||
| 10064 | await clearChat(); | 10173 | await clearChat(); |
| 10174 | if (!temporary) { | ||
| 10175 | return openPermanentAssistantChat(); | ||
| 10176 | } | ||
| 10065 | chat.splice(0, chat.length); | 10177 | chat.splice(0, chat.length); |
| 10066 | chat_metadata = {}; | 10178 | chat_metadata = {}; |
| 10067 | setCharacterName(neutralCharacterName); | 10179 | setCharacterName(neutralCharacterName); |
| @@ -10259,6 +10371,8 @@ API Settings: ${JSON.stringify(getSettingsContents[getSettingsContents.main_api | |||
| 10259 | }); | 10371 | }); |
| 10260 | } | 10372 | } |
| 10261 | 10373 | ||
| 10374 | |||
| 10375 | // MARK: DOM Handlers Start | ||
| 10262 | jQuery(async function () { | 10376 | jQuery(async function () { |
| 10263 | async function doForceSave() { | 10377 | async function doForceSave() { |
| 10264 | await saveSettings(); | 10378 | await saveSettings(); |
| @@ -10374,7 +10488,7 @@ jQuery(async function () { | |||
| 10374 | if (chatId) { | 10488 | if (chatId) { |
| 10375 | return reject('Not in a temporary chat'); | 10489 | return reject('Not in a temporary chat'); |
| 10376 | } | 10490 | } |
| 10377 | await newAssistantChat(); | 10491 | await newAssistantChat({ temporary: true }); |
| 10378 | return resolve(''); | 10492 | return resolve(''); |
| 10379 | }; | 10493 | }; |
| 10380 | eventSource.once(event_types.CHAT_CHANGED, eventCallback); | 10494 | eventSource.once(event_types.CHAT_CHANGED, eventCallback); |
| @@ -11041,6 +11155,9 @@ jQuery(async function () { | |||
| 11041 | }); | 11155 | }); |
| 11042 | 11156 | ||
| 11043 | if (id == 'option_select_chat') { | 11157 | if (id == 'option_select_chat') { |
| 11158 | if (this_chid === undefined && !is_send_press && !selected_group) { | ||
| 11159 | await openPermanentAssistantCard(); | ||
| 11160 | } | ||
| 11044 | if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press) || fromSlashCommand) { | 11161 | if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press) || fromSlashCommand) { |
| 11045 | await displayPastChats(); | 11162 | await displayPastChats(); |
| 11046 | //this is just to avoid the shadow for past chat view when using /delchat | 11163 | //this is just to avoid the shadow for past chat view when using /delchat |
| @@ -11071,7 +11188,7 @@ jQuery(async function () { | |||
| 11071 | await doNewChat({ deleteCurrentChat: deleteCurrentChat }); | 11188 | await doNewChat({ deleteCurrentChat: deleteCurrentChat }); |
| 11072 | } | 11189 | } |
| 11073 | if (!selected_group && this_chid === undefined && !is_send_press) { | 11190 | if (!selected_group && this_chid === undefined && !is_send_press) { |
| 11074 | await newAssistantChat(); | 11191 | await newAssistantChat({ temporary: true }); |
| 11075 | } | 11192 | } |
| 11076 | } | 11193 | } |
| 11077 | 11194 | ||
| @@ -11112,6 +11229,7 @@ jQuery(async function () { | |||
| 11112 | 11229 | ||
| 11113 | else if (id == 'option_close_chat') { | 11230 | else if (id == 'option_close_chat') { |
| 11114 | if (is_send_press == false) { | 11231 | if (is_send_press == false) { |
| 11232 | await waitUntilCondition(() => !isChatSaving, debounce_timeout.extended, 10); | ||
| 11115 | await clearChat(); | 11233 | await clearChat(); |
| 11116 | chat.length = 0; | 11234 | chat.length = 0; |
| 11117 | resetSelectedGroup(); | 11235 | resetSelectedGroup(); |
| @@ -11124,12 +11242,9 @@ jQuery(async function () { | |||
| 11124 | selected_button = 'characters'; | 11242 | selected_button = 'characters'; |
| 11125 | $('#rm_button_selected_ch').children('h2').text(''); | 11243 | $('#rm_button_selected_ch').children('h2').text(''); |
| 11126 | select_rm_characters(); | 11244 | select_rm_characters(); |
| 11127 | sendSystemMessage(system_message_types.WELCOME); | ||
| 11128 | sendSystemMessage(system_message_types.WELCOME_PROMPT); | ||
| 11129 | await getClientVersion(); | ||
| 11130 | await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId()); | 11245 | await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId()); |
| 11131 | } else { | 11246 | } else { |
| 11132 | toastr.info('Please stop the message generation first.'); | 11247 | toastr.info(t`Please stop the message generation first.`); |
| 11133 | } | 11248 | } |
| 11134 | } | 11249 | } |
| 11135 | 11250 | ||
| @@ -11197,6 +11312,7 @@ jQuery(async function () { | |||
| 11197 | $(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); | 11312 | $(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); |
| 11198 | $(`.mes[mesid="${this_del_mes}"]`).remove(); | 11313 | $(`.mes[mesid="${this_del_mes}"]`).remove(); |
| 11199 | chat.length = this_del_mes; | 11314 | chat.length = this_del_mes; |
| 11315 | chat_metadata['tainted'] = true; | ||
| 11200 | await saveChatConditional(); | 11316 | await saveChatConditional(); |
| 11201 | chatElement.scrollTop(chatElement[0].scrollHeight); | 11317 | chatElement.scrollTop(chatElement[0].scrollHeight); |
| 11202 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); | 11318 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| @@ -11636,6 +11752,7 @@ jQuery(async function () { | |||
| 11636 | let startFromZero = Number(this_edit_mes_id) === 0; | 11752 | let startFromZero = Number(this_edit_mes_id) === 0; |
| 11637 | 11753 | ||
| 11638 | this_edit_mes_id = undefined; | 11754 | this_edit_mes_id = undefined; |
| 11755 | chat_metadata['tainted'] = true; | ||
| 11639 | 11756 | ||
| 11640 | updateViewMessageIds(startFromZero); | 11757 | updateViewMessageIds(startFromZero); |
| 11641 | saveChatDebounced(); | 11758 | saveChatDebounced(); |
| @@ -12056,7 +12173,7 @@ jQuery(async function () { | |||
| 12056 | ); | 12173 | ); |
| 12057 | break;*/ | 12174 | break;*/ |
| 12058 | default: | 12175 | default: |
| 12059 | await eventSource.emit('charManagementDropdown', target); | 12176 | await eventSource.emit(event_types.CHARACTER_MANAGEMENT_DROPDOWN, target); |
| 12060 | } | 12177 | } |
| 12061 | $('#char-management-dropdown').prop('selectedIndex', 0); | 12178 | $('#char-management-dropdown').prop('selectedIndex', 0); |
| 12062 | }); | 12179 | }); |
| @@ -12224,8 +12341,6 @@ jQuery(async function () { | |||
| 12224 | // Added here to prevent execution before script.js is loaded and get rid of quirky timeouts | 12341 | // Added here to prevent execution before script.js is loaded and get rid of quirky timeouts |
| 12225 | await firstLoadInit(); | 12342 | await firstLoadInit(); |
| 12226 | 12343 | ||
| 12227 | addDebugFunctions(); | ||
| 12228 | |||
| 12229 | eventSource.on(event_types.CHAT_DELETED, async (name) => { | 12344 | eventSource.on(event_types.CHAT_DELETED, async (name) => { |
| 12230 | await deleteItemizedPrompts(name); | 12345 | await deleteItemizedPrompts(name); |
| 12231 | }); | 12346 | }); |
| @@ -12233,8 +12348,6 @@ jQuery(async function () { | |||
| 12233 | await deleteItemizedPrompts(name); | 12348 | await deleteItemizedPrompts(name); |
| 12234 | }); | 12349 | }); |
| 12235 | 12350 | ||
| 12236 | initCustomSelectedSamplers(); | ||
| 12237 | |||
| 12238 | window.addEventListener('beforeunload', (e) => { | 12351 | window.addEventListener('beforeunload', (e) => { |
| 12239 | if (isChatSaving) { | 12352 | if (isChatSaving) { |
| 12240 | e.preventDefault(); | 12353 | e.preventDefault(); |
| @@ -77,7 +77,7 @@ const registerPromptManagerMigration = () => { | |||
| 77 | * Represents a prompt. | 77 | * Represents a prompt. |
| 78 | */ | 78 | */ |
| 79 | class Prompt { | 79 | class Prompt { |
| 80 | identifier; role; content; name; system_prompt; position; injection_position; injection_depth; forbid_overrides; extension; | 80 | identifier; role; content; name; system_prompt; position; injection_position; injection_depth; injection_order; forbid_overrides; extension; |
| 81 | 81 | ||
| 82 | /** | 82 | /** |
| 83 | * Create a new Prompt instance. | 83 | * Create a new Prompt instance. |
| @@ -86,15 +86,16 @@ class Prompt { | |||
| 86 | * @param {string} param0.identifier - The unique identifier of the prompt. | 86 | * @param {string} param0.identifier - The unique identifier of the prompt. |
| 87 | * @param {string} param0.role - The role associated with the prompt. | 87 | * @param {string} param0.role - The role associated with the prompt. |
| 88 | * @param {string} param0.content - The content of the prompt. | 88 | * @param {string} param0.content - The content of the prompt. |
| 89 | * @param {string} param0.name - The name of the prompt. | 89 | * @param {string} [param0.name] - The name of the prompt. |
| 90 | * @param {boolean} param0.system_prompt - Indicates if the prompt is a system prompt. | 90 | * @param {boolean} [param0.system_prompt] - Indicates if the prompt is a system prompt. |
| 91 | * @param {string} param0.position - The position of the prompt in the prompt list. | 91 | * @param {string} [param0.position] - The position of the prompt in the prompt list. |
| 92 | * @param {number} param0.injection_position - The insert position of the prompt. | 92 | * @param {number} [param0.injection_position] - The insert position of the prompt. |
| 93 | * @param {number} param0.injection_depth - The depth of the prompt in the chat. | 93 | * @param {number} [param0.injection_depth] - The depth of the prompt in the chat. |
| 94 | * @param {boolean} param0.forbid_overrides - Indicates if the prompt should not be overridden. | 94 | * @param {number} [param0.injection_order] - The order of the prompt in the chat. |
| 95 | * @param {boolean} param0.extension - Prompt is added by an extension. | 95 | * @param {boolean} [param0.forbid_overrides] - Indicates if the prompt should not be overridden. |
| 96 | */ | 96 | * @param {boolean} [param0.extension] - Prompt is added by an extension. |
| 97 | constructor({ identifier, role, content, name, system_prompt, position, injection_depth, injection_position, forbid_overrides, extension } = {}) { | 97 | */ |
| 98 | constructor({ identifier, role, content, name, system_prompt, position, injection_depth, injection_position, forbid_overrides, extension, injection_order } = {}) { | ||
| 98 | this.identifier = identifier; | 99 | this.identifier = identifier; |
| 99 | this.role = role; | 100 | this.role = role; |
| 100 | this.content = content; | 101 | this.content = content; |
| @@ -105,6 +106,7 @@ class Prompt { | |||
| 105 | this.injection_position = injection_position; | 106 | this.injection_position = injection_position; |
| 106 | this.forbid_overrides = forbid_overrides; | 107 | this.forbid_overrides = forbid_overrides; |
| 107 | this.extension = extension ?? false; | 108 | this.extension = extension ?? false; |
| 109 | this.injection_order = injection_order ?? 100; | ||
| 108 | } | 110 | } |
| 109 | } | 111 | } |
| 110 | 112 | ||
| @@ -196,6 +198,17 @@ export class PromptCollection { | |||
| 196 | } | 198 | } |
| 197 | 199 | ||
| 198 | class PromptManager { | 200 | class PromptManager { |
| 201 | get promptSources() { | ||
| 202 | return { | ||
| 203 | charDescription: t`Character Description`, | ||
| 204 | charPersonality: t`Character Personality`, | ||
| 205 | scenario: t`Character Scenario`, | ||
| 206 | personaDescription: t`Persona Description`, | ||
| 207 | worldInfoBefore: t`World Info (↑Char)`, | ||
| 208 | worldInfoAfter: t`World Info (↓Char)`, | ||
| 209 | }; | ||
| 210 | } | ||
| 211 | |||
| 199 | constructor() { | 212 | constructor() { |
| 200 | this.systemPrompts = [ | 213 | this.systemPrompts = [ |
| 201 | 'main', | 214 | 'main', |
| @@ -408,6 +421,7 @@ class PromptManager { | |||
| 408 | this.handleResetPrompt = (event) => { | 421 | this.handleResetPrompt = (event) => { |
| 409 | const promptId = event.target.dataset.pmPrompt; | 422 | const promptId = event.target.dataset.pmPrompt; |
| 410 | const prompt = this.getPromptById(promptId); | 423 | const prompt = this.getPromptById(promptId); |
| 424 | const isPulledPrompt = Object.keys(this.promptSources).includes(promptId); | ||
| 411 | 425 | ||
| 412 | switch (promptId) { | 426 | switch (promptId) { |
| 413 | case 'main': | 427 | case 'main': |
| @@ -435,10 +449,18 @@ class PromptManager { | |||
| 435 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value = prompt.content ?? ''; | 449 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value = prompt.content ?? ''; |
| 436 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value = prompt.injection_position ?? 0; | 450 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value = prompt.injection_position ?? 0; |
| 437 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value = prompt.injection_depth ?? DEFAULT_DEPTH; | 451 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value = prompt.injection_depth ?? DEFAULT_DEPTH; |
| 452 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_order').value = prompt.injection_order ?? 100; | ||
| 438 | document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block').style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; | 453 | document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block').style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; |
| 454 | document.getElementById(this.configuration.prefix + 'prompt_manager_order_block').style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; | ||
| 439 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides').checked = prompt.forbid_overrides ?? false; | 455 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides').checked = prompt.forbid_overrides ?? false; |
| 440 | document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block').style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden'; | 456 | document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block').style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden'; |
| 441 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').disabled = prompt.marker ?? false; | 457 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').disabled = prompt.marker ?? false; |
| 458 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block').style.display = isPulledPrompt ? '' : 'none'; | ||
| 459 | |||
| 460 | if (isPulledPrompt) { | ||
| 461 | const sourceName = this.promptSources[promptId]; | ||
| 462 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source').textContent = sourceName; | ||
| 463 | } | ||
| 442 | 464 | ||
| 443 | if (!this.systemPrompts.includes(promptId)) { | 465 | if (!this.systemPrompts.includes(promptId)) { |
| 444 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').removeAttribute('disabled'); | 466 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').removeAttribute('disabled'); |
| @@ -672,6 +694,7 @@ class PromptManager { | |||
| 672 | // Clear forms on closing the popup | 694 | // Clear forms on closing the popup |
| 673 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_close').addEventListener('click', closeAndClearPopup); | 695 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_close').addEventListener('click', closeAndClearPopup); |
| 674 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_close_button').addEventListener('click', closeAndClearPopup); | 696 | document.getElementById(this.configuration.prefix + 'prompt_manager_popup_close_button').addEventListener('click', closeAndClearPopup); |
| 697 | closeAndClearPopup(); | ||
| 675 | 698 | ||
| 676 | // Re-render prompt manager on openai preset change | 699 | // Re-render prompt manager on openai preset change |
| 677 | eventSource.on(event_types.OAI_PRESET_CHANGED_AFTER, () => { | 700 | eventSource.on(event_types.OAI_PRESET_CHANGED_AFTER, () => { |
| @@ -764,6 +787,7 @@ class PromptManager { | |||
| 764 | prompt.content = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value; | 787 | prompt.content = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value; |
| 765 | prompt.injection_position = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value); | 788 | prompt.injection_position = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value); |
| 766 | prompt.injection_depth = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value); | 789 | prompt.injection_depth = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value); |
| 790 | prompt.injection_order = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_order').value); | ||
| 767 | prompt.forbid_overrides = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides').checked; | 791 | prompt.forbid_overrides = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides').checked; |
| 768 | } | 792 | } |
| 769 | 793 | ||
| @@ -1204,9 +1228,14 @@ class PromptManager { | |||
| 1204 | const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt'); | 1228 | const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt'); |
| 1205 | const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position'); | 1229 | const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position'); |
| 1206 | const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth'); | 1230 | const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth'); |
| 1231 | const injectionOrderField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_order'); | ||
| 1207 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); | 1232 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); |
| 1233 | const injectionOrderBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_order_block'); | ||
| 1208 | const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides'); | 1234 | const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides'); |
| 1209 | const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block'); | 1235 | const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block'); |
| 1236 | const entrySourceBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block'); | ||
| 1237 | const entrySource = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source'); | ||
| 1238 | const isPulledPrompt = Object.keys(this.promptSources).includes(prompt.identifier); | ||
| 1210 | 1239 | ||
| 1211 | nameField.value = prompt.name ?? ''; | 1240 | nameField.value = prompt.name ?? ''; |
| 1212 | roleField.value = prompt.role || 'system'; | 1241 | roleField.value = prompt.role || 'system'; |
| @@ -1214,10 +1243,18 @@ class PromptManager { | |||
| 1214 | promptField.disabled = prompt.marker ?? false; | 1243 | promptField.disabled = prompt.marker ?? false; |
| 1215 | injectionPositionField.value = prompt.injection_position ?? INJECTION_POSITION.RELATIVE; | 1244 | injectionPositionField.value = prompt.injection_position ?? INJECTION_POSITION.RELATIVE; |
| 1216 | injectionDepthField.value = prompt.injection_depth ?? DEFAULT_DEPTH; | 1245 | injectionDepthField.value = prompt.injection_depth ?? DEFAULT_DEPTH; |
| 1246 | injectionOrderField.value = prompt.injection_order ?? 100; | ||
| 1217 | injectionDepthBlock.style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; | 1247 | injectionDepthBlock.style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; |
| 1248 | injectionOrderBlock.style.visibility = prompt.injection_position === INJECTION_POSITION.ABSOLUTE ? 'visible' : 'hidden'; | ||
| 1218 | injectionPositionField.removeAttribute('disabled'); | 1249 | injectionPositionField.removeAttribute('disabled'); |
| 1219 | forbidOverridesField.checked = prompt.forbid_overrides ?? false; | 1250 | forbidOverridesField.checked = prompt.forbid_overrides ?? false; |
| 1220 | forbidOverridesBlock.style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden'; | 1251 | forbidOverridesBlock.style.visibility = this.overridablePrompts.includes(prompt.identifier) ? 'visible' : 'hidden'; |
| 1252 | entrySourceBlock.style.display = isPulledPrompt ? '' : 'none'; | ||
| 1253 | |||
| 1254 | if (isPulledPrompt) { | ||
| 1255 | const sourceName = this.promptSources[prompt.identifier]; | ||
| 1256 | entrySource.textContent = sourceName; | ||
| 1257 | } | ||
| 1221 | 1258 | ||
| 1222 | if (this.systemPrompts.includes(prompt.identifier)) { | 1259 | if (this.systemPrompts.includes(prompt.identifier)) { |
| 1223 | injectionPositionField.setAttribute('disabled', 'disabled'); | 1260 | injectionPositionField.setAttribute('disabled', 'disabled'); |
| @@ -1240,11 +1277,14 @@ class PromptManager { | |||
| 1240 | 1277 | ||
| 1241 | handleInjectionPositionChange(event) { | 1278 | handleInjectionPositionChange(event) { |
| 1242 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); | 1279 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); |
| 1280 | const injectionOrderBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_order_block'); | ||
| 1243 | const injectionPosition = Number(event.target.value); | 1281 | const injectionPosition = Number(event.target.value); |
| 1244 | if (injectionPosition === INJECTION_POSITION.ABSOLUTE) { | 1282 | if (injectionPosition === INJECTION_POSITION.ABSOLUTE) { |
| 1245 | injectionDepthBlock.style.visibility = 'visible'; | 1283 | injectionDepthBlock.style.visibility = 'visible'; |
| 1284 | injectionOrderBlock.style.visibility = 'visible'; | ||
| 1246 | } else { | 1285 | } else { |
| 1247 | injectionDepthBlock.style.visibility = 'hidden'; | 1286 | injectionDepthBlock.style.visibility = 'hidden'; |
| 1287 | injectionOrderBlock.style.visibility = 'hidden'; | ||
| 1248 | } | 1288 | } |
| 1249 | } | 1289 | } |
| 1250 | 1290 | ||
| @@ -1301,8 +1341,11 @@ class PromptManager { | |||
| 1301 | const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position'); | 1341 | const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position'); |
| 1302 | const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth'); | 1342 | const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth'); |
| 1303 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); | 1343 | const injectionDepthBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_depth_block'); |
| 1344 | const injectionOrderBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_order_block'); | ||
| 1304 | const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides'); | 1345 | const forbidOverridesField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_forbid_overrides'); |
| 1305 | const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block'); | 1346 | const forbidOverridesBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_forbid_overrides_block'); |
| 1347 | const entrySourceBlock = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source_block'); | ||
| 1348 | const entrySource = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_source'); | ||
| 1306 | 1349 | ||
| 1307 | nameField.value = ''; | 1350 | nameField.value = ''; |
| 1308 | roleField.selectedIndex = 0; | 1351 | roleField.selectedIndex = 0; |
| @@ -1312,8 +1355,11 @@ class PromptManager { | |||
| 1312 | injectionPositionField.removeAttribute('disabled'); | 1355 | injectionPositionField.removeAttribute('disabled'); |
| 1313 | injectionDepthField.value = DEFAULT_DEPTH; | 1356 | injectionDepthField.value = DEFAULT_DEPTH; |
| 1314 | injectionDepthBlock.style.visibility = 'unset'; | 1357 | injectionDepthBlock.style.visibility = 'unset'; |
| 1358 | injectionOrderBlock.style.visibility = 'unset'; | ||
| 1315 | forbidOverridesBlock.style.visibility = 'unset'; | 1359 | forbidOverridesBlock.style.visibility = 'unset'; |
| 1316 | forbidOverridesField.checked = false; | 1360 | forbidOverridesField.checked = false; |
| 1361 | entrySourceBlock.style.display = 'none'; | ||
| 1362 | entrySource.textContent = ''; | ||
| 1317 | 1363 | ||
| 1318 | roleField.disabled = false; | 1364 | roleField.disabled = false; |
| 1319 | } | 1365 | } |
| @@ -402,6 +402,7 @@ function RA_autoconnect(PrevApi) { | |||
| 402 | || (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) | 402 | || (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) |
| 403 | || (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21) | 403 | || (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21) |
| 404 | || (secret_state[SECRET_KEYS.MAKERSUITE] && oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) | 404 | || (secret_state[SECRET_KEYS.MAKERSUITE] && oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) |
| 405 | || (secret_state[SECRET_KEYS.VERTEXAI] && oai_settings.chat_completion_source == chat_completion_sources.VERTEXAI) | ||
| 405 | || (secret_state[SECRET_KEYS.MISTRALAI] && oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI) | 406 | || (secret_state[SECRET_KEYS.MISTRALAI] && oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI) |
| 406 | || (secret_state[SECRET_KEYS.COHERE] && oai_settings.chat_completion_source == chat_completion_sources.COHERE) | 407 | || (secret_state[SECRET_KEYS.COHERE] && oai_settings.chat_completion_source == chat_completion_sources.COHERE) |
| 407 | || (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) | 408 | || (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) |
| @@ -410,6 +411,7 @@ function RA_autoconnect(PrevApi) { | |||
| 410 | || (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) | 411 | || (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) |
| 411 | || (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) | 412 | || (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) |
| 412 | || (secret_state[SECRET_KEYS.XAI] && oai_settings.chat_completion_source == chat_completion_sources.XAI) | 413 | || (secret_state[SECRET_KEYS.XAI] && oai_settings.chat_completion_source == chat_completion_sources.XAI) |
| 414 | || (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS) | ||
| 413 | || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) | 415 | || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) |
| 414 | ) { | 416 | ) { |
| 415 | $('#api_button_openai').trigger('click'); | 417 | $('#api_button_openai').trigger('click'); |
| @@ -1048,7 +1050,7 @@ export function initRossMods() { | |||
| 1048 | //Enter to send when send_textarea in focus | 1050 | //Enter to send when send_textarea in focus |
| 1049 | if (document.activeElement == hotkeyTargets['send_textarea']) { | 1051 | if (document.activeElement == hotkeyTargets['send_textarea']) { |
| 1050 | const sendOnEnter = shouldSendOnEnter(); | 1052 | const sendOnEnter = shouldSendOnEnter(); |
| 1051 | if (!event.shiftKey && !event.ctrlKey && !event.altKey && event.key == 'Enter' && sendOnEnter) { | 1053 | if (!event.isComposing && !event.shiftKey && !event.ctrlKey && !event.altKey && event.key == 'Enter' && sendOnEnter) { |
| 1052 | event.preventDefault(); | 1054 | event.preventDefault(); |
| 1053 | sendTextareaMessage(); | 1055 | sendTextareaMessage(); |
| 1054 | return; | 1056 | return; |
| @@ -1120,7 +1122,7 @@ export function initRossMods() { | |||
| 1120 | const result = await Popup.show.confirm('Regenerate Message', 'Are you sure you want to regenerate the latest message?', { | 1122 | const result = await Popup.show.confirm('Regenerate Message', 'Are you sure you want to regenerate the latest message?', { |
| 1121 | customInputs: [{ id: 'regenerateWithCtrlEnter', label: 'Don\'t ask again' }], | 1123 | customInputs: [{ id: 'regenerateWithCtrlEnter', label: 'Don\'t ask again' }], |
| 1122 | onClose: (popup) => { | 1124 | onClose: (popup) => { |
| 1123 | regenerateWithCtrlEnter = popup.inputResults.get('regenerateWithCtrlEnter') ?? false; | 1125 | regenerateWithCtrlEnter = Boolean(popup.inputResults.get('regenerateWithCtrlEnter') ?? false); |
| 1124 | }, | 1126 | }, |
| 1125 | }); | 1127 | }); |
| 1126 | if (!result) { | 1128 | if (!result) { |
| @@ -1,11 +1,12 @@ | |||
| 1 | import { Fuse } from '../lib.js'; | 1 | import { Fuse } from '../lib.js'; |
| 2 | 2 | ||
| 3 | import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl, saveSettingsDebounced } from '../script.js'; | 3 | import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl, saveSettingsDebounced } from '../script.js'; |
| 4 | import { saveMetadataDebounced } from './extensions.js'; | 4 | import { openThirdPartyExtensionMenu, saveMetadataDebounced } from './extensions.js'; |
| 5 | import { SlashCommand } from './slash-commands/SlashCommand.js'; | 5 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 6 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; | 6 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 7 | import { flashHighlight, stringFormat } from './utils.js'; | 7 | import { flashHighlight, stringFormat } from './utils.js'; |
| 8 | import { t } from './i18n.js'; | 8 | import { t } from './i18n.js'; |
| 9 | import { Popup } from './popup.js'; | ||
| 9 | 10 | ||
| 10 | const BG_METADATA_KEY = 'custom_background'; | 11 | const BG_METADATA_KEY = 'custom_background'; |
| 11 | const LIST_METADATA_KEY = 'chat_backgrounds'; | 12 | const LIST_METADATA_KEY = 'chat_backgrounds'; |
| @@ -77,7 +78,7 @@ function getChatBackgroundsList() { | |||
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | function getBackgroundPath(fileUrl) { | 80 | function getBackgroundPath(fileUrl) { |
| 80 | return `backgrounds/${fileUrl}`; | 81 | return `backgrounds/${encodeURIComponent(fileUrl)}`; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | function highlightLockedBackground() { | 84 | function highlightLockedBackground() { |
| @@ -217,7 +218,7 @@ async function onCopyToSystemBackgroundClick(e) { | |||
| 217 | const formData = new FormData(); | 218 | const formData = new FormData(); |
| 218 | formData.set('avatar', file); | 219 | formData.set('avatar', file); |
| 219 | 220 | ||
| 220 | uploadBackground(formData); | 221 | await uploadBackground(formData); |
| 221 | 222 | ||
| 222 | const list = chat_metadata[LIST_METADATA_KEY] || []; | 223 | const list = chat_metadata[LIST_METADATA_KEY] || []; |
| 223 | const index = list.indexOf(bgNames.oldBg); | 224 | const index = list.indexOf(bgNames.oldBg); |
| @@ -291,7 +292,7 @@ async function onDeleteBackgroundClick(e) { | |||
| 291 | const bgToDelete = $(this).closest('.bg_example'); | 292 | const bgToDelete = $(this).closest('.bg_example'); |
| 292 | const url = bgToDelete.data('url'); | 293 | const url = bgToDelete.data('url'); |
| 293 | const isCustom = bgToDelete.attr('custom') === 'true'; | 294 | const isCustom = bgToDelete.attr('custom') === 'true'; |
| 294 | const confirm = await callPopup('<h3>Delete the background?</h3>', 'confirm'); | 295 | const confirm = await Popup.show.confirm(t`Delete the background?`, null); |
| 295 | const bg = bgToDelete.attr('bgfile'); | 296 | const bg = bgToDelete.attr('bgfile'); |
| 296 | 297 | ||
| 297 | if (confirm) { | 298 | if (confirm) { |
| @@ -438,7 +439,7 @@ async function delBackground(bg) { | |||
| 438 | }); | 439 | }); |
| 439 | } | 440 | } |
| 440 | 441 | ||
| 441 | function onBackgroundUploadSelected() { | 442 | async function onBackgroundUploadSelected() { |
| 442 | const form = $('#form_bg_download').get(0); | 443 | const form = $('#form_bg_download').get(0); |
| 443 | 444 | ||
| 444 | if (!(form instanceof HTMLFormElement)) { | 445 | if (!(form instanceof HTMLFormElement)) { |
| @@ -447,34 +448,82 @@ function onBackgroundUploadSelected() { | |||
| 447 | } | 448 | } |
| 448 | 449 | ||
| 449 | const formData = new FormData(form); | 450 | const formData = new FormData(form); |
| 450 | uploadBackground(formData); | 451 | await convertFileIfVideo(formData); |
| 452 | await uploadBackground(formData); | ||
| 451 | form.reset(); | 453 | form.reset(); |
| 452 | } | 454 | } |
| 453 | 455 | ||
| 454 | /** | 456 | /** |
| 457 | * Converts a video file to an animated webp format if the file is a video. | ||
| 458 | * @param {FormData} formData | ||
| 459 | * @returns {Promise<void>} | ||
| 460 | */ | ||
| 461 | async function convertFileIfVideo(formData) { | ||
| 462 | const file = formData.get('avatar'); | ||
| 463 | if (!(file instanceof File)) { | ||
| 464 | return; | ||
| 465 | } | ||
| 466 | if (!file.type.startsWith('video/')) { | ||
| 467 | return; | ||
| 468 | } | ||
| 469 | if (typeof globalThis.convertVideoToAnimatedWebp !== 'function') { | ||
| 470 | toastr.warning(t`Click here to install the Video Background Loader extension`, t`Video background uploads require a downloadable add-on`, { | ||
| 471 | timeOut: 0, | ||
| 472 | extendedTimeOut: 0, | ||
| 473 | onclick: () => openThirdPartyExtensionMenu('https://github.com/SillyTavern/Extension-VideoBackgroundLoader'), | ||
| 474 | }); | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | |||
| 478 | let toastMessage = jQuery(); | ||
| 479 | try { | ||
| 480 | toastMessage = toastr.info(t`Preparing video for upload. This may take several minutes.`, t`Please wait`, { timeOut: 0, extendedTimeOut: 0 }); | ||
| 481 | const sourceBuffer = await file.arrayBuffer(); | ||
| 482 | const convertedBuffer = await globalThis.convertVideoToAnimatedWebp({ buffer: new Uint8Array(sourceBuffer), name: file.name }); | ||
| 483 | const convertedFileName = file.name.replace(/\.[^/.]+$/, '.webp'); | ||
| 484 | const convertedFile = new File([convertedBuffer], convertedFileName, { type: 'image/webp' }); | ||
| 485 | formData.set('avatar', convertedFile); | ||
| 486 | toastMessage.remove(); | ||
| 487 | } catch (error) { | ||
| 488 | formData.delete('avatar'); | ||
| 489 | toastMessage.remove(); | ||
| 490 | console.error('Error converting video to animated webp:', error); | ||
| 491 | toastr.error(t`Error converting video to animated webp`); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | /** | ||
| 455 | * Uploads a background to the server | 496 | * Uploads a background to the server |
| 456 | * @param {FormData} formData | 497 | * @param {FormData} formData |
| 457 | */ | 498 | */ |
| 458 | function uploadBackground(formData) { | 499 | async function uploadBackground(formData) { |
| 459 | jQuery.ajax({ | 500 | try { |
| 460 | type: 'POST', | 501 | if (!formData.has('avatar')) { |
| 461 | url: '/api/backgrounds/upload', | 502 | console.log('No file provided. Background upload cancelled.'); |
| 462 | data: formData, | 503 | return; |
| 463 | beforeSend: function () { | 504 | } |
| 464 | }, | 505 | |
| 465 | cache: false, | 506 | const headers = getRequestHeaders(); |
| 466 | contentType: false, | 507 | delete headers['Content-Type']; |
| 467 | processData: false, | 508 | |
| 468 | success: async function (bg) { | 509 | const response = await fetch('/api/backgrounds/upload', { |
| 510 | method: 'POST', | ||
| 511 | headers: headers, | ||
| 512 | body: formData, | ||
| 513 | cache: 'no-cache', | ||
| 514 | }); | ||
| 515 | |||
| 516 | if (!response.ok) { | ||
| 517 | throw new Error('Failed to upload background'); | ||
| 518 | } | ||
| 519 | |||
| 520 | const bg = await response.text(); | ||
| 469 | setBackground(bg, generateUrlParameter(bg, false)); | 521 | setBackground(bg, generateUrlParameter(bg, false)); |
| 470 | await getBackgrounds(); | 522 | await getBackgrounds(); |
| 471 | highlightNewBackground(bg); | 523 | highlightNewBackground(bg); |
| 472 | }, | 524 | } catch (error) { |
| 473 | error: function (jqXHR, exception) { | 525 | console.error('Error uploading background:', error); |
| 474 | console.log(exception); | 526 | } |
| 475 | console.log(jqXHR); | ||
| 476 | }, | ||
| 477 | }); | ||
| 478 | } | 527 | } |
| 479 | 528 | ||
| 480 | /** | 529 | /** |
| @@ -33,6 +33,12 @@ | |||
| 33 | * @property {number} role - The specific function or purpose of the extension. | 33 | * @property {number} role - The specific function or purpose of the extension. |
| 34 | * @property {boolean} vectorized - Indicates if the extension is optimized for vectorized processing. | 34 | * @property {boolean} vectorized - Indicates if the extension is optimized for vectorized processing. |
| 35 | * @property {number} display_index - The order in which the extension should be displayed for user interfaces. | 35 | * @property {number} display_index - The order in which the extension should be displayed for user interfaces. |
| 36 | * @property {boolean} match_persona_description - Wether to match against the persona description. | ||
| 37 | * @property {boolean} match_character_description - Wether to match against the persona description. | ||
| 38 | * @property {boolean} match_character_personality - Wether to match against the character personality. | ||
| 39 | * @property {boolean} match_character_depth_prompt - Wether to match against the character depth prompt. | ||
| 40 | * @property {boolean} match_scenario - Wether to match against the character scenario. | ||
| 41 | * @property {boolean} match_creator_notes - Wether to match against the character creator notes. | ||
| 36 | */ | 42 | */ |
| 37 | 43 | ||
| 38 | /** | 44 | /** |
| @@ -24,17 +24,21 @@ const hash_derivations = { | |||
| 24 | // Mistral-Large-Instruct-2407 | 24 | // Mistral-Large-Instruct-2407 |
| 25 | 'Mistral V2 & V3' | 25 | 'Mistral V2 & V3' |
| 26 | , | 26 | , |
| 27 | '3c4ad5fa60dd8c7ccdf82fa4225864c903e107728fcaf859fa6052cb80c92ee9': | 27 | '26a59556925c987317ce5291811ba3b7f32ec4c647c400c6cc7e3a9993007ba7': |
| 28 | // Mistral-Large-Instruct-2411 | 28 | // Mistral-7B-Instruct-v0.3 |
| 29 | 'Mistral V7' // https://huggingface.co/mistralai/Mistral-Large-Instruct-2411 | 29 | 'Mistral V2 & V3' |
| 30 | , | 30 | , |
| 31 | 'e4676cb56dffea7782fd3e2b577cfaf1e123537e6ef49b3ec7caa6c095c62272': | 31 | 'e4676cb56dffea7782fd3e2b577cfaf1e123537e6ef49b3ec7caa6c095c62272': |
| 32 | // Mistral-Nemo-Instruct-2407 | 32 | // Mistral-Nemo-Instruct-2407 |
| 33 | 'Mistral V3-Tekken' | 33 | 'Mistral V3-Tekken' |
| 34 | , | 34 | , |
| 35 | '26a59556925c987317ce5291811ba3b7f32ec4c647c400c6cc7e3a9993007ba7': | 35 | '3c4ad5fa60dd8c7ccdf82fa4225864c903e107728fcaf859fa6052cb80c92ee9': |
| 36 | // Mistral-7B-Instruct-v0.3 | 36 | // Mistral-Large-Instruct-2411 |
| 37 | 'Mistral V2 & V3' | 37 | 'Mistral V7' |
| 38 | , | ||
| 39 | '3934d199bfe5b6fab5cba1b5f8ee475e8d5738ac315f21cb09545b4e665cc005': | ||
| 40 | // Mistral Small 24B | ||
| 41 | 'Mistral V7' | ||
| 38 | , | 42 | , |
| 39 | 43 | ||
| 40 | // Gemma | 44 | // Gemma |
| @@ -74,6 +78,11 @@ const hash_derivations = { | |||
| 74 | 'b6835114b7303ddd78919a82e4d9f7d8c26ed0d7dfc36beeb12d524f6144eab1': | 78 | 'b6835114b7303ddd78919a82e4d9f7d8c26ed0d7dfc36beeb12d524f6144eab1': |
| 75 | 'DeepSeek-V2.5' | 79 | 'DeepSeek-V2.5' |
| 76 | , | 80 | , |
| 81 | |||
| 82 | // THUDM-GLM 4 | ||
| 83 | '854b703e44ca06bdb196cc471c728d15dbab61e744fe6cdce980086b61646ed1': | ||
| 84 | 'GLM-4' | ||
| 85 | , | ||
| 77 | }; | 86 | }; |
| 78 | 87 | ||
| 79 | const substr_derivations = { | 88 | const substr_derivations = { |
| @@ -1,6 +1,6 @@ | |||
| 1 | // Move chat functions here from script.js (eventually) | 1 | // Move chat functions here from script.js (eventually) |
| 2 | 2 | ||
| 3 | import { Popper, css } from '../lib.js'; | 3 | import { Popper, css, DOMPurify } from '../lib.js'; |
| 4 | import { | 4 | import { |
| 5 | addCopyToCodeBlocks, | 5 | addCopyToCodeBlocks, |
| 6 | appendMediaToMessage, | 6 | appendMediaToMessage, |
| @@ -23,6 +23,11 @@ import { | |||
| 23 | neutralCharacterName, | 23 | neutralCharacterName, |
| 24 | updateChatMetadata, | 24 | updateChatMetadata, |
| 25 | system_message_types, | 25 | system_message_types, |
| 26 | converter, | ||
| 27 | substituteParams, | ||
| 28 | getSystemMessageByType, | ||
| 29 | printMessages, | ||
| 30 | clearChat, | ||
| 26 | } from '../script.js'; | 31 | } from '../script.js'; |
| 27 | import { selected_group } from './group-chats.js'; | 32 | import { selected_group } from './group-chats.js'; |
| 28 | import { power_user } from './power-user.js'; | 33 | import { power_user } from './power-user.js'; |
| @@ -37,6 +42,7 @@ import { | |||
| 37 | saveBase64AsFile, | 42 | saveBase64AsFile, |
| 38 | extractTextFromOffice, | 43 | extractTextFromOffice, |
| 39 | download, | 44 | download, |
| 45 | getFileText, | ||
| 40 | } from './utils.js'; | 46 | } from './utils.js'; |
| 41 | import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js'; | 47 | import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js'; |
| 42 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; | 48 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; |
| @@ -347,11 +353,14 @@ async function onFileAttach(file) { | |||
| 347 | $('#file_form .file_size').text(humanFileSize(file.size)); | 353 | $('#file_form .file_size').text(humanFileSize(file.size)); |
| 348 | $('#file_form').removeClass('displayNone'); | 354 | $('#file_form').removeClass('displayNone'); |
| 349 | 355 | ||
| 350 | // Reset form on chat change | 356 | // Reset form on chat change (if not on a welcome screen) |
| 357 | const currentChatId = getCurrentChatId(); | ||
| 358 | if (currentChatId) { | ||
| 351 | eventSource.once(event_types.CHAT_CHANGED, () => { | 359 | eventSource.once(event_types.CHAT_CHANGED, () => { |
| 352 | $('#file_form').trigger('reset'); | 360 | $('#file_form').trigger('reset'); |
| 353 | }); | 361 | }); |
| 354 | } | 362 | } |
| 363 | } | ||
| 355 | 364 | ||
| 356 | /** | 365 | /** |
| 357 | * Deletes file from message. | 366 | * Deletes file from message. |
| @@ -468,10 +477,12 @@ export function encodeStyleTags(text) { | |||
| 468 | /** | 477 | /** |
| 469 | * Sanitizes custom style tags in the message text to prevent DOM pollution. | 478 | * Sanitizes custom style tags in the message text to prevent DOM pollution. |
| 470 | * @param {string} text Message text | 479 | * @param {string} text Message text |
| 480 | * @param {object} options Options object | ||
| 481 | * @param {string} options.prefix Prefix the selectors with this value | ||
| 471 | * @returns {string} Sanitized message text | 482 | * @returns {string} Sanitized message text |
| 472 | * @copyright https://github.com/kwaroran/risuAI | 483 | * @copyright https://github.com/kwaroran/risuAI |
| 473 | */ | 484 | */ |
| 474 | export function decodeStyleTags(text) { | 485 | export function decodeStyleTags(text, { prefix } = { prefix: '.mes_text ' }) { |
| 475 | const styleDecodeRegex = /<custom-style>(.+?)<\/custom-style>/gms; | 486 | const styleDecodeRegex = /<custom-style>(.+?)<\/custom-style>/gms; |
| 476 | const mediaAllowed = isExternalMediaAllowed(); | 487 | const mediaAllowed = isExternalMediaAllowed(); |
| 477 | 488 | ||
| @@ -487,7 +498,7 @@ export function decodeStyleTags(text) { | |||
| 487 | return v; | 498 | return v; |
| 488 | }).join(' '); | 499 | }).join(' '); |
| 489 | 500 | ||
| 490 | rule.selectors[i] = '.mes_text ' + selectors; | 501 | rule.selectors[i] = prefix + selectors; |
| 491 | } | 502 | } |
| 492 | } | 503 | } |
| 493 | } | 504 | } |
| @@ -525,6 +536,200 @@ export function decodeStyleTags(text) { | |||
| 525 | }); | 536 | }); |
| 526 | } | 537 | } |
| 527 | 538 | ||
| 539 | /** | ||
| 540 | * Class to manage style preferences for characters. | ||
| 541 | */ | ||
| 542 | class StylesPreference { | ||
| 543 | /** | ||
| 544 | * Creates a new StylesPreference instance. | ||
| 545 | * @param {string|null} avatarId - The avatar ID of the character | ||
| 546 | */ | ||
| 547 | constructor(avatarId) { | ||
| 548 | this.avatarId = avatarId; | ||
| 549 | } | ||
| 550 | |||
| 551 | /** | ||
| 552 | * Gets the account storage key for the style preference. | ||
| 553 | */ | ||
| 554 | get key() { | ||
| 555 | return `AllowGlobalStyles-${this.avatarId}`; | ||
| 556 | } | ||
| 557 | |||
| 558 | /** | ||
| 559 | * Checks if a preference exists for this character. | ||
| 560 | * @returns {boolean} True if preference exists, false otherwise | ||
| 561 | */ | ||
| 562 | exists() { | ||
| 563 | return this.avatarId | ||
| 564 | ? accountStorage.getItem(this.key) !== null | ||
| 565 | : true; // No character == assume preference is set | ||
| 566 | } | ||
| 567 | |||
| 568 | /** | ||
| 569 | * Gets the current style preference. | ||
| 570 | * @returns {boolean} True if global styles are allowed, false otherwise | ||
| 571 | */ | ||
| 572 | get() { | ||
| 573 | return this.avatarId | ||
| 574 | ? accountStorage.getItem(this.key) === 'true' | ||
| 575 | : false; // Always disabled when creating a new character | ||
| 576 | } | ||
| 577 | |||
| 578 | /** | ||
| 579 | * Sets the global styles preference. | ||
| 580 | * @param {boolean} allowed - Whether global styles are allowed | ||
| 581 | */ | ||
| 582 | set(allowed) { | ||
| 583 | if (this.avatarId) { | ||
| 584 | accountStorage.setItem(this.key, String(allowed)); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | /** | ||
| 590 | * Formats creator notes in the message text. | ||
| 591 | * @param {string} text Raw Markdown text | ||
| 592 | * @param {string} avatarId Avatar ID | ||
| 593 | * @returns {string} Formatted HTML text | ||
| 594 | */ | ||
| 595 | export function formatCreatorNotes(text, avatarId) { | ||
| 596 | const preference = new StylesPreference(avatarId); | ||
| 597 | const sanitizeStyles = !preference.get(); | ||
| 598 | const decodeStyleParam = { prefix: sanitizeStyles ? '#creator_notes_spoiler ' : '' }; | ||
| 599 | /** @type {import('dompurify').Config & { MESSAGE_SANITIZE: boolean }} */ | ||
| 600 | const config = { | ||
| 601 | RETURN_DOM: false, | ||
| 602 | RETURN_DOM_FRAGMENT: false, | ||
| 603 | RETURN_TRUSTED_TYPE: false, | ||
| 604 | MESSAGE_SANITIZE: true, | ||
| 605 | ADD_TAGS: ['custom-style'], | ||
| 606 | }; | ||
| 607 | |||
| 608 | let html = converter.makeHtml(substituteParams(text)); | ||
| 609 | html = encodeStyleTags(html); | ||
| 610 | html = DOMPurify.sanitize(html, config); | ||
| 611 | html = decodeStyleTags(html, decodeStyleParam); | ||
| 612 | |||
| 613 | return html; | ||
| 614 | } | ||
| 615 | |||
| 616 | async function openGlobalStylesPreferenceDialog() { | ||
| 617 | if (selected_group) { | ||
| 618 | toastr.info(t`To change the global styles preference, please select a character individually.`); | ||
| 619 | return; | ||
| 620 | } | ||
| 621 | |||
| 622 | const entityId = getCurrentEntityId(); | ||
| 623 | const preference = new StylesPreference(entityId); | ||
| 624 | const currentValue = preference.get(); | ||
| 625 | |||
| 626 | const template = $(await renderTemplateAsync('globalStylesPreference')); | ||
| 627 | |||
| 628 | const allowedRadio = template.find('#global_styles_allowed'); | ||
| 629 | const forbiddenRadio = template.find('#global_styles_forbidden'); | ||
| 630 | |||
| 631 | allowedRadio.on('change', () => { | ||
| 632 | preference.set(true); | ||
| 633 | allowedRadio.prop('checked', true); | ||
| 634 | forbiddenRadio.prop('checked', false); | ||
| 635 | }); | ||
| 636 | |||
| 637 | forbiddenRadio.on('change', () => { | ||
| 638 | preference.set(false); | ||
| 639 | allowedRadio.prop('checked', false); | ||
| 640 | forbiddenRadio.prop('checked', true); | ||
| 641 | }); | ||
| 642 | |||
| 643 | const currentPreferenceRadio = currentValue ? allowedRadio : forbiddenRadio; | ||
| 644 | template.find(currentPreferenceRadio).prop('checked', true); | ||
| 645 | |||
| 646 | await callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: false, large: false }); | ||
| 647 | |||
| 648 | // Re-render the notes if the preference changed | ||
| 649 | const newValue = preference.get(); | ||
| 650 | if (newValue !== currentValue) { | ||
| 651 | $('#rm_button_selected_ch').trigger('click'); | ||
| 652 | setGlobalStylesButtonClass(newValue); | ||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 656 | async function checkForCreatorNotesStyles() { | ||
| 657 | // Don't do anything if in group chat or not in a chat | ||
| 658 | if (selected_group || this_chid === undefined) { | ||
| 659 | return; | ||
| 660 | } | ||
| 661 | |||
| 662 | const notes = characters[this_chid].data?.creator_notes || characters[this_chid].creatorcomment; | ||
| 663 | const avatarId = characters[this_chid].avatar; | ||
| 664 | const styleContents = getStyleContentsFromMarkdown(notes); | ||
| 665 | |||
| 666 | if (!styleContents) { | ||
| 667 | setGlobalStylesButtonClass(null); | ||
| 668 | return; | ||
| 669 | } | ||
| 670 | |||
| 671 | const preference = new StylesPreference(avatarId); | ||
| 672 | const hasPreference = preference.exists(); | ||
| 673 | if (!hasPreference) { | ||
| 674 | const template = $(await renderTemplateAsync('globalStylesPopup')); | ||
| 675 | template.find('textarea').val(styleContents); | ||
| 676 | const confirmResult = await callGenericPopup(template, POPUP_TYPE.CONFIRM, '', { | ||
| 677 | wide: false, | ||
| 678 | large: false, | ||
| 679 | okButton: t`Just to Creator's Notes`, | ||
| 680 | cancelButton: t`Apply to the entire app`, | ||
| 681 | }); | ||
| 682 | |||
| 683 | switch (confirmResult) { | ||
| 684 | case POPUP_RESULT.AFFIRMATIVE: | ||
| 685 | preference.set(false); | ||
| 686 | break; | ||
| 687 | case POPUP_RESULT.NEGATIVE: | ||
| 688 | preference.set(true); | ||
| 689 | break; | ||
| 690 | case POPUP_RESULT.CANCELLED: | ||
| 691 | preference.set(false); | ||
| 692 | break; | ||
| 693 | } | ||
| 694 | |||
| 695 | $('#rm_button_selected_ch').trigger('click'); | ||
| 696 | } | ||
| 697 | |||
| 698 | const currentPreference = preference.get(); | ||
| 699 | setGlobalStylesButtonClass(currentPreference); | ||
| 700 | } | ||
| 701 | |||
| 702 | /** | ||
| 703 | * Sets the class of the global styles button based on the state. | ||
| 704 | * @param {boolean|null} state State of the button | ||
| 705 | */ | ||
| 706 | function setGlobalStylesButtonClass(state) { | ||
| 707 | const button = $('#creators_note_styles_button'); | ||
| 708 | button.toggleClass('empty', state === null); | ||
| 709 | button.toggleClass('allowed', state === true); | ||
| 710 | button.toggleClass('forbidden', state === false); | ||
| 711 | } | ||
| 712 | |||
| 713 | /** | ||
| 714 | * Extracts the contents of all style elements from the Markdown text. | ||
| 715 | * @param {string} text Markdown text | ||
| 716 | * @returns {string} The joined contents of all style elements | ||
| 717 | */ | ||
| 718 | function getStyleContentsFromMarkdown(text) { | ||
| 719 | if (!text) { | ||
| 720 | return ''; | ||
| 721 | } | ||
| 722 | |||
| 723 | const div = document.createElement('div'); | ||
| 724 | const html = converter.makeHtml(substituteParams(text)); | ||
| 725 | div.innerHTML = html; | ||
| 726 | const styleElements = Array.from(div.querySelectorAll('style')); | ||
| 727 | return styleElements | ||
| 728 | .filter(s => s.textContent.trim().length > 0) | ||
| 729 | .map(s => s.textContent.trim()) | ||
| 730 | .join('\n\n'); | ||
| 731 | } | ||
| 732 | |||
| 528 | async function openExternalMediaOverridesDialog() { | 733 | async function openExternalMediaOverridesDialog() { |
| 529 | const entityId = getCurrentEntityId(); | 734 | const entityId = getCurrentEntityId(); |
| 530 | 735 | ||
| @@ -1030,12 +1235,12 @@ async function openAttachmentManager() { | |||
| 1030 | popper.update(); | 1235 | popper.update(); |
| 1031 | }); | 1236 | }); |
| 1032 | 1237 | ||
| 1033 | return [popper, bodyListener]; | 1238 | return { popper, bodyListener }; |
| 1034 | }).filter(Boolean); | 1239 | }).filter(Boolean); |
| 1035 | 1240 | ||
| 1036 | return () => { | 1241 | return () => { |
| 1037 | modalButtonData.forEach(p => { | 1242 | modalButtonData.forEach(p => { |
| 1038 | const [popper, bodyListener] = p; | 1243 | const { popper,bodyListener } = p; |
| 1039 | popper.destroy(); | 1244 | popper.destroy(); |
| 1040 | document.body.removeEventListener('click', bodyListener); | 1245 | document.body.removeEventListener('click', bodyListener); |
| 1041 | }); | 1246 | }); |
| @@ -1459,7 +1664,7 @@ export function registerFileConverter(mimeType, converter) { | |||
| 1459 | converters[mimeType] = converter; | 1664 | converters[mimeType] = converter; |
| 1460 | } | 1665 | } |
| 1461 | 1666 | ||
| 1462 | jQuery(function () { | 1667 | export function initChatUtilities() { |
| 1463 | $(document).on('click', '.mes_hide', async function () { | 1668 | $(document).on('click', '.mes_hide', async function () { |
| 1464 | const messageBlock = $(this).closest('.mes'); | 1669 | const messageBlock = $(this).closest('.mes'); |
| 1465 | const messageId = Number(messageBlock.attr('mesid')); | 1670 | const messageId = Number(messageBlock.attr('mesid')); |
| @@ -1497,6 +1702,35 @@ jQuery(function () { | |||
| 1497 | download(chatToSave.map((m) => JSON.stringify(m)).join('\n'), `Assistant - ${humanizedDateTime()}.jsonl`, 'application/json'); | 1702 | download(chatToSave.map((m) => JSON.stringify(m)).join('\n'), `Assistant - ${humanizedDateTime()}.jsonl`, 'application/json'); |
| 1498 | }); | 1703 | }); |
| 1499 | 1704 | ||
| 1705 | $(document).on('click', '.assistant_note_import', async function () { | ||
| 1706 | const importFile = async () => { | ||
| 1707 | const file = fileInput.files[0]; | ||
| 1708 | if (!file) { | ||
| 1709 | return; | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | try { | ||
| 1713 | const text = await getFileText(file); | ||
| 1714 | const lines = text.split('\n').filter(line => line.trim() !== ''); | ||
| 1715 | const messages = lines.map(line => JSON.parse(line)); | ||
| 1716 | const metadata = messages.shift()?.chat_metadata || {}; | ||
| 1717 | messages.unshift(getSystemMessageByType(system_message_types.ASSISTANT_NOTE)); | ||
| 1718 | await clearChat(); | ||
| 1719 | chat.splice(0, chat.length, ...messages); | ||
| 1720 | updateChatMetadata(metadata, true); | ||
| 1721 | await printMessages(); | ||
| 1722 | } catch (error) { | ||
| 1723 | console.error('Error importing assistant chat:', error); | ||
| 1724 | toastr.error(t`It's either corrupted or not a valid JSONL file.`, t`Failed to import chat`); | ||
| 1725 | } | ||
| 1726 | }; | ||
| 1727 | const fileInput = document.createElement('input'); | ||
| 1728 | fileInput.type = 'file'; | ||
| 1729 | fileInput.accept = '.jsonl'; | ||
| 1730 | fileInput.addEventListener('change', importFile); | ||
| 1731 | fileInput.click(); | ||
| 1732 | }); | ||
| 1733 | |||
| 1500 | // Do not change. #attachFile is added by extension. | 1734 | // Do not change. #attachFile is added by extension. |
| 1501 | $(document).on('click', '#attachFile', function () { | 1735 | $(document).on('click', '#attachFile', function () { |
| 1502 | $('#file_form_input').trigger('click'); | 1736 | $('#file_form_input').trigger('click'); |
| @@ -1576,7 +1810,8 @@ jQuery(function () { | |||
| 1576 | await callGenericPopup(wrapper, POPUP_TYPE.TEXT, '', { wide: true, large: true }); | 1810 | await callGenericPopup(wrapper, POPUP_TYPE.TEXT, '', { wide: true, large: true }); |
| 1577 | }); | 1811 | }); |
| 1578 | 1812 | ||
| 1579 | $(document).on('click', 'body.documentstyle .mes .mes_text', function () { | 1813 | $(document).on('click', 'body .mes .mes_text', function () { |
| 1814 | if (!power_user.click_to_edit) return; | ||
| 1580 | if (window.getSelection().toString()) return; | 1815 | if (window.getSelection().toString()) return; |
| 1581 | if ($('.edit_textarea').length) return; | 1816 | if ($('.edit_textarea').length) return; |
| 1582 | $(this).closest('.mes').find('.mes_edit').trigger('click'); | 1817 | $(this).closest('.mes').find('.mes_edit').trigger('click'); |
| @@ -1608,6 +1843,10 @@ jQuery(function () { | |||
| 1608 | reloadCurrentChat(); | 1843 | reloadCurrentChat(); |
| 1609 | }); | 1844 | }); |
| 1610 | 1845 | ||
| 1846 | $('#creators_note_styles_button').on('click', function () { | ||
| 1847 | openGlobalStylesPreferenceDialog(); | ||
| 1848 | }); | ||
| 1849 | |||
| 1611 | $(document).on('click', '.mes_img', expandMessageImage); | 1850 | $(document).on('click', '.mes_img', expandMessageImage); |
| 1612 | $(document).on('click', '.mes_img_enlarge', expandAndZoomMessageImage); | 1851 | $(document).on('click', '.mes_img_enlarge', expandAndZoomMessageImage); |
| 1613 | $(document).on('click', '.mes_img_delete', deleteMessageImage); | 1852 | $(document).on('click', '.mes_img_delete', deleteMessageImage); |
| @@ -1642,4 +1881,6 @@ jQuery(function () { | |||
| 1642 | fileInput.files = dataTransfer.files; | 1881 | fileInput.files = dataTransfer.files; |
| 1643 | await onFileAttach(fileInput.files[0]); | 1882 | await onFileAttach(fileInput.files[0]); |
| 1644 | }); | 1883 | }); |
| 1645 | }); | 1884 | |
| 1885 | eventSource.on(event_types.CHAT_CHANGED, checkForCreatorNotesStyles); | ||
| 1886 | } | ||
| @@ -242,9 +242,16 @@ export class TextCompletionService { | |||
| 242 | 242 | ||
| 243 | // Format messages using instruct formatting | 243 | // Format messages using instruct formatting |
| 244 | const formattedMessages = []; | 244 | const formattedMessages = []; |
| 245 | const prefillActive = prompt.length > 0 ? prompt[prompt.length - 1].role === 'assistant' : false; | ||
| 245 | for (const message of prompt) { | 246 | for (const message of prompt) { |
| 246 | let messageContent = message.content; | 247 | let messageContent = message.content; |
| 247 | if (!message.ignoreInstruct) { | 248 | if (!message.ignoreInstruct) { |
| 249 | const isLastMessage = message === prompt[prompt.length - 1]; | ||
| 250 | |||
| 251 | // This complicated logic means: | ||
| 252 | // 1. If prefill is not active, format all messages | ||
| 253 | // 2. If prefill is active, format all messages except the last one | ||
| 254 | if (!isLastMessage || !prefillActive) { | ||
| 248 | messageContent = formatInstructModeChat( | 255 | messageContent = formatInstructModeChat( |
| 249 | message.role, | 256 | message.role, |
| 250 | message.content, | 257 | message.content, |
| @@ -256,9 +263,11 @@ export class TextCompletionService { | |||
| 256 | undefined, | 263 | undefined, |
| 257 | instructPreset, | 264 | instructPreset, |
| 258 | ); | 265 | ); |
| 266 | } | ||
| 259 | 267 | ||
| 260 | // Add prompt formatting for the last message | 268 | // Add prompt formatting for the last message. |
| 261 | if (message === prompt[prompt.length - 1]) { | 269 | if (isLastMessage) { |
| 270 | if (!prefillActive) { // e.g. "<|im_start|>user:" | ||
| 262 | messageContent += formatInstructModePrompt( | 271 | messageContent += formatInstructModePrompt( |
| 263 | undefined, | 272 | undefined, |
| 264 | false, | 273 | false, |
| @@ -269,6 +278,22 @@ export class TextCompletionService { | |||
| 269 | false, | 278 | false, |
| 270 | instructPreset, | 279 | instructPreset, |
| 271 | ); | 280 | ); |
| 281 | } else { // e.g. "<|im_start|>assistant: Hello, my name is" | ||
| 282 | const overridenInstructPreset = structuredClone(instructPreset); | ||
| 283 | overridenInstructPreset.output_suffix = ''; | ||
| 284 | overridenInstructPreset.wrap = false; | ||
| 285 | messageContent = formatInstructModeChat( | ||
| 286 | message.role, | ||
| 287 | message.content, | ||
| 288 | false, // since it is assistant | ||
| 289 | false, | ||
| 290 | undefined, | ||
| 291 | undefined, | ||
| 292 | undefined, | ||
| 293 | undefined, | ||
| 294 | overridenInstructPreset, | ||
| 295 | ); | ||
| 296 | } | ||
| 272 | } | 297 | } |
| 273 | } | 298 | } |
| 274 | formattedMessages.push(messageContent); | 299 | formattedMessages.push(messageContent); |
| @@ -58,14 +58,20 @@ let requiresReload = false; | |||
| 58 | let stateChanged = false; | 58 | let stateChanged = false; |
| 59 | let saveMetadataTimeout = null; | 59 | let saveMetadataTimeout = null; |
| 60 | 60 | ||
| 61 | export function cancelDebouncedMetadataSave() { | ||
| 62 | if (saveMetadataTimeout) { | ||
| 63 | console.debug('Debounced metadata save cancelled'); | ||
| 64 | clearTimeout(saveMetadataTimeout); | ||
| 65 | saveMetadataTimeout = null; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 61 | export function saveMetadataDebounced() { | 69 | export function saveMetadataDebounced() { |
| 62 | const context = getContext(); | 70 | const context = getContext(); |
| 63 | const groupId = context.groupId; | 71 | const groupId = context.groupId; |
| 64 | const characterId = context.characterId; | 72 | const characterId = context.characterId; |
| 65 | 73 | ||
| 66 | if (saveMetadataTimeout) { | 74 | cancelDebouncedMetadataSave(); |
| 67 | clearTimeout(saveMetadataTimeout); | ||
| 68 | } | ||
| 69 | 75 | ||
| 70 | saveMetadataTimeout = setTimeout(async () => { | 76 | saveMetadataTimeout = setTimeout(async () => { |
| 71 | const newContext = getContext(); | 77 | const newContext = getContext(); |
| @@ -661,6 +667,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, | |||
| 661 | let deleteButton = isExternal ? `<button class="btn_delete menu_button" data-name="${externalId}" data-i18n="[title]Delete" title="Delete"><i class="fa-fw fa-solid fa-trash-can"></i></button>` : ''; | 667 | let deleteButton = isExternal ? `<button class="btn_delete menu_button" data-name="${externalId}" data-i18n="[title]Delete" title="Delete"><i class="fa-fw fa-solid fa-trash-can"></i></button>` : ''; |
| 662 | let updateButton = isExternal ? `<button class="btn_update menu_button displayNone" data-name="${externalId}" title="Update available"><i class="fa-solid fa-download fa-fw"></i></button>` : ''; | 668 | let updateButton = isExternal ? `<button class="btn_update menu_button displayNone" data-name="${externalId}" title="Update available"><i class="fa-solid fa-download fa-fw"></i></button>` : ''; |
| 663 | let moveButton = isExternal && isUserAdmin ? `<button class="btn_move menu_button" data-name="${externalId}" data-i18n="[title]Move" title="Move"><i class="fa-solid fa-folder-tree fa-fw"></i></button>` : ''; | 669 | let moveButton = isExternal && isUserAdmin ? `<button class="btn_move menu_button" data-name="${externalId}" data-i18n="[title]Move" title="Move"><i class="fa-solid fa-folder-tree fa-fw"></i></button>` : ''; |
| 670 | let branchButton = isExternal && isUserAdmin ? `<button class="btn_branch menu_button" data-name="${externalId}" data-i18n="[title]Switch branch" title="Switch branch"><i class="fa-solid fa-code-branch fa-fw"></i></button>` : ''; | ||
| 664 | let modulesInfo = ''; | 671 | let modulesInfo = ''; |
| 665 | 672 | ||
| 666 | if (isActive && Array.isArray(manifest.optional)) { | 673 | if (isActive && Array.isArray(manifest.optional)) { |
| @@ -701,6 +708,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, | |||
| 701 | 708 | ||
| 702 | <div class="extension_actions flex-container alignItemsCenter"> | 709 | <div class="extension_actions flex-container alignItemsCenter"> |
| 703 | ${updateButton} | 710 | ${updateButton} |
| 711 | ${branchButton} | ||
| 704 | ${moveButton} | 712 | ${moveButton} |
| 705 | ${deleteButton} | 713 | ${deleteButton} |
| 706 | </div> | 714 | </div> |
| @@ -944,6 +952,44 @@ async function onDeleteClick() { | |||
| 944 | } | 952 | } |
| 945 | } | 953 | } |
| 946 | 954 | ||
| 955 | async function onBranchClick() { | ||
| 956 | const extensionName = $(this).data('name'); | ||
| 957 | const isCurrentUserAdmin = isAdmin(); | ||
| 958 | const isGlobal = getExtensionType(extensionName) === 'global'; | ||
| 959 | if (isGlobal && !isCurrentUserAdmin) { | ||
| 960 | toastr.error(t`You don't have permission to switch branch.`); | ||
| 961 | return; | ||
| 962 | } | ||
| 963 | |||
| 964 | let newBranch = ''; | ||
| 965 | |||
| 966 | const branches = await getExtensionBranches(extensionName, isGlobal); | ||
| 967 | const selectElement = document.createElement('select'); | ||
| 968 | selectElement.classList.add('text_pole', 'wide100p'); | ||
| 969 | selectElement.addEventListener('change', function () { | ||
| 970 | newBranch = this.value; | ||
| 971 | }); | ||
| 972 | for (const branch of branches) { | ||
| 973 | const option = document.createElement('option'); | ||
| 974 | option.value = branch.name; | ||
| 975 | option.textContent = `${branch.name} (${branch.commit}) [${branch.label}]`; | ||
| 976 | option.selected = branch.current; | ||
| 977 | selectElement.appendChild(option); | ||
| 978 | } | ||
| 979 | |||
| 980 | const popup = new Popup(selectElement, POPUP_TYPE.CONFIRM, '', { | ||
| 981 | okButton: t`Switch`, | ||
| 982 | cancelButton: t`Cancel`, | ||
| 983 | }); | ||
| 984 | const popupResult = await popup.show(); | ||
| 985 | |||
| 986 | if (!popupResult || !newBranch) { | ||
| 987 | return; | ||
| 988 | } | ||
| 989 | |||
| 990 | await switchExtensionBranch(extensionName, isGlobal, newBranch); | ||
| 991 | } | ||
| 992 | |||
| 947 | async function onMoveClick() { | 993 | async function onMoveClick() { |
| 948 | const extensionName = $(this).data('name'); | 994 | const extensionName = $(this).data('name'); |
| 949 | const isCurrentUserAdmin = isAdmin(); | 995 | const isCurrentUserAdmin = isAdmin(); |
| @@ -1056,12 +1102,82 @@ async function getExtensionVersion(extensionName, abortSignal) { | |||
| 1056 | } | 1102 | } |
| 1057 | 1103 | ||
| 1058 | /** | 1104 | /** |
| 1105 | * Gets the list of branches for a specific extension. | ||
| 1106 | * @param {string} extensionName The name of the extension | ||
| 1107 | * @param {boolean} isGlobal Whether the extension is global or not | ||
| 1108 | * @returns {Promise<ExtensionBranch[]>} List of branches for the extension | ||
| 1109 | * @typedef {object} ExtensionBranch | ||
| 1110 | * @property {string} name The name of the branch | ||
| 1111 | * @property {string} commit The commit hash of the branch | ||
| 1112 | * @property {boolean} current Whether this branch is the current one | ||
| 1113 | * @property {string} label The commit label of the branch | ||
| 1114 | */ | ||
| 1115 | async function getExtensionBranches(extensionName, isGlobal) { | ||
| 1116 | try { | ||
| 1117 | const response = await fetch('/api/extensions/branches', { | ||
| 1118 | method: 'POST', | ||
| 1119 | headers: getRequestHeaders(), | ||
| 1120 | body: JSON.stringify({ | ||
| 1121 | extensionName, | ||
| 1122 | global: isGlobal, | ||
| 1123 | }), | ||
| 1124 | }); | ||
| 1125 | |||
| 1126 | if (!response.ok) { | ||
| 1127 | const text = await response.text(); | ||
| 1128 | toastr.error(text || response.statusText, t`Extension branches fetch failed`); | ||
| 1129 | console.error('Extension branches fetch failed', response.status, response.statusText, text); | ||
| 1130 | return []; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | return await response.json(); | ||
| 1134 | } catch (error) { | ||
| 1135 | console.error('Error:', error); | ||
| 1136 | return []; | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | /** | ||
| 1141 | * Switches the branch of an extension. | ||
| 1142 | * @param {string} extensionName The name of the extension | ||
| 1143 | * @param {boolean} isGlobal If the extension is global | ||
| 1144 | * @param {string} branch Branch name to switch to | ||
| 1145 | * @returns {Promise<void>} | ||
| 1146 | */ | ||
| 1147 | async function switchExtensionBranch(extensionName, isGlobal, branch) { | ||
| 1148 | try { | ||
| 1149 | const response = await fetch('/api/extensions/switch', { | ||
| 1150 | method: 'POST', | ||
| 1151 | headers: getRequestHeaders(), | ||
| 1152 | body: JSON.stringify({ | ||
| 1153 | extensionName, | ||
| 1154 | branch, | ||
| 1155 | global: isGlobal, | ||
| 1156 | }), | ||
| 1157 | }); | ||
| 1158 | |||
| 1159 | if (!response.ok) { | ||
| 1160 | const text = await response.text(); | ||
| 1161 | toastr.error(text || response.statusText, t`Extension branch switch failed`); | ||
| 1162 | console.error('Extension branch switch failed', response.status, response.statusText, text); | ||
| 1163 | return; | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | toastr.success(t`Extension ${extensionName} switched to ${branch}`); | ||
| 1167 | await loadExtensionSettings({}, false, false); | ||
| 1168 | void showExtensionsDetails(); | ||
| 1169 | } catch (error) { | ||
| 1170 | console.error('Error:', error); | ||
| 1171 | } | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | /** | ||
| 1059 | * Installs a third-party extension via the API. | 1175 | * Installs a third-party extension via the API. |
| 1060 | * @param {string} url Extension repository URL | 1176 | * @param {string} url Extension repository URL |
| 1061 | * @param {boolean} global Is the extension global? | 1177 | * @param {boolean} global Is the extension global? |
| 1062 | * @returns {Promise<void>} | 1178 | * @returns {Promise<void>} |
| 1063 | */ | 1179 | */ |
| 1064 | export async function installExtension(url, global) { | 1180 | export async function installExtension(url, global, branch = '') { |
| 1065 | console.debug('Extension installation started', url); | 1181 | console.debug('Extension installation started', url); |
| 1066 | 1182 | ||
| 1067 | toastr.info(t`Please wait...`, t`Installing extension`); | 1183 | toastr.info(t`Please wait...`, t`Installing extension`); |
| @@ -1072,6 +1188,7 @@ export async function installExtension(url, global) { | |||
| 1072 | body: JSON.stringify({ | 1188 | body: JSON.stringify({ |
| 1073 | url, | 1189 | url, |
| 1074 | global, | 1190 | global, |
| 1191 | branch, | ||
| 1075 | }), | 1192 | }), |
| 1076 | }); | 1193 | }); |
| 1077 | 1194 | ||
| @@ -1406,9 +1523,17 @@ export async function openThirdPartyExtensionMenu(suggestUrl = '') { | |||
| 1406 | await popup.complete(POPUP_RESULT.AFFIRMATIVE); | 1523 | await popup.complete(POPUP_RESULT.AFFIRMATIVE); |
| 1407 | }, | 1524 | }, |
| 1408 | }; | 1525 | }; |
| 1526 | /** @type {import('./popup.js').CustomPopupInput} */ | ||
| 1527 | const branchNameInput = { | ||
| 1528 | id: 'extension_branch_name', | ||
| 1529 | label: t`Branch or tag name (optional)`, | ||
| 1530 | type: 'text', | ||
| 1531 | tooltip: 'e.g. main, dev, v1.0.0', | ||
| 1532 | }; | ||
| 1409 | 1533 | ||
| 1410 | const customButtons = isCurrentUserAdmin ? [installForAllButton] : []; | 1534 | const customButtons = isCurrentUserAdmin ? [installForAllButton] : []; |
| 1411 | const popup = new Popup(html, POPUP_TYPE.INPUT, suggestUrl ?? '', { okButton, customButtons }); | 1535 | const customInputs = [branchNameInput]; |
| 1536 | const popup = new Popup(html, POPUP_TYPE.INPUT, suggestUrl ?? '', { okButton, customButtons, customInputs }); | ||
| 1412 | const input = await popup.show(); | 1537 | const input = await popup.show(); |
| 1413 | 1538 | ||
| 1414 | if (!input) { | 1539 | if (!input) { |
| @@ -1417,7 +1542,8 @@ export async function openThirdPartyExtensionMenu(suggestUrl = '') { | |||
| 1417 | } | 1542 | } |
| 1418 | 1543 | ||
| 1419 | const url = String(input).trim(); | 1544 | const url = String(input).trim(); |
| 1420 | await installExtension(url, global); | 1545 | const branchName = String(popup.inputResults.get('extension_branch_name') ?? '').trim(); |
| 1546 | await installExtension(url, global, branchName); | ||
| 1421 | } | 1547 | } |
| 1422 | 1548 | ||
| 1423 | export async function initExtensions() { | 1549 | export async function initExtensions() { |
| @@ -1433,6 +1559,7 @@ export async function initExtensions() { | |||
| 1433 | $(document).on('click', '.extensions_info .extension_block .btn_update', onUpdateClick); | 1559 | $(document).on('click', '.extensions_info .extension_block .btn_update', onUpdateClick); |
| 1434 | $(document).on('click', '.extensions_info .extension_block .btn_delete', onDeleteClick); | 1560 | $(document).on('click', '.extensions_info .extension_block .btn_delete', onDeleteClick); |
| 1435 | $(document).on('click', '.extensions_info .extension_block .btn_move', onMoveClick); | 1561 | $(document).on('click', '.extensions_info .extension_block .btn_move', onMoveClick); |
| 1562 | $(document).on('click', '.extensions_info .extension_block .btn_branch', onBranchClick); | ||
| 1436 | 1563 | ||
| 1437 | /** | 1564 | /** |
| 1438 | * Handles the click event for the third-party extension import button. | 1565 | * Handles the click event for the third-party extension import button. |
| @@ -291,7 +291,7 @@ async function installAsset(url, assetType, filename) { | |||
| 291 | try { | 291 | try { |
| 292 | if (category === 'extension') { | 292 | if (category === 'extension') { |
| 293 | console.debug(DEBUG_PREFIX, 'Installing extension ', url); | 293 | console.debug(DEBUG_PREFIX, 'Installing extension ', url); |
| 294 | await installExtension(url); | 294 | await installExtension(url, false); |
| 295 | console.debug(DEBUG_PREFIX, 'Extension installed.'); | 295 | console.debug(DEBUG_PREFIX, 'Extension installed.'); |
| 296 | return; | 296 | return; |
| 297 | } | 297 | } |
| @@ -309,7 +309,7 @@ async function installAsset(url, assetType, filename) { | |||
| 309 | console.debug(DEBUG_PREFIX, 'Importing character ', filename); | 309 | console.debug(DEBUG_PREFIX, 'Importing character ', filename); |
| 310 | const blob = await result.blob(); | 310 | const blob = await result.blob(); |
| 311 | const file = new File([blob], filename, { type: blob.type }); | 311 | const file = new File([blob], filename, { type: blob.type }); |
| 312 | await processDroppedFiles([file], true); | 312 | await processDroppedFiles([file]); |
| 313 | console.debug(DEBUG_PREFIX, 'Character downloaded.'); | 313 | console.debug(DEBUG_PREFIX, 'Character downloaded.'); |
| 314 | } | 314 | } |
| 315 | } | 315 | } |
| @@ -408,13 +408,17 @@ jQuery(async function () { | |||
| 408 | // Handle multimodal sources | 408 | // Handle multimodal sources |
| 409 | if (settings.source === 'multimodal') { | 409 | if (settings.source === 'multimodal') { |
| 410 | const api = settings.multimodal_api; | 410 | const api = settings.multimodal_api; |
| 411 | const altEndpointEnabled = settings.alt_endpoint_enabled; | ||
| 412 | const altEndpointUrl = settings.alt_endpoint_url; | ||
| 411 | 413 | ||
| 412 | // APIs that support reverse proxy | 414 | // APIs that support reverse proxy |
| 413 | const reverseProxyApis = { | 415 | const reverseProxyApis = { |
| 414 | 'openai': SECRET_KEYS.OPENAI, | 416 | 'openai': SECRET_KEYS.OPENAI, |
| 415 | 'mistral': SECRET_KEYS.MISTRALAI, | 417 | 'mistral': SECRET_KEYS.MISTRALAI, |
| 416 | 'google': SECRET_KEYS.MAKERSUITE, | 418 | 'google': SECRET_KEYS.MAKERSUITE, |
| 419 | 'vertexai': SECRET_KEYS.VERTEXAI, | ||
| 417 | 'anthropic': SECRET_KEYS.CLAUDE, | 420 | 'anthropic': SECRET_KEYS.CLAUDE, |
| 421 | 'xai': SECRET_KEYS.XAI, | ||
| 418 | }; | 422 | }; |
| 419 | 423 | ||
| 420 | if (reverseProxyApis[api]) { | 424 | if (reverseProxyApis[api]) { |
| @@ -428,7 +432,6 @@ jQuery(async function () { | |||
| 428 | 'zerooneai': SECRET_KEYS.ZEROONEAI, | 432 | 'zerooneai': SECRET_KEYS.ZEROONEAI, |
| 429 | 'groq': SECRET_KEYS.GROQ, | 433 | 'groq': SECRET_KEYS.GROQ, |
| 430 | 'cohere': SECRET_KEYS.COHERE, | 434 | 'cohere': SECRET_KEYS.COHERE, |
| 431 | 'xai': SECRET_KEYS.XAI, | ||
| 432 | }; | 435 | }; |
| 433 | 436 | ||
| 434 | if (chatCompletionApis[api] && secret_state[chatCompletionApis[api]]) { | 437 | if (chatCompletionApis[api] && secret_state[chatCompletionApis[api]]) { |
| @@ -443,12 +446,16 @@ jQuery(async function () { | |||
| 443 | 'vllm': textgen_types.VLLM, | 446 | 'vllm': textgen_types.VLLM, |
| 444 | }; | 447 | }; |
| 445 | 448 | ||
| 446 | if (textCompletionApis[api] && textgenerationwebui_settings.server_urls[textCompletionApis[api]]) { | 449 | if (textCompletionApis[api] && altEndpointEnabled && altEndpointUrl) { |
| 450 | return true; | ||
| 451 | } | ||
| 452 | |||
| 453 | if (textCompletionApis[api] && !altEndpointEnabled && textgenerationwebui_settings.server_urls[textCompletionApis[api]]) { | ||
| 447 | return true; | 454 | return true; |
| 448 | } | 455 | } |
| 449 | 456 | ||
| 450 | // Custom API doesn't need additional checks | 457 | // Custom API doesn't need additional checks |
| 451 | if (api === 'custom') { | 458 | if (api === 'custom' || api === 'pollinations') { |
| 452 | return true; | 459 | return true; |
| 453 | } | 460 | } |
| 454 | } | 461 | } |
| @@ -579,6 +586,14 @@ jQuery(async function () { | |||
| 579 | extension_settings.caption.multimodal_model = String($('#caption_multimodal_model').val()); | 586 | extension_settings.caption.multimodal_model = String($('#caption_multimodal_model').val()); |
| 580 | saveSettingsDebounced(); | 587 | saveSettingsDebounced(); |
| 581 | }); | 588 | }); |
| 589 | $('#caption_altEndpoint_url').val(extension_settings.caption.alt_endpoint_url).on('input', () => { | ||
| 590 | extension_settings.caption.alt_endpoint_url = String($('#caption_altEndpoint_url').val()); | ||
| 591 | saveSettingsDebounced(); | ||
| 592 | }); | ||
| 593 | $('#caption_altEndpoint_enabled').prop('checked', !!(extension_settings.caption.alt_endpoint_enabled)).on('input', () => { | ||
| 594 | extension_settings.caption.alt_endpoint_enabled = !!$('#caption_altEndpoint_enabled').prop('checked'); | ||
| 595 | saveSettingsDebounced(); | ||
| 596 | }); | ||
| 582 | 597 | ||
| 583 | const onMessageEvent = async (index) => { | 598 | const onMessageEvent = async (index) => { |
| 584 | if (!extension_settings.caption.auto_mode) { | 599 | if (!extension_settings.caption.auto_mode) { |
| @@ -22,6 +22,7 @@ | |||
| 22 | <option value="cohere">Cohere</option> | 22 | <option value="cohere">Cohere</option> |
| 23 | <option value="custom" data-i18n="Custom (OpenAI-compatible)">Custom (OpenAI-compatible)</option> | 23 | <option value="custom" data-i18n="Custom (OpenAI-compatible)">Custom (OpenAI-compatible)</option> |
| 24 | <option value="google">Google AI Studio</option> | 24 | <option value="google">Google AI Studio</option> |
| 25 | <option value="vertexai">Google Vertex AI</option> | ||
| 25 | <option value="groq">Groq</option> | 26 | <option value="groq">Groq</option> |
| 26 | <option value="koboldcpp">KoboldCpp</option> | 27 | <option value="koboldcpp">KoboldCpp</option> |
| 27 | <option value="llamacpp">llama.cpp</option> | 28 | <option value="llamacpp">llama.cpp</option> |
| @@ -30,6 +31,7 @@ | |||
| 30 | <option value="openai">OpenAI</option> | 31 | <option value="openai">OpenAI</option> |
| 31 | <option value="openrouter">OpenRouter</option> | 32 | <option value="openrouter">OpenRouter</option> |
| 32 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> | 33 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> |
| 34 | <option value="pollinations">Pollinations</option> | ||
| 33 | <option value="vllm">vLLM</option> | 35 | <option value="vllm">vLLM</option> |
| 34 | <option value="xai">xAI (Grok)</option> | 36 | <option value="xai">xAI (Grok)</option> |
| 35 | </select> | 37 | </select> |
| @@ -46,6 +48,8 @@ | |||
| 46 | <option data-type="mistral" value="mistral-large-pixtral-2411">mistral-large-pixtral-2411</option> | 48 | <option data-type="mistral" value="mistral-large-pixtral-2411">mistral-large-pixtral-2411</option> |
| 47 | <option data-type="mistral" value="mistral-small-2503">mistral-small-2503</option> | 49 | <option data-type="mistral" value="mistral-small-2503">mistral-small-2503</option> |
| 48 | <option data-type="mistral" value="mistral-small-latest">mistral-small-latest</option> | 50 | <option data-type="mistral" value="mistral-small-latest">mistral-small-latest</option> |
| 51 | <option data-type="mistral" value="mistral-medium-latest">mistral-medium-latest</option> | ||
| 52 | <option data-type="mistral" value="mistral-medium-2505">mistral-medium-2505</option> | ||
| 49 | <option data-type="zerooneai" value="yi-vision">yi-vision</option> | 53 | <option data-type="zerooneai" value="yi-vision">yi-vision</option> |
| 50 | <option data-type="openai" value="gpt-4.1">gpt-4.1</option> | 54 | <option data-type="openai" value="gpt-4.1">gpt-4.1</option> |
| 51 | <option data-type="openai" value="gpt-4.1-2025-04-14">gpt-4.1-2025-04-14</option> | 55 | <option data-type="openai" value="gpt-4.1-2025-04-14">gpt-4.1-2025-04-14</option> |
| @@ -57,6 +61,7 @@ | |||
| 57 | <option data-type="openai" value="gpt-4-turbo">gpt-4-turbo</option> | 61 | <option data-type="openai" value="gpt-4-turbo">gpt-4-turbo</option> |
| 58 | <option data-type="openai" value="gpt-4o">gpt-4o</option> | 62 | <option data-type="openai" value="gpt-4o">gpt-4o</option> |
| 59 | <option data-type="openai" value="gpt-4o-mini">gpt-4o-mini</option> | 63 | <option data-type="openai" value="gpt-4o-mini">gpt-4o-mini</option> |
| 64 | <option data-type="openai" value="gpt-4o-mini-2024-07-18">gpt-4o-mini-2024-07-18</option> | ||
| 60 | <option data-type="openai" value="chatgpt-4o-latest">chatgpt-4o-latest</option> | 65 | <option data-type="openai" value="chatgpt-4o-latest">chatgpt-4o-latest</option> |
| 61 | <option data-type="openai" value="o1">o1</option> | 66 | <option data-type="openai" value="o1">o1</option> |
| 62 | <option data-type="openai" value="o1-2024-12-17">o1-2024-12-17</option> | 67 | <option data-type="openai" value="o1-2024-12-17">o1-2024-12-17</option> |
| @@ -66,6 +71,10 @@ | |||
| 66 | <option data-type="openai" value="o4-mini-2025-04-16">o4-mini-2025-04-16</option> | 71 | <option data-type="openai" value="o4-mini-2025-04-16">o4-mini-2025-04-16</option> |
| 67 | <option data-type="openai" value="gpt-4.5-preview">gpt-4.5-preview</option> | 72 | <option data-type="openai" value="gpt-4.5-preview">gpt-4.5-preview</option> |
| 68 | <option data-type="openai" value="gpt-4.5-preview-2025-02-27">gpt-4.5-preview-2025-02-27</option> | 73 | <option data-type="openai" value="gpt-4.5-preview-2025-02-27">gpt-4.5-preview-2025-02-27</option> |
| 74 | <option data-type="anthropic" value="claude-opus-4-0">claude-opus-4-0</option> | ||
| 75 | <option data-type="anthropic" value="claude-opus-4-20250514">claude-opus-4-20250514</option> | ||
| 76 | <option data-type="anthropic" value="claude-sonnet-4-0">claude-sonnet-4-0</option> | ||
| 77 | <option data-type="anthropic" value="claude-sonnet-4-20250514">claude-sonnet-4-20250514</option> | ||
| 69 | <option data-type="anthropic" value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option> | 78 | <option data-type="anthropic" value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option> |
| 70 | <option data-type="anthropic" value="claude-3-7-sonnet-20250219">claude-3-7-sonnet-20250219</option> | 79 | <option data-type="anthropic" value="claude-3-7-sonnet-20250219">claude-3-7-sonnet-20250219</option> |
| 71 | <option data-type="anthropic" value="claude-3-5-sonnet-latest">claude-3-5-sonnet-latest</option> | 80 | <option data-type="anthropic" value="claude-3-5-sonnet-latest">claude-3-5-sonnet-latest</option> |
| @@ -76,36 +85,43 @@ | |||
| 76 | <option data-type="anthropic" value="claude-3-opus-20240229">claude-3-opus-20240229</option> | 85 | <option data-type="anthropic" value="claude-3-opus-20240229">claude-3-opus-20240229</option> |
| 77 | <option data-type="anthropic" value="claude-3-sonnet-20240229">claude-3-sonnet-20240229</option> | 86 | <option data-type="anthropic" value="claude-3-sonnet-20240229">claude-3-sonnet-20240229</option> |
| 78 | <option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> | 87 | <option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> |
| 88 | <option data-type="google" value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> | ||
| 79 | <option data-type="google" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> | 89 | <option data-type="google" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> |
| 80 | <option data-type="google" value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option> | 90 | <option data-type="google" value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option> |
| 81 | <option data-type="google" value="gemini-2.0-pro-exp">gemini-2.0-pro-exp</option> | 91 | <option data-type="google" value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option> |
| 82 | <option data-type="google" value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05</option> | ||
| 83 | <option data-type="google" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> | 92 | <option data-type="google" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> |
| 84 | <option data-type="google" value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option> | 93 | <option data-type="google" value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option> |
| 85 | <option data-type="google" value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option> | 94 | <option data-type="google" value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option> |
| 86 | <option data-type="google" value="gemini-2.0-flash">gemini-2.0-flash</option> | 95 | <option data-type="google" value="gemini-exp-1206">gemini-exp-1206 → 2.5-pro-exp-03-25</option> |
| 87 | <option data-type="google" value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> | 96 | <option data-type="google" value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> |
| 88 | <option data-type="google" value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option> | ||
| 89 | <option data-type="google" value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option> | 97 | <option data-type="google" value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option> |
| 90 | <option data-type="google" value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp</option> | 98 | <option data-type="google" value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option> |
| 91 | <option data-type="google" value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21</option> | 99 | <option data-type="google" value="gemini-2.0-flash">gemini-2.0-flash</option> |
| 92 | <option data-type="google" value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219</option> | 100 | <option data-type="google" value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21 → 2.5-flash-preview-04-17</option> |
| 93 | <option data-type="google" value="gemini-1.5-flash">gemini-1.5-flash</option> | 101 | <option data-type="google" value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219 → 2.5-flash-preview-04-17</option> |
| 102 | <option data-type="google" value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp → 2.5-flash-preview-04-17</option> | ||
| 103 | <option data-type="google" value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option> | ||
| 104 | <option data-type="google" value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option> | ||
| 105 | <option data-type="google" value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option> | ||
| 106 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | ||
| 107 | <option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option> | ||
| 108 | <option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> | ||
| 109 | <option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option> | ||
| 94 | <option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> | 110 | <option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> |
| 95 | <option data-type="google" value="gemini-1.5-flash-001">gemini-1.5-flash-001</option> | ||
| 96 | <option data-type="google" value="gemini-1.5-flash-002">gemini-1.5-flash-002</option> | 111 | <option data-type="google" value="gemini-1.5-flash-002">gemini-1.5-flash-002</option> |
| 97 | <option data-type="google" value="gemini-1.5-flash-exp-0827">gemini-1.5-flash-exp-0827</option> | 112 | <option data-type="google" value="gemini-1.5-flash-001">gemini-1.5-flash-001</option> |
| 98 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> | 113 | <option data-type="google" value="gemini-1.5-flash">gemini-1.5-flash</option> |
| 114 | <option data-type="google" value="gemini-1.5-flash-8b-001">gemini-1.5-flash-8b-001</option> | ||
| 99 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> | 115 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> |
| 100 | <option data-type="google" value="gemini-exp-1114">gemini-exp-1114</option> | 116 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> |
| 101 | <option data-type="google" value="gemini-exp-1121">gemini-exp-1121</option> | 117 | <option data-type="google" value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option> |
| 102 | <option data-type="google" value="gemini-exp-1206">gemini-exp-1206</option> | 118 | <option data-type="google" value="learnlm-1.5-pro-experimental">learnlm-1.5-pro-experimental</option> |
| 103 | <option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option> | 119 | <option data-type="vertexai" value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> |
| 104 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | 120 | <option data-type="vertexai" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> |
| 105 | <option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> | 121 | <option data-type="vertexai" value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option> |
| 106 | <option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option> | 122 | <option data-type="vertexai" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> |
| 107 | <option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option> | 123 | <option data-type="vertexai" value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> |
| 108 | <option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option> | 124 | <option data-type="vertexai" value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option> |
| 109 | <option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option> | 125 | <option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option> |
| 110 | <option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option> | 126 | <option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option> |
| 111 | <option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option> | 127 | <option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option> |
| @@ -148,12 +164,24 @@ | |||
| 148 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> | 164 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> |
| 149 | <option data-type="xai" value="grok-2-vision-1212">grok-2-vision-1212</option> | 165 | <option data-type="xai" value="grok-2-vision-1212">grok-2-vision-1212</option> |
| 150 | <option data-type="xai" value="grok-vision-beta">grok-vision-beta</option> | 166 | <option data-type="xai" value="grok-vision-beta">grok-vision-beta</option> |
| 167 | <option data-type="pollinations" value="openai">openai</option> | ||
| 168 | <option data-type="pollinations" value="openai-fast">openai-fast</option> | ||
| 169 | <option data-type="pollinations" value="openai-large">openai-large</option> | ||
| 170 | <option data-type="pollinations" value="openai-roblox">openai-roblox</option> | ||
| 171 | <option data-type="pollinations" value="mistral">mistral</option> | ||
| 172 | <option data-type="pollinations" value="unity">unity</option> | ||
| 173 | <option data-type="pollinations" value="mirexa">mirexa</option> | ||
| 174 | <option data-type="pollinations" value="searchgpt">searchgpt</option> | ||
| 175 | <option data-type="pollinations" value="evil">evil</option> | ||
| 176 | <option data-type="pollinations" value="phi">phi</option> | ||
| 177 | <option data-type="pollinations" value="sur">sur</option> | ||
| 178 | <option data-type="pollinations" value="bidara">bidara</option> | ||
| 151 | </select> | 179 | </select> |
| 152 | </div> | 180 | </div> |
| 153 | <div data-type="ollama"> | 181 | <div data-type="ollama"> |
| 154 | The model must be downloaded first! Do it with the <code>ollama pull</code> command or <a href="#" id="caption_ollama_pull">click here</a>. | 182 | The model must be downloaded first! Do it with the <code>ollama pull</code> command or <a href="#" id="caption_ollama_pull">click here</a>. |
| 155 | </div> | 183 | </div> |
| 156 | <label data-type="openai,anthropic,google,mistral" class="checkbox_label flexBasis100p" for="caption_allow_reverse_proxy" title="Allow using reverse proxy if defined and valid."> | 184 | <label data-type="openai,anthropic,google,vertexai,mistral,xai" class="checkbox_label flexBasis100p" for="caption_allow_reverse_proxy" title="Allow using reverse proxy if defined and valid."> |
| 157 | <input id="caption_allow_reverse_proxy" type="checkbox" class="checkbox"> | 185 | <input id="caption_allow_reverse_proxy" type="checkbox" class="checkbox"> |
| 158 | <span data-i18n="Allow reverse proxy">Allow reverse proxy</span> | 186 | <span data-i18n="Allow reverse proxy">Allow reverse proxy</span> |
| 159 | </label> | 187 | </label> |
| @@ -161,6 +189,16 @@ | |||
| 161 | <small><b data-i18n="Hint:">Hint:</b> <span data-i18n="Set your API keys and endpoints in the 'API Connections' tab first.">Set your API keys and endpoints in the 'API Connections' tab first.</span></small> | 189 | <small><b data-i18n="Hint:">Hint:</b> <span data-i18n="Set your API keys and endpoints in the 'API Connections' tab first.">Set your API keys and endpoints in the 'API Connections' tab first.</span></small> |
| 162 | </div> | 190 | </div> |
| 163 | </div> | 191 | </div> |
| 192 | <div data-type="koboldcpp,ollama,vllm,llamacpp,ooba" class="flex-container flexFlowColumn"> | ||
| 193 | <label for="caption_altEndpoint_enabled" class="checkbox_label"> | ||
| 194 | <input id="caption_altEndpoint_enabled" type="checkbox"> | ||
| 195 | <span data-i18n="Use secondary URL">Use secondary URL</span> | ||
| 196 | </label> | ||
| 197 | <label for="caption_altEndpoint_url" data-i18n="Secondary captioning endpoint URL"> | ||
| 198 | Secondary captioning endpoint URL | ||
| 199 | </label> | ||
| 200 | <input id="caption_altEndpoint_url" class="text_pole" type="text" placeholder="e.g. http://localhost:5001" /> | ||
| 201 | </div> | ||
| 164 | <div id="caption_prompt_block"> | 202 | <div id="caption_prompt_block"> |
| 165 | <label for="caption_prompt" data-i18n="Caption Prompt">Caption Prompt</label> | 203 | <label for="caption_prompt" data-i18n="Caption Prompt">Caption Prompt</label> |
| 166 | <textarea id="caption_prompt" class="text_pole" rows="1" placeholder="< Use default >">{{PROMPT_DEFAULT}}</textarea> | 204 | <textarea id="caption_prompt" class="text_pole" rows="1" placeholder="< Use default >">{{PROMPT_DEFAULT}}</textarea> |
| @@ -710,7 +710,7 @@ async function listGalleryCommand(args) { | |||
| 710 | delete context.extensionSettings.gallery.folders[avatar]; | 710 | delete context.extensionSettings.gallery.folders[avatar]; |
| 711 | context.saveSettingsDebounced(); | 711 | context.saveSettingsDebounced(); |
| 712 | }); | 712 | }); |
| 713 | eventSource.on('charManagementDropdown', (selectedOptionId) => { | 713 | eventSource.on(event_types.CHARACTER_MANAGEMENT_DROPDOWN, (selectedOptionId) => { |
| 714 | if (selectedOptionId === 'show_char_gallery') { | 714 | if (selectedOptionId === 'show_char_gallery') { |
| 715 | showCharGallery(); | 715 | showCharGallery(); |
| 716 | } | 716 | } |
| @@ -28,6 +28,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from ' | |||
| 28 | import { MacrosParser } from '../../macros.js'; | 28 | import { MacrosParser } from '../../macros.js'; |
| 29 | import { countWebLlmTokens, generateWebLlmChatPrompt, getWebLlmContextSize, isWebLlmSupported } from '../shared.js'; | 29 | import { countWebLlmTokens, generateWebLlmChatPrompt, getWebLlmContextSize, isWebLlmSupported } from '../shared.js'; |
| 30 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | 30 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 31 | import { removeReasoningFromString } from '../../reasoning.js'; | ||
| 31 | export { MODULE_NAME }; | 32 | export { MODULE_NAME }; |
| 32 | 33 | ||
| 33 | const MODULE_NAME = '1_memory'; | 34 | const MODULE_NAME = '1_memory'; |
| @@ -504,7 +505,7 @@ async function summarizeCallback(args, text) { | |||
| 504 | case summary_sources.extras: | 505 | case summary_sources.extras: |
| 505 | return await callExtrasSummarizeAPI(text); | 506 | return await callExtrasSummarizeAPI(text); |
| 506 | case summary_sources.main: | 507 | case summary_sources.main: |
| 507 | return await generateRaw(text, '', false, false, prompt, extension_settings.memory.overrideResponseLength); | 508 | return removeReasoningFromString(await generateRaw(text, '', false, false, prompt, extension_settings.memory.overrideResponseLength)); |
| 508 | case summary_sources.webllm: { | 509 | case summary_sources.webllm: { |
| 509 | const messages = [{ role: 'system', content: prompt }, { role: 'user', content: text }].filter(m => m.content); | 510 | const messages = [{ role: 'system', content: prompt }, { role: 'user', content: text }].filter(m => m.content); |
| 510 | const params = extension_settings.memory.overrideResponseLength > 0 ? { max_tokens: extension_settings.memory.overrideResponseLength } : {}; | 511 | const params = extension_settings.memory.overrideResponseLength > 0 ? { max_tokens: extension_settings.memory.overrideResponseLength } : {}; |
| @@ -699,7 +700,8 @@ async function summarizeChatMain(context, force, skipWIAN) { | |||
| 699 | return null; | 700 | return null; |
| 700 | } | 701 | } |
| 701 | 702 | ||
| 702 | summary = await generateRaw(rawPrompt, '', false, false, prompt, extension_settings.memory.overrideResponseLength); | 703 | const rawSummary = await generateRaw(rawPrompt, '', false, false, prompt, extension_settings.memory.overrideResponseLength); |
| 704 | summary = removeReasoningFromString(rawSummary); | ||
| 703 | index = lastUsedIndex; | 705 | index = lastUsedIndex; |
| 704 | } finally { | 706 | } finally { |
| 705 | inApiCall = false; | 707 | inApiCall = false; |
| @@ -15,14 +15,14 @@ import { createThumbnail, isValidUrl } from '../utils.js'; | |||
| 15 | */ | 15 | */ |
| 16 | export async function getMultimodalCaption(base64Img, prompt) { | 16 | export async function getMultimodalCaption(base64Img, prompt) { |
| 17 | const useReverseProxy = | 17 | const useReverseProxy = |
| 18 | (['openai', 'anthropic', 'google', 'mistral'].includes(extension_settings.caption.multimodal_api)) | 18 | (['openai', 'anthropic', 'google', 'mistral', 'vertexai', 'xai'].includes(extension_settings.caption.multimodal_api)) |
| 19 | && extension_settings.caption.allow_reverse_proxy | 19 | && extension_settings.caption.allow_reverse_proxy |
| 20 | && oai_settings.reverse_proxy | 20 | && oai_settings.reverse_proxy |
| 21 | && isValidUrl(oai_settings.reverse_proxy); | 21 | && isValidUrl(oai_settings.reverse_proxy); |
| 22 | 22 | ||
| 23 | throwIfInvalidModel(useReverseProxy); | 23 | throwIfInvalidModel(useReverseProxy); |
| 24 | 24 | ||
| 25 | const noPrefix = ['ollama', 'llamacpp'].includes(extension_settings.caption.multimodal_api); | 25 | const noPrefix = ['ollama'].includes(extension_settings.caption.multimodal_api); |
| 26 | 26 | ||
| 27 | if (noPrefix && base64Img.startsWith('data:image/')) { | 27 | if (noPrefix && base64Img.startsWith('data:image/')) { |
| 28 | base64Img = base64Img.split(',')[1]; | 28 | base64Img = base64Img.split(',')[1]; |
| @@ -38,7 +38,8 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 38 | const isVllm = extension_settings.caption.multimodal_api === 'vllm'; | 38 | const isVllm = extension_settings.caption.multimodal_api === 'vllm'; |
| 39 | const base64Bytes = base64Img.length * 0.75; | 39 | const base64Bytes = base64Img.length * 0.75; |
| 40 | const compressionLimit = 2 * 1024 * 1024; | 40 | const compressionLimit = 2 * 1024 * 1024; |
| 41 | if ((['google', 'openrouter', 'mistral', 'groq'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { | 41 | const thumbnailNeeded = ['google', 'openrouter', 'mistral', 'groq', 'vertexai'].includes(extension_settings.caption.multimodal_api); |
| 42 | if ((thumbnailNeeded && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { | ||
| 42 | const maxSide = 1024; | 43 | const maxSide = 1024; |
| 43 | base64Img = await createThumbnail(base64Img, maxSide, maxSide, 'image/jpeg'); | 44 | base64Img = await createThumbnail(base64Img, maxSide, maxSide, 'image/jpeg'); |
| 44 | } | 45 | } |
| @@ -60,7 +61,9 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 60 | requestBody.model = textgenerationwebui_settings.ollama_model; | 61 | requestBody.model = textgenerationwebui_settings.ollama_model; |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; | 64 | requestBody.server_url = extension_settings.caption.alt_endpoint_enabled |
| 65 | ? extension_settings.caption.alt_endpoint_url | ||
| 66 | : textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; | ||
| 64 | } | 67 | } |
| 65 | 68 | ||
| 66 | if (isVllm) { | 69 | if (isVllm) { |
| @@ -68,19 +71,27 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 68 | requestBody.model = textgenerationwebui_settings.vllm_model; | 71 | requestBody.model = textgenerationwebui_settings.vllm_model; |
| 69 | } | 72 | } |
| 70 | 73 | ||
| 71 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.VLLM]; | 74 | requestBody.server_url = extension_settings.caption.alt_endpoint_enabled |
| 75 | ? extension_settings.caption.alt_endpoint_url | ||
| 76 | : textgenerationwebui_settings.server_urls[textgen_types.VLLM]; | ||
| 72 | } | 77 | } |
| 73 | 78 | ||
| 74 | if (isLlamaCpp) { | 79 | if (isLlamaCpp) { |
| 75 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; | 80 | requestBody.server_url = extension_settings.caption.alt_endpoint_enabled |
| 81 | ? extension_settings.caption.alt_endpoint_url | ||
| 82 | : textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; | ||
| 76 | } | 83 | } |
| 77 | 84 | ||
| 78 | if (isOoba) { | 85 | if (isOoba) { |
| 79 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OOBA]; | 86 | requestBody.server_url = extension_settings.caption.alt_endpoint_enabled |
| 87 | ? extension_settings.caption.alt_endpoint_url | ||
| 88 | : textgenerationwebui_settings.server_urls[textgen_types.OOBA]; | ||
| 80 | } | 89 | } |
| 81 | 90 | ||
| 82 | if (isKoboldCpp) { | 91 | if (isKoboldCpp) { |
| 83 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]; | 92 | requestBody.server_url = extension_settings.caption.alt_endpoint_enabled |
| 93 | ? extension_settings.caption.alt_endpoint_url | ||
| 94 | : textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]; | ||
| 84 | } | 95 | } |
| 85 | 96 | ||
| 86 | if (isCustom) { | 97 | if (isCustom) { |
| @@ -94,11 +105,10 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 94 | function getEndpointUrl() { | 105 | function getEndpointUrl() { |
| 95 | switch (extension_settings.caption.multimodal_api) { | 106 | switch (extension_settings.caption.multimodal_api) { |
| 96 | case 'google': | 107 | case 'google': |
| 108 | case 'vertexai': | ||
| 97 | return '/api/google/caption-image'; | 109 | return '/api/google/caption-image'; |
| 98 | case 'anthropic': | 110 | case 'anthropic': |
| 99 | return '/api/anthropic/caption-image'; | 111 | return '/api/anthropic/caption-image'; |
| 100 | case 'llamacpp': | ||
| 101 | return '/api/backends/text-completions/llamacpp/caption-image'; | ||
| 102 | case 'ollama': | 112 | case 'ollama': |
| 103 | return '/api/backends/text-completions/ollama/caption-image'; | 113 | return '/api/backends/text-completions/ollama/caption-image'; |
| 104 | default: | 114 | default: |
| @@ -121,71 +131,84 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 121 | } | 131 | } |
| 122 | 132 | ||
| 123 | function throwIfInvalidModel(useReverseProxy) { | 133 | function throwIfInvalidModel(useReverseProxy) { |
| 124 | if (extension_settings.caption.multimodal_api === 'openai' && !secret_state[SECRET_KEYS.OPENAI] && !useReverseProxy) { | 134 | const altEndpointEnabled = extension_settings.caption.alt_endpoint_enabled; |
| 135 | const altEndpointUrl = extension_settings.caption.alt_endpoint_url; | ||
| 136 | const multimodalModel = extension_settings.caption.multimodal_model; | ||
| 137 | const multimodalApi = extension_settings.caption.multimodal_api; | ||
| 138 | |||
| 139 | if (altEndpointEnabled && ['llamacpp', 'ooba', 'koboldcpp', 'vllm', 'ollama'].includes(multimodalApi) && !altEndpointUrl) { | ||
| 140 | throw new Error('Secondary endpoint URL is not set.'); | ||
| 141 | } | ||
| 142 | |||
| 143 | if (multimodalApi === 'openai' && !secret_state[SECRET_KEYS.OPENAI] && !useReverseProxy) { | ||
| 125 | throw new Error('OpenAI API key is not set.'); | 144 | throw new Error('OpenAI API key is not set.'); |
| 126 | } | 145 | } |
| 127 | 146 | ||
| 128 | if (extension_settings.caption.multimodal_api === 'openrouter' && !secret_state[SECRET_KEYS.OPENROUTER]) { | 147 | if (multimodalApi === 'openrouter' && !secret_state[SECRET_KEYS.OPENROUTER]) { |
| 129 | throw new Error('OpenRouter API key is not set.'); | 148 | throw new Error('OpenRouter API key is not set.'); |
| 130 | } | 149 | } |
| 131 | 150 | ||
| 132 | if (extension_settings.caption.multimodal_api === 'anthropic' && !secret_state[SECRET_KEYS.CLAUDE] && !useReverseProxy) { | 151 | if (multimodalApi === 'anthropic' && !secret_state[SECRET_KEYS.CLAUDE] && !useReverseProxy) { |
| 133 | throw new Error('Anthropic (Claude) API key is not set.'); | 152 | throw new Error('Anthropic (Claude) API key is not set.'); |
| 134 | } | 153 | } |
| 135 | 154 | ||
| 136 | if (extension_settings.caption.multimodal_api === 'zerooneai' && !secret_state[SECRET_KEYS.ZEROONEAI]) { | 155 | if (multimodalApi === 'zerooneai' && !secret_state[SECRET_KEYS.ZEROONEAI]) { |
| 137 | throw new Error('01.AI API key is not set.'); | 156 | throw new Error('01.AI API key is not set.'); |
| 138 | } | 157 | } |
| 139 | 158 | ||
| 140 | if (extension_settings.caption.multimodal_api === 'groq' && !secret_state[SECRET_KEYS.GROQ]) { | 159 | if (multimodalApi === 'groq' && !secret_state[SECRET_KEYS.GROQ]) { |
| 141 | throw new Error('Groq API key is not set.'); | 160 | throw new Error('Groq API key is not set.'); |
| 142 | } | 161 | } |
| 143 | 162 | ||
| 144 | if (extension_settings.caption.multimodal_api === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) { | 163 | if (multimodalApi === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) { |
| 145 | throw new Error('Google AI Studio API key is not set.'); | 164 | throw new Error('Google AI Studio API key is not set.'); |
| 146 | } | 165 | } |
| 147 | 166 | ||
| 148 | if (extension_settings.caption.multimodal_api === 'mistral' && !secret_state[SECRET_KEYS.MISTRALAI] && !useReverseProxy) { | 167 | if (multimodalApi === 'vertexai' && !secret_state[SECRET_KEYS.VERTEXAI] && !useReverseProxy) { |
| 168 | throw new Error('Google Vertex AI API key is not set.'); | ||
| 169 | } | ||
| 170 | |||
| 171 | if (multimodalApi === 'mistral' && !secret_state[SECRET_KEYS.MISTRALAI] && !useReverseProxy) { | ||
| 149 | throw new Error('Mistral AI API key is not set.'); | 172 | throw new Error('Mistral AI API key is not set.'); |
| 150 | } | 173 | } |
| 151 | 174 | ||
| 152 | if (extension_settings.caption.multimodal_api === 'cohere' && !secret_state[SECRET_KEYS.COHERE]) { | 175 | if (multimodalApi === 'cohere' && !secret_state[SECRET_KEYS.COHERE]) { |
| 153 | throw new Error('Cohere API key is not set.'); | 176 | throw new Error('Cohere API key is not set.'); |
| 154 | } | 177 | } |
| 155 | 178 | ||
| 156 | if (extension_settings.caption.multimodal_api === 'xai' && !secret_state[SECRET_KEYS.XAI]) { | 179 | if (multimodalApi === 'xai' && !secret_state[SECRET_KEYS.XAI] && !useReverseProxy) { |
| 157 | throw new Error('xAI API key is not set.'); | 180 | throw new Error('xAI API key is not set.'); |
| 158 | } | 181 | } |
| 159 | 182 | ||
| 160 | if (extension_settings.caption.multimodal_api === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]) { | 183 | if (multimodalApi === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA] && !altEndpointEnabled) { |
| 161 | throw new Error('Ollama server URL is not set.'); | 184 | throw new Error('Ollama server URL is not set.'); |
| 162 | } | 185 | } |
| 163 | 186 | ||
| 164 | if (extension_settings.caption.multimodal_api === 'ollama' && extension_settings.caption.multimodal_model === 'ollama_current' && !textgenerationwebui_settings.ollama_model) { | 187 | if (multimodalApi === 'ollama' && multimodalModel === 'ollama_current' && !textgenerationwebui_settings.ollama_model) { |
| 165 | throw new Error('Ollama model is not set.'); | 188 | throw new Error('Ollama model is not set.'); |
| 166 | } | 189 | } |
| 167 | 190 | ||
| 168 | if (extension_settings.caption.multimodal_api === 'llamacpp' && !textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) { | 191 | if (multimodalApi === 'llamacpp' && !textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP] && !altEndpointEnabled) { |
| 169 | throw new Error('LlamaCPP server URL is not set.'); | 192 | throw new Error('LlamaCPP server URL is not set.'); |
| 170 | } | 193 | } |
| 171 | 194 | ||
| 172 | if (extension_settings.caption.multimodal_api === 'ooba' && !textgenerationwebui_settings.server_urls[textgen_types.OOBA]) { | 195 | if (multimodalApi === 'ooba' && !textgenerationwebui_settings.server_urls[textgen_types.OOBA] && !altEndpointEnabled) { |
| 173 | throw new Error('Text Generation WebUI server URL is not set.'); | 196 | throw new Error('Text Generation WebUI server URL is not set.'); |
| 174 | } | 197 | } |
| 175 | 198 | ||
| 176 | if (extension_settings.caption.multimodal_api === 'koboldcpp' && !textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) { | 199 | if (multimodalApi === 'koboldcpp' && !textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP] && !altEndpointEnabled) { |
| 177 | throw new Error('KoboldCpp server URL is not set.'); | 200 | throw new Error('KoboldCpp server URL is not set.'); |
| 178 | } | 201 | } |
| 179 | 202 | ||
| 180 | if (extension_settings.caption.multimodal_api === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM]) { | 203 | if (multimodalApi === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM] && !altEndpointEnabled) { |
| 181 | throw new Error('vLLM server URL is not set.'); | 204 | throw new Error('vLLM server URL is not set.'); |
| 182 | } | 205 | } |
| 183 | 206 | ||
| 184 | if (extension_settings.caption.multimodal_api === 'vllm' && extension_settings.caption.multimodal_model === 'vllm_current' && !textgenerationwebui_settings.vllm_model) { | 207 | if (multimodalApi === 'vllm' && multimodalModel === 'vllm_current' && !textgenerationwebui_settings.vllm_model) { |
| 185 | throw new Error('vLLM model is not set.'); | 208 | throw new Error('vLLM model is not set.'); |
| 186 | } | 209 | } |
| 187 | 210 | ||
| 188 | if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) { | 211 | if (multimodalApi === 'custom' && !oai_settings.custom_url) { |
| 189 | throw new Error('Custom API URL is not set.'); | 212 | throw new Error('Custom API URL is not set.'); |
| 190 | } | 213 | } |
| 191 | } | 214 | } |
| @@ -56,6 +56,8 @@ import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValu | |||
| 56 | import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; | 56 | import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; |
| 57 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | 57 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 58 | import { ToolManager } from '../../tool-calling.js'; | 58 | import { ToolManager } from '../../tool-calling.js'; |
| 59 | import { MacrosParser } from '../../macros.js'; | ||
| 60 | import { t } from '../../i18n.js'; | ||
| 59 | 61 | ||
| 60 | export { MODULE_NAME }; | 62 | export { MODULE_NAME }; |
| 61 | 63 | ||
| @@ -930,6 +932,10 @@ const resolutionOptions = { | |||
| 930 | sd_res_768x1344: { width: 768, height: 1344, name: '768x1344 (3:4, SDXL)' }, | 932 | sd_res_768x1344: { width: 768, height: 1344, name: '768x1344 (3:4, SDXL)' }, |
| 931 | sd_res_1536x640: { width: 1536, height: 640, name: '1536x640 (24:10, SDXL)' }, | 933 | sd_res_1536x640: { width: 1536, height: 640, name: '1536x640 (24:10, SDXL)' }, |
| 932 | sd_res_640x1536: { width: 640, height: 1536, name: '640x1536 (10:24, SDXL)' }, | 934 | sd_res_640x1536: { width: 640, height: 1536, name: '640x1536 (10:24, SDXL)' }, |
| 935 | sd_res_1536x1024: { width: 1536, height: 1024, name: '1536x1024 (3:2, ChatGPT)' }, | ||
| 936 | sd_res_1024x1536: { width: 1024, height: 1536, name: '1024x1536 (2:3, ChatGPT)' }, | ||
| 937 | sd_res_1024x1792: { width: 1024, height: 1792, name: '1024x1792 (4:7, DALL-E)' }, | ||
| 938 | sd_res_1792x1024: { width: 1792, height: 1024, name: '1792x1024 (7:4, DALL-E)' }, | ||
| 933 | }; | 939 | }; |
| 934 | 940 | ||
| 935 | function onResolutionChange() { | 941 | function onResolutionChange() { |
| @@ -1947,8 +1953,9 @@ async function loadDrawthingsModels() { | |||
| 1947 | 1953 | ||
| 1948 | async function loadOpenAiModels() { | 1954 | async function loadOpenAiModels() { |
| 1949 | return [ | 1955 | return [ |
| 1950 | { value: 'dall-e-3', text: 'DALL-E 3' }, | 1956 | { value: 'gpt-image-1', text: 'gpt-image-1' }, |
| 1951 | { value: 'dall-e-2', text: 'DALL-E 2' }, | 1957 | { value: 'dall-e-3', text: 'dall-e-3' }, |
| 1958 | { value: 'dall-e-2', text: 'dall-e-2' }, | ||
| 1952 | ]; | 1959 | ]; |
| 1953 | } | 1960 | } |
| 1954 | 1961 | ||
| @@ -3250,9 +3257,11 @@ function getNovelParams() { | |||
| 3250 | async function generateOpenAiImage(prompt, signal) { | 3257 | async function generateOpenAiImage(prompt, signal) { |
| 3251 | const dalle2PromptLimit = 1000; | 3258 | const dalle2PromptLimit = 1000; |
| 3252 | const dalle3PromptLimit = 4000; | 3259 | const dalle3PromptLimit = 4000; |
| 3260 | const gptImgPromptLimit = 32000; | ||
| 3253 | 3261 | ||
| 3254 | const isDalle2 = extension_settings.sd.model === 'dall-e-2'; | 3262 | const isDalle2 = extension_settings.sd.model === 'dall-e-2'; |
| 3255 | const isDalle3 = extension_settings.sd.model === 'dall-e-3'; | 3263 | const isDalle3 = extension_settings.sd.model === 'dall-e-3'; |
| 3264 | const isGptImg = extension_settings.sd.model === 'gpt-image-1'; | ||
| 3256 | 3265 | ||
| 3257 | if (isDalle2 && prompt.length > dalle2PromptLimit) { | 3266 | if (isDalle2 && prompt.length > dalle2PromptLimit) { |
| 3258 | prompt = prompt.substring(0, dalle2PromptLimit); | 3267 | prompt = prompt.substring(0, dalle2PromptLimit); |
| @@ -3262,6 +3271,10 @@ async function generateOpenAiImage(prompt, signal) { | |||
| 3262 | prompt = prompt.substring(0, dalle3PromptLimit); | 3271 | prompt = prompt.substring(0, dalle3PromptLimit); |
| 3263 | } | 3272 | } |
| 3264 | 3273 | ||
| 3274 | if (isGptImg && prompt.length > gptImgPromptLimit) { | ||
| 3275 | prompt = prompt.substring(0, gptImgPromptLimit); | ||
| 3276 | } | ||
| 3277 | |||
| 3265 | let width = 1024; | 3278 | let width = 1024; |
| 3266 | let height = 1024; | 3279 | let height = 1024; |
| 3267 | let aspectRatio = extension_settings.sd.width / extension_settings.sd.height; | 3280 | let aspectRatio = extension_settings.sd.width / extension_settings.sd.height; |
| @@ -3274,6 +3287,14 @@ async function generateOpenAiImage(prompt, signal) { | |||
| 3274 | width = 1792; | 3287 | width = 1792; |
| 3275 | } | 3288 | } |
| 3276 | 3289 | ||
| 3290 | if (isGptImg && aspectRatio < 1) { | ||
| 3291 | height = 1536; | ||
| 3292 | } | ||
| 3293 | |||
| 3294 | if (isGptImg && aspectRatio > 1) { | ||
| 3295 | width = 1536; | ||
| 3296 | } | ||
| 3297 | |||
| 3277 | if (isDalle2 && (extension_settings.sd.width <= 512 && extension_settings.sd.height <= 512)) { | 3298 | if (isDalle2 && (extension_settings.sd.width <= 512 && extension_settings.sd.height <= 512)) { |
| 3278 | width = 512; | 3299 | width = 512; |
| 3279 | height = 512; | 3300 | height = 512; |
| @@ -3290,7 +3311,8 @@ async function generateOpenAiImage(prompt, signal) { | |||
| 3290 | n: 1, | 3311 | n: 1, |
| 3291 | quality: isDalle3 ? extension_settings.sd.openai_quality : undefined, | 3312 | quality: isDalle3 ? extension_settings.sd.openai_quality : undefined, |
| 3292 | style: isDalle3 ? extension_settings.sd.openai_style : undefined, | 3313 | style: isDalle3 ? extension_settings.sd.openai_style : undefined, |
| 3293 | response_format: 'b64_json', | 3314 | response_format: isDalle2 || isDalle3 ? 'b64_json' : undefined, |
| 3315 | moderation: isGptImg ? 'low' : undefined, | ||
| 3294 | }), | 3316 | }), |
| 3295 | }); | 3317 | }); |
| 3296 | 3318 | ||
| @@ -4528,4 +4550,29 @@ jQuery(async () => { | |||
| 4528 | 4550 | ||
| 4529 | await loadSettings(); | 4551 | await loadSettings(); |
| 4530 | $('body').addClass('sd'); | 4552 | $('body').addClass('sd'); |
| 4553 | |||
| 4554 | const getMacroValue = ({ isNegative }) => { | ||
| 4555 | if (selected_group || this_chid === undefined) { | ||
| 4556 | return ''; | ||
| 4557 | } | ||
| 4558 | |||
| 4559 | const key = getCharaFilename(this_chid); | ||
| 4560 | let characterPrompt = key ? (extension_settings.sd.character_prompts[key] || '') : ''; | ||
| 4561 | let negativePrompt = key ? (extension_settings.sd.character_negative_prompts[key] || '') : ''; | ||
| 4562 | |||
| 4563 | const context = getContext(); | ||
| 4564 | const sharedPromptData = context?.characters[this_chid]?.data?.extensions?.sd_character_prompt; | ||
| 4565 | |||
| 4566 | if (typeof sharedPromptData?.positive === 'string' && !characterPrompt && sharedPromptData.positive) { | ||
| 4567 | characterPrompt = sharedPromptData.positive || ''; | ||
| 4568 | } | ||
| 4569 | if (typeof sharedPromptData?.negative === 'string' && !negativePrompt && sharedPromptData.negative) { | ||
| 4570 | negativePrompt = sharedPromptData.negative || ''; | ||
| 4571 | } | ||
| 4572 | |||
| 4573 | return isNegative ? negativePrompt : characterPrompt; | ||
| 4574 | }; | ||
| 4575 | |||
| 4576 | MacrosParser.registerMacro('charPrefix', () => getMacroValue({ isNegative: false }), t`Character's positive positive Image Generation prompt prefix`); | ||
| 4577 | MacrosParser.registerMacro('charNegativePrefix', () => getMacroValue({ isNegative: true }), t`Character's negative Image Generation prompt prefix`); | ||
| 4531 | }); | 4578 | }); |
| @@ -45,7 +45,7 @@ | |||
| 45 | <option value="huggingface">HuggingFace Inference API (serverless)</option> | 45 | <option value="huggingface">HuggingFace Inference API (serverless)</option> |
| 46 | <option value="nanogpt">NanoGPT</option> | 46 | <option value="nanogpt">NanoGPT</option> |
| 47 | <option value="novel">NovelAI Diffusion</option> | 47 | <option value="novel">NovelAI Diffusion</option> |
| 48 | <option value="openai">OpenAI (DALL-E)</option> | 48 | <option value="openai">OpenAI</option> |
| 49 | <option value="pollinations">Pollinations</option> | 49 | <option value="pollinations">Pollinations</option> |
| 50 | <option value="vlad">SD.Next (vladmandic)</option> | 50 | <option value="vlad">SD.Next (vladmandic)</option> |
| 51 | <option value="stability">Stability AI</option> | 51 | <option value="stability">Stability AI</option> |
| @@ -36,6 +36,7 @@ import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandRetur | |||
| 36 | import { callGenericPopup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; | 36 | import { callGenericPopup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; |
| 37 | import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js'; | 37 | import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js'; |
| 38 | import { WebLlmVectorProvider } from './webllm.js'; | 38 | import { WebLlmVectorProvider } from './webllm.js'; |
| 39 | import { removeReasoningFromString } from '../../reasoning.js'; | ||
| 39 | 40 | ||
| 40 | /** | 41 | /** |
| 41 | * @typedef {object} HashedMessage | 42 | * @typedef {object} HashedMessage |
| @@ -260,7 +261,7 @@ async function summarizeExtra(element) { | |||
| 260 | * @returns {Promise<boolean>} Sucess | 261 | * @returns {Promise<boolean>} Sucess |
| 261 | */ | 262 | */ |
| 262 | async function summarizeMain(element) { | 263 | async function summarizeMain(element) { |
| 263 | element.text = await generateRaw(element.text, '', false, false, settings.summary_prompt); | 264 | element.text = removeReasoningFromString(await generateRaw(element.text, '', false, false, settings.summary_prompt)); |
| 264 | return true; | 265 | return true; |
| 265 | } | 266 | } |
| 266 | 267 | ||
| @@ -829,11 +830,12 @@ async function getAdditionalArgs(items) { | |||
| 829 | * @returns {Promise<number[]>} Saved hashes | 830 | * @returns {Promise<number[]>} Saved hashes |
| 830 | */ | 831 | */ |
| 831 | async function getSavedHashes(collectionId) { | 832 | async function getSavedHashes(collectionId) { |
| 833 | const args = await getAdditionalArgs([]); | ||
| 832 | const response = await fetch('/api/vector/list', { | 834 | const response = await fetch('/api/vector/list', { |
| 833 | method: 'POST', | 835 | method: 'POST', |
| 834 | headers: getRequestHeaders(), | 836 | headers: getRequestHeaders(), |
| 835 | body: JSON.stringify({ | 837 | body: JSON.stringify({ |
| 836 | ...getVectorsRequestBody(), | 838 | ...getVectorsRequestBody(args), |
| 837 | collectionId: collectionId, | 839 | collectionId: collectionId, |
| 838 | source: settings.source, | 840 | source: settings.source, |
| 839 | }), | 841 | }), |
| @@ -1155,6 +1157,9 @@ function loadWebLlmModels() { | |||
| 1155 | * @returns {Promise<Record<string, number[]>>} Calculated embeddings | 1157 | * @returns {Promise<Record<string, number[]>>} Calculated embeddings |
| 1156 | */ | 1158 | */ |
| 1157 | async function createWebLlmEmbeddings(items) { | 1159 | async function createWebLlmEmbeddings(items) { |
| 1160 | if (items.length === 0) { | ||
| 1161 | return /** @type {Record<string, number[]>} */ ({}); | ||
| 1162 | } | ||
| 1158 | return executeWithWebLlmErrorHandling(async () => { | 1163 | return executeWithWebLlmErrorHandling(async () => { |
| 1159 | const embeddings = await webllmProvider.embedTexts(items, settings.webllm_model); | 1164 | const embeddings = await webllmProvider.embedTexts(items, settings.webllm_model); |
| 1160 | const result = /** @type {Record<string, number[]>} */ ({}); | 1165 | const result = /** @type {Record<string, number[]>} */ ({}); |
| @@ -97,6 +97,7 @@ | |||
| 97 | Vectorization Model | 97 | Vectorization Model |
| 98 | </label> | 98 | </label> |
| 99 | <select id="vectors_cohere_model" class="text_pole"> | 99 | <select id="vectors_cohere_model" class="text_pole"> |
| 100 | <option value="embed-v4.0">embed-v4.0</option> | ||
| 100 | <option value="embed-english-v3.0">embed-english-v3.0</option> | 101 | <option value="embed-english-v3.0">embed-english-v3.0</option> |
| 101 | <option value="embed-multilingual-v3.0">embed-multilingual-v3.0</option> | 102 | <option value="embed-multilingual-v3.0">embed-multilingual-v3.0</option> |
| 102 | <option value="embed-english-light-v3.0">embed-english-light-v3.0</option> | 103 | <option value="embed-english-light-v3.0">embed-english-light-v3.0</option> |
| @@ -13,6 +13,10 @@ import { | |||
| 13 | getBase64Async, | 13 | getBase64Async, |
| 14 | resetScrollHeight, | 14 | resetScrollHeight, |
| 15 | initScrollHeight, | 15 | initScrollHeight, |
| 16 | localizePagination, | ||
| 17 | renderPaginationDropdown, | ||
| 18 | paginationDropdownChangeHandler, | ||
| 19 | waitUntilCondition, | ||
| 16 | } from './utils.js'; | 20 | } from './utils.js'; |
| 17 | import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap, getMessageTimeStamp } from './RossAscends-mods.js'; | 21 | import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap, getMessageTimeStamp } from './RossAscends-mods.js'; |
| 18 | import { power_user, loadMovingUIState, sortEntitiesList } from './power-user.js'; | 22 | import { power_user, loadMovingUIState, sortEntitiesList } from './power-user.js'; |
| @@ -101,7 +105,7 @@ export { | |||
| 101 | 105 | ||
| 102 | let is_group_generating = false; // Group generation flag | 106 | let is_group_generating = false; // Group generation flag |
| 103 | let is_group_automode_enabled = false; | 107 | let is_group_automode_enabled = false; |
| 104 | let hideMutedSprites = true; | 108 | let hideMutedSprites = false; |
| 105 | let groups = []; | 109 | let groups = []; |
| 106 | let selected_group = null; | 110 | let selected_group = null; |
| 107 | let group_generation_id = null; | 111 | let group_generation_id = null; |
| @@ -203,6 +207,16 @@ async function validateGroup(group) { | |||
| 203 | return character; | 207 | return character; |
| 204 | }); | 208 | }); |
| 205 | 209 | ||
| 210 | // Remove duplicate chat ids | ||
| 211 | if (Array.isArray(group.chats)) { | ||
| 212 | const lengthBefore = group.chats.length; | ||
| 213 | group.chats = group.chats.filter(onlyUnique); | ||
| 214 | const lengthAfter = group.chats.length; | ||
| 215 | if (lengthBefore !== lengthAfter) { | ||
| 216 | dirty = true; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 206 | if (dirty) { | 220 | if (dirty) { |
| 207 | await editGroup(group.id, true, false); | 221 | await editGroup(group.id, true, false); |
| 208 | } | 222 | } |
| @@ -216,11 +230,12 @@ export async function getGroupChat(groupId, reload = false) { | |||
| 216 | } | 230 | } |
| 217 | 231 | ||
| 218 | // Run validation before any loading | 232 | // Run validation before any loading |
| 219 | validateGroup(group); | 233 | await validateGroup(group); |
| 220 | await unshallowGroupMembers(groupId); | 234 | await unshallowGroupMembers(groupId); |
| 221 | 235 | ||
| 222 | const chat_id = group.chat_id; | 236 | const chat_id = group.chat_id; |
| 223 | const data = await loadGroupChat(chat_id); | 237 | const data = await loadGroupChat(chat_id); |
| 238 | const metadata = group.chat_metadata ?? {}; | ||
| 224 | let freshChat = false; | 239 | let freshChat = false; |
| 225 | 240 | ||
| 226 | await loadItemizedPrompts(getCurrentChatId()); | 241 | await loadItemizedPrompts(getCurrentChatId()); |
| @@ -230,7 +245,8 @@ export async function getGroupChat(groupId, reload = false) { | |||
| 230 | chat.splice(0, chat.length, ...data); | 245 | chat.splice(0, chat.length, ...data); |
| 231 | await printMessages(); | 246 | await printMessages(); |
| 232 | } else { | 247 | } else { |
| 233 | if (group && Array.isArray(group.members)) { | 248 | freshChat = !metadata.tainted; |
| 249 | if (group && Array.isArray(group.members) && freshChat) { | ||
| 234 | for (let member of group.members) { | 250 | for (let member of group.members) { |
| 235 | const character = characters.find(x => x.avatar === member || x.name === member); | 251 | const character = characters.find(x => x.avatar === member || x.name === member); |
| 236 | if (!character) { | 252 | if (!character) { |
| @@ -249,12 +265,10 @@ export async function getGroupChat(groupId, reload = false) { | |||
| 249 | addOneMessage(mes); | 265 | addOneMessage(mes); |
| 250 | await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, (chat.length - 1), 'first_message'); | 266 | await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, (chat.length - 1), 'first_message'); |
| 251 | } | 267 | } |
| 252 | } | ||
| 253 | await saveGroupChat(groupId, false); | 268 | await saveGroupChat(groupId, false); |
| 254 | freshChat = true; | 269 | } |
| 255 | } | 270 | } |
| 256 | 271 | ||
| 257 | let metadata = group.chat_metadata ?? {}; | ||
| 258 | updateChatMetadata(metadata, true); | 272 | updateChatMetadata(metadata, true); |
| 259 | 273 | ||
| 260 | if (reload) { | 274 | if (reload) { |
| @@ -701,7 +715,7 @@ export function getGroupBlock(group) { | |||
| 701 | 715 | ||
| 702 | // Display inline tags | 716 | // Display inline tags |
| 703 | const tagsElement = template.find('.tags'); | 717 | const tagsElement = template.find('.tags'); |
| 704 | printTagList(tagsElement, { forEntityOrKey: group.id }); | 718 | printTagList(tagsElement, { forEntityOrKey: group.id, tagOptions: { isCharacterList: true } }); |
| 705 | 719 | ||
| 706 | const avatar = getGroupAvatar(group); | 720 | const avatar = getGroupAvatar(group); |
| 707 | if (avatar) { | 721 | if (avatar) { |
| @@ -1181,7 +1195,9 @@ export async function editGroup(id, immediately, reload = true) { | |||
| 1181 | return; | 1195 | return; |
| 1182 | } | 1196 | } |
| 1183 | 1197 | ||
| 1184 | group['chat_metadata'] = chat_metadata; | 1198 | if (id === selected_group) { |
| 1199 | group['chat_metadata'] = structuredClone(chat_metadata); | ||
| 1200 | } | ||
| 1185 | 1201 | ||
| 1186 | if (immediately) { | 1202 | if (immediately) { |
| 1187 | return await _save(group, reload); | 1203 | return await _save(group, reload); |
| @@ -1374,6 +1390,8 @@ function getGroupCharacters({ doFilter, onlyMembers } = {}) { | |||
| 1374 | 1390 | ||
| 1375 | function printGroupCandidates() { | 1391 | function printGroupCandidates() { |
| 1376 | const storageKey = 'GroupCandidates_PerPage'; | 1392 | const storageKey = 'GroupCandidates_PerPage'; |
| 1393 | const pageSize = Number(accountStorage.getItem(storageKey)) || 5; | ||
| 1394 | const sizeChangerOptions = [5, 10, 25, 50, 100, 200, 500, 1000]; | ||
| 1377 | $('#rm_group_add_members_pagination').pagination({ | 1395 | $('#rm_group_add_members_pagination').pagination({ |
| 1378 | dataSource: getGroupCharacters({ doFilter: true, onlyMembers: false }), | 1396 | dataSource: getGroupCharacters({ doFilter: true, onlyMembers: false }), |
| 1379 | pageRange: 1, | 1397 | pageRange: 1, |
| @@ -1382,18 +1400,20 @@ function printGroupCandidates() { | |||
| 1382 | prevText: '<', | 1400 | prevText: '<', |
| 1383 | nextText: '>', | 1401 | nextText: '>', |
| 1384 | formatNavigator: PAGINATION_TEMPLATE, | 1402 | formatNavigator: PAGINATION_TEMPLATE, |
| 1403 | formatSizeChanger: renderPaginationDropdown(pageSize, sizeChangerOptions), | ||
| 1385 | showNavigator: true, | 1404 | showNavigator: true, |
| 1386 | showSizeChanger: true, | 1405 | showSizeChanger: true, |
| 1387 | pageSize: Number(accountStorage.getItem(storageKey)) || 5, | 1406 | pageSize, |
| 1388 | sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000], | 1407 | afterSizeSelectorChange: function (e, size) { |
| 1389 | afterSizeSelectorChange: function (e) { | ||
| 1390 | accountStorage.setItem(storageKey, e.target.value); | 1408 | accountStorage.setItem(storageKey, e.target.value); |
| 1409 | paginationDropdownChangeHandler(e, size); | ||
| 1391 | }, | 1410 | }, |
| 1392 | callback: function (data) { | 1411 | callback: function (data) { |
| 1393 | $('#rm_group_add_members').empty(); | 1412 | $('#rm_group_add_members').empty(); |
| 1394 | for (const i of data) { | 1413 | for (const i of data) { |
| 1395 | $('#rm_group_add_members').append(getGroupCharacterBlock(i.item)); | 1414 | $('#rm_group_add_members').append(getGroupCharacterBlock(i.item)); |
| 1396 | } | 1415 | } |
| 1416 | localizePagination($('#rm_group_add_members_pagination')); | ||
| 1397 | }, | 1417 | }, |
| 1398 | }); | 1418 | }); |
| 1399 | } | 1419 | } |
| @@ -1401,6 +1421,9 @@ function printGroupCandidates() { | |||
| 1401 | function printGroupMembers() { | 1421 | function printGroupMembers() { |
| 1402 | const storageKey = 'GroupMembers_PerPage'; | 1422 | const storageKey = 'GroupMembers_PerPage'; |
| 1403 | $('.rm_group_members_pagination').each(function () { | 1423 | $('.rm_group_members_pagination').each(function () { |
| 1424 | let that = this; | ||
| 1425 | const pageSize = Number(accountStorage.getItem(storageKey)) || 5; | ||
| 1426 | const sizeChangerOptions = [5, 10, 25, 50, 100, 200, 500, 1000]; | ||
| 1404 | $(this).pagination({ | 1427 | $(this).pagination({ |
| 1405 | dataSource: getGroupCharacters({ doFilter: false, onlyMembers: true }), | 1428 | dataSource: getGroupCharacters({ doFilter: false, onlyMembers: true }), |
| 1406 | pageRange: 1, | 1429 | pageRange: 1, |
| @@ -1411,16 +1434,18 @@ function printGroupMembers() { | |||
| 1411 | formatNavigator: PAGINATION_TEMPLATE, | 1434 | formatNavigator: PAGINATION_TEMPLATE, |
| 1412 | showNavigator: true, | 1435 | showNavigator: true, |
| 1413 | showSizeChanger: true, | 1436 | showSizeChanger: true, |
| 1414 | pageSize: Number(accountStorage.getItem(storageKey)) || 5, | 1437 | formatSizeChanger: renderPaginationDropdown(pageSize, sizeChangerOptions), |
| 1415 | sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000], | 1438 | pageSize, |
| 1416 | afterSizeSelectorChange: function (e) { | 1439 | afterSizeSelectorChange: function (e, size) { |
| 1417 | accountStorage.setItem(storageKey, e.target.value); | 1440 | accountStorage.setItem(storageKey, e.target.value); |
| 1441 | paginationDropdownChangeHandler(e, size); | ||
| 1418 | }, | 1442 | }, |
| 1419 | callback: function (data) { | 1443 | callback: function (data) { |
| 1420 | $('.rm_group_members').empty(); | 1444 | $('.rm_group_members').empty(); |
| 1421 | for (const i of data) { | 1445 | for (const i of data) { |
| 1422 | $('.rm_group_members').append(getGroupCharacterBlock(i.item)); | 1446 | $('.rm_group_members').append(getGroupCharacterBlock(i.item)); |
| 1423 | } | 1447 | } |
| 1448 | localizePagination($(that)); | ||
| 1424 | }, | 1449 | }, |
| 1425 | }); | 1450 | }); |
| 1426 | }); | 1451 | }); |
| @@ -1457,7 +1482,7 @@ function getGroupCharacterBlock(character) { | |||
| 1457 | 1482 | ||
| 1458 | // Display inline tags | 1483 | // Display inline tags |
| 1459 | const tagsElement = template.find('.tags'); | 1484 | const tagsElement = template.find('.tags'); |
| 1460 | printTagList(tagsElement, { forEntityOrKey: characters.indexOf(character) }); | 1485 | printTagList(tagsElement, { forEntityOrKey: characters.indexOf(character), tagOptions: { isCharacterList: true } }); |
| 1461 | 1486 | ||
| 1462 | if (!openGroupId) { | 1487 | if (!openGroupId) { |
| 1463 | template.find('[data-action="speak"]').hide(); | 1488 | template.find('[data-action="speak"]').hide(); |
| @@ -1514,6 +1539,7 @@ async function onHideMutedSpritesClick(value) { | |||
| 1514 | _thisGroup.hideMutedSprites = value; | 1539 | _thisGroup.hideMutedSprites = value; |
| 1515 | console.log(`_thisGroup.hideMutedSprites = ${_thisGroup.hideMutedSprites}`); | 1540 | console.log(`_thisGroup.hideMutedSprites = ${_thisGroup.hideMutedSprites}`); |
| 1516 | await editGroup(openGroupId, false, false); | 1541 | await editGroup(openGroupId, false, false); |
| 1542 | await eventSource.emit(event_types.GROUP_UPDATED); | ||
| 1517 | } | 1543 | } |
| 1518 | } | 1544 | } |
| 1519 | 1545 | ||
| @@ -1607,6 +1633,9 @@ function select_group_chats(groupId, skipAnimation) { | |||
| 1607 | }); | 1633 | }); |
| 1608 | } | 1634 | } |
| 1609 | 1635 | ||
| 1636 | hideMutedSprites = group?.hideMutedSprites ?? false; | ||
| 1637 | $('#rm_group_hidemutedsprites').prop('checked', hideMutedSprites); | ||
| 1638 | |||
| 1610 | eventSource.emit('groupSelected', { detail: { id: openGroupId, group: group } }); | 1639 | eventSource.emit('groupSelected', { detail: { id: openGroupId, group: group } }); |
| 1611 | } | 1640 | } |
| 1612 | 1641 | ||
| @@ -1804,7 +1833,7 @@ async function createGroup() { | |||
| 1804 | const memberNames = characters.filter(x => members.includes(x.avatar)).map(x => x.name).join(', '); | 1833 | const memberNames = characters.filter(x => members.includes(x.avatar)).map(x => x.name).join(', '); |
| 1805 | 1834 | ||
| 1806 | if (!name) { | 1835 | if (!name) { |
| 1807 | name = `Group: ${memberNames}`; | 1836 | name = t`Group: ${memberNames}`; |
| 1808 | } | 1837 | } |
| 1809 | 1838 | ||
| 1810 | const avatar_url = $('#group_avatar_preview img').attr('src'); | 1839 | const avatar_url = $('#group_avatar_preview img').attr('src'); |
| @@ -1900,6 +1929,7 @@ export async function getGroupPastChats(groupId) { | |||
| 1900 | } | 1929 | } |
| 1901 | 1930 | ||
| 1902 | export async function openGroupChat(groupId, chatId) { | 1931 | export async function openGroupChat(groupId, chatId) { |
| 1932 | await waitUntilCondition(() => !isChatSaving, debounce_timeout.extended, 10); | ||
| 1903 | const group = groups.find(x => x.id === groupId); | 1933 | const group = groups.find(x => x.id === groupId); |
| 1904 | 1934 | ||
| 1905 | if (!group || !group.chats.includes(chatId)) { | 1935 | if (!group || !group.chats.includes(chatId)) { |
| @@ -394,7 +394,7 @@ function getHordeModelTemplate(option) { | |||
| 394 | `)); | 394 | `)); |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | jQuery(function () { | 397 | export function initHorde () { |
| 398 | $('#horde_model').on('mousedown change', async function (e) { | 398 | $('#horde_model').on('mousedown change', async function (e) { |
| 399 | console.log('Horde model change', e); | 399 | console.log('Horde model change', e); |
| 400 | horde_settings.models = $('#horde_model').val(); | 400 | horde_settings.models = $('#horde_model').val(); |
| @@ -441,7 +441,7 @@ jQuery(function () { | |||
| 441 | if (!isMobile()) { | 441 | if (!isMobile()) { |
| 442 | $('#horde_model').select2({ | 442 | $('#horde_model').select2({ |
| 443 | width: '100%', | 443 | width: '100%', |
| 444 | placeholder: 'Select Horde models', | 444 | placeholder: t`Select Horde models`, |
| 445 | allowClear: true, | 445 | allowClear: true, |
| 446 | closeOnSelect: false, | 446 | closeOnSelect: false, |
| 447 | templateSelection: function (data) { | 447 | templateSelection: function (data) { |
| @@ -451,5 +451,5 @@ jQuery(function () { | |||
| 451 | templateResult: getHordeModelTemplate, | 451 | templateResult: getHordeModelTemplate, |
| 452 | }); | 452 | }); |
| 453 | } | 453 | } |
| 454 | }); | 454 | } |
| 455 | 455 | ||
| @@ -208,16 +208,7 @@ export function autoSelectInstructPreset(modelId) { | |||
| 208 | 208 | ||
| 209 | // Select matching instruct preset | 209 | // Select matching instruct preset |
| 210 | let foundMatch = false; | 210 | let foundMatch = false; |
| 211 | for (const instruct_preset of instruct_presets) { | 211 | |
| 212 | // If instruct preset matches the context template | ||
| 213 | if (power_user.instruct.bind_to_context && instruct_preset.name === power_user.context.preset) { | ||
| 214 | foundMatch = true; | ||
| 215 | selectInstructPreset(instruct_preset.name, { isAuto: true }); | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | // If no match was found, auto-select instruct preset | ||
| 220 | if (!foundMatch) { | ||
| 221 | for (const preset of instruct_presets) { | 212 | for (const preset of instruct_presets) { |
| 222 | // If activation regex is set, check if it matches the model id | 213 | // If activation regex is set, check if it matches the model id |
| 223 | if (preset.activation_regex) { | 214 | if (preset.activation_regex) { |
| @@ -227,8 +218,8 @@ export function autoSelectInstructPreset(modelId) { | |||
| 227 | // Stop on first match so it won't cycle back and forth between presets if multiple regexes match | 218 | // Stop on first match so it won't cycle back and forth between presets if multiple regexes match |
| 228 | if (regex instanceof RegExp && regex.test(modelId)) { | 219 | if (regex instanceof RegExp && regex.test(modelId)) { |
| 229 | selectInstructPreset(preset.name, { isAuto: true }); | 220 | selectInstructPreset(preset.name, { isAuto: true }); |
| 230 | 221 | foundMatch = true; | |
| 231 | return true; | 222 | break; |
| 232 | } | 223 | } |
| 233 | } catch { | 224 | } catch { |
| 234 | // If regex is invalid, ignore it | 225 | // If regex is invalid, ignore it |
| @@ -236,9 +227,20 @@ export function autoSelectInstructPreset(modelId) { | |||
| 236 | } | 227 | } |
| 237 | } | 228 | } |
| 238 | } | 229 | } |
| 230 | |||
| 231 | // If no match was found, auto-select instruct preset | ||
| 232 | if (!foundMatch && power_user.instruct.bind_to_context) { | ||
| 233 | for (const instruct_preset of instruct_presets) { | ||
| 234 | // If instruct preset matches the context template | ||
| 235 | if (instruct_preset.name === power_user.context.preset) { | ||
| 236 | selectInstructPreset(instruct_preset.name, { isAuto: true }); | ||
| 237 | foundMatch = true; | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | return false; | 243 | return foundMatch; |
| 242 | } | 244 | } |
| 243 | 245 | ||
| 244 | /** | 246 | /** |
| @@ -8,6 +8,7 @@ import { | |||
| 8 | getGeneratingApi, | 8 | getGeneratingApi, |
| 9 | is_send_press, | 9 | is_send_press, |
| 10 | isStreamingEnabled, | 10 | isStreamingEnabled, |
| 11 | substituteParamsExtended, | ||
| 11 | } from '../script.js'; | 12 | } from '../script.js'; |
| 12 | import { debounce, delay, getStringHash } from './utils.js'; | 13 | import { debounce, delay, getStringHash } from './utils.js'; |
| 13 | import { decodeTextTokens, getTokenizerBestMatch } from './tokenizers.js'; | 14 | import { decodeTextTokens, getTokenizerBestMatch } from './tokenizers.js'; |
| @@ -368,7 +369,7 @@ function onToggleLogprobsPanel() { | |||
| 368 | function createSwipe(messageId, prompt) { | 369 | function createSwipe(messageId, prompt) { |
| 369 | // need to call `cleanUpMessage` on our new prompt, because we were working | 370 | // need to call `cleanUpMessage` on our new prompt, because we were working |
| 370 | // with raw model output and our new prompt is missing trimming/macro replacements | 371 | // with raw model output and our new prompt is missing trimming/macro replacements |
| 371 | const cleanedPrompt = cleanUpMessage({ | 372 | let cleanedPrompt = cleanUpMessage({ |
| 372 | getMessage: prompt, | 373 | getMessage: prompt, |
| 373 | isImpersonate: false, | 374 | isImpersonate: false, |
| 374 | isContinue: false, | 375 | isContinue: false, |
| @@ -376,6 +377,46 @@ function createSwipe(messageId, prompt) { | |||
| 376 | }); | 377 | }); |
| 377 | 378 | ||
| 378 | const msg = chat[messageId]; | 379 | const msg = chat[messageId]; |
| 380 | |||
| 381 | const reasoningPrefix = substituteParamsExtended(power_user.reasoning.prefix); | ||
| 382 | const reasoningSuffix = substituteParamsExtended(power_user.reasoning.suffix); | ||
| 383 | const isReasoningAutoParsed = power_user.reasoning.auto_parse; | ||
| 384 | const msgHasParsedReasoning = msg.extra?.reasoning?.length > 0; | ||
| 385 | let shouldRerollReasoning = false; | ||
| 386 | |||
| 387 | //if we have pre-existing reasoning and are currently autoparsing | ||
| 388 | if (isReasoningAutoParsed && msgHasParsedReasoning) { | ||
| 389 | console.debug('saw autoparse on with reasoning in message'); | ||
| 390 | //but the reroll prompt does not include the end of reasoning | ||
| 391 | if (cleanedPrompt.includes(reasoningPrefix) && !cleanedPrompt.includes(reasoningSuffix)) { | ||
| 392 | //we need to send the results to the reasoning block | ||
| 393 | //this will involve the ReasoningHandler from reasoning.js | ||
| 394 | console.debug('..with start tag but no end tag... reroll reasoning'); | ||
| 395 | shouldRerollReasoning = true; | ||
| 396 | } | ||
| 397 | |||
| 398 | let hasReasoningPrefix = cleanedPrompt.includes(reasoningPrefix); | ||
| 399 | let hasReasoningSuffix = cleanedPrompt.includes(reasoningSuffix); | ||
| 400 | |||
| 401 | //..with both the start and end think tags | ||
| 402 | //OR | ||
| 403 | //..with only the end think tag (implying prefilled think start) | ||
| 404 | if (hasReasoningPrefix && hasReasoningSuffix) { | ||
| 405 | //we need to send the results to the response block without reasoning attached | ||
| 406 | console.debug('...incl. end tag...rerolling response'); | ||
| 407 | const endOfThink = cleanedPrompt.indexOf(reasoningSuffix) + reasoningSuffix.length; | ||
| 408 | cleanedPrompt = cleanedPrompt.substring(endOfThink); | ||
| 409 | } | ||
| 410 | |||
| 411 | //if cleanedprompt includes the think prefix, but no suffix.. | ||
| 412 | if (hasReasoningPrefix && !hasReasoningSuffix) { | ||
| 413 | console.debug('..no end tag...rerolling reasoning, so removing prefix'); | ||
| 414 | cleanedPrompt = cleanedPrompt.replace(reasoningPrefix, ''); | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 418 | console.debug('cleanedPrompt: ', cleanedPrompt); | ||
| 419 | |||
| 379 | const newSwipeInfo = { | 420 | const newSwipeInfo = { |
| 380 | send_date: msg.send_date, | 421 | send_date: msg.send_date, |
| 381 | gen_started: msg.gen_started, | 422 | gen_started: msg.gen_started, |
| @@ -387,8 +428,19 @@ function createSwipe(messageId, prompt) { | |||
| 387 | msg.swipe_info = msg.swipe_info || []; | 428 | msg.swipe_info = msg.swipe_info || []; |
| 388 | 429 | ||
| 389 | // Add our new swipe, then make sure the active swipe is the one just before | 430 | // Add our new swipe, then make sure the active swipe is the one just before |
| 390 | // it. The call to `swipe_right` will switch to it immediately. | 431 | // it. The call to `swipe_right` in addGeneration() will switch to it immediately. |
| 432 | |||
| 433 | //if we determined that we need to reroll from reasoning | ||
| 434 | if (shouldRerollReasoning) { | ||
| 435 | //cleaned prompt goes into reasoning | ||
| 436 | newSwipeInfo.extra.reasoning = cleanedPrompt; | ||
| 437 | //mes_text becomes empty, causing the reasoning handler to parse the reasoning first | ||
| 438 | msg.swipes.push(''); | ||
| 439 | } else { | ||
| 440 | //otherwise just add the cleaned prompt to the message and continue | ||
| 391 | msg.swipes.push(cleanedPrompt); | 441 | msg.swipes.push(cleanedPrompt); |
| 442 | } | ||
| 443 | |||
| 392 | msg.swipe_info.push(newSwipeInfo); | 444 | msg.swipe_info.push(newSwipeInfo); |
| 393 | msg.swipe_id = Math.max(0, msg.swipes.length - 2); | 445 | msg.swipe_id = Math.max(0, msg.swipes.length - 2); |
| 394 | } | 446 | } |
| @@ -71,7 +71,7 @@ import { SlashCommand } from './slash-commands/SlashCommand.js'; | |||
| 71 | import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js'; | 71 | import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js'; |
| 72 | import { renderTemplateAsync } from './templates.js'; | 72 | import { renderTemplateAsync } from './templates.js'; |
| 73 | import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; | 73 | import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; |
| 74 | import { Popup, POPUP_RESULT } from './popup.js'; | 74 | import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js'; |
| 75 | import { t } from './i18n.js'; | 75 | import { t } from './i18n.js'; |
| 76 | import { ToolManager } from './tool-calling.js'; | 76 | import { ToolManager } from './tool-calling.js'; |
| 77 | import { accountStorage } from './util/AccountStorage.js'; | 77 | import { accountStorage } from './util/AccountStorage.js'; |
| @@ -176,6 +176,7 @@ export const chat_completion_sources = { | |||
| 176 | OPENROUTER: 'openrouter', | 176 | OPENROUTER: 'openrouter', |
| 177 | AI21: 'ai21', | 177 | AI21: 'ai21', |
| 178 | MAKERSUITE: 'makersuite', | 178 | MAKERSUITE: 'makersuite', |
| 179 | VERTEXAI: 'vertexai', | ||
| 179 | MISTRALAI: 'mistralai', | 180 | MISTRALAI: 'mistralai', |
| 180 | CUSTOM: 'custom', | 181 | CUSTOM: 'custom', |
| 181 | COHERE: 'cohere', | 182 | COHERE: 'cohere', |
| @@ -185,6 +186,7 @@ export const chat_completion_sources = { | |||
| 185 | NANOGPT: 'nanogpt', | 186 | NANOGPT: 'nanogpt', |
| 186 | DEEPSEEK: 'deepseek', | 187 | DEEPSEEK: 'deepseek', |
| 187 | XAI: 'xai', | 188 | XAI: 'xai', |
| 189 | POLLINATIONS: 'pollinations', | ||
| 188 | }; | 190 | }; |
| 189 | 191 | ||
| 190 | const character_names_behavior = { | 192 | const character_names_behavior = { |
| @@ -201,13 +203,14 @@ const continue_postfix_types = { | |||
| 201 | DOUBLE_NEWLINE: '\n\n', | 203 | DOUBLE_NEWLINE: '\n\n', |
| 202 | }; | 204 | }; |
| 203 | 205 | ||
| 204 | const custom_prompt_post_processing_types = { | 206 | export const custom_prompt_post_processing_types = { |
| 205 | NONE: '', | 207 | NONE: '', |
| 206 | /** @deprecated Use MERGE instead. */ | 208 | /** @deprecated Use MERGE instead. */ |
| 207 | CLAUDE: 'claude', | 209 | CLAUDE: 'claude', |
| 208 | MERGE: 'merge', | 210 | MERGE: 'merge', |
| 209 | SEMI: 'semi', | 211 | SEMI: 'semi', |
| 210 | STRICT: 'strict', | 212 | STRICT: 'strict', |
| 213 | SINGLE: 'single', | ||
| 211 | }; | 214 | }; |
| 212 | 215 | ||
| 213 | const openrouter_middleout_types = { | 216 | const openrouter_middleout_types = { |
| @@ -216,6 +219,15 @@ const openrouter_middleout_types = { | |||
| 216 | OFF: 'off', | 219 | OFF: 'off', |
| 217 | }; | 220 | }; |
| 218 | 221 | ||
| 222 | export const reasoning_effort_types = { | ||
| 223 | auto: 'auto', | ||
| 224 | low: 'low', | ||
| 225 | medium: 'medium', | ||
| 226 | high: 'high', | ||
| 227 | min: 'min', | ||
| 228 | max: 'max', | ||
| 229 | }; | ||
| 230 | |||
| 219 | const sensitiveFields = [ | 231 | const sensitiveFields = [ |
| 220 | 'reverse_proxy', | 232 | 'reverse_proxy', |
| 221 | 'proxy_password', | 233 | 'proxy_password', |
| @@ -226,86 +238,88 @@ const sensitiveFields = [ | |||
| 226 | ]; | 238 | ]; |
| 227 | 239 | ||
| 228 | /** | 240 | /** |
| 229 | * preset_name -> [selector, setting_name, is_checkbox] | 241 | * preset_name -> [selector, setting_name, is_checkbox, is_connection] |
| 230 | * @type {Record<string, [string, string, boolean]>} | 242 | * @type {Record<string, [string, string, boolean, boolean]>} |
| 231 | */ | 243 | */ |
| 232 | export const settingsToUpdate = { | 244 | export const settingsToUpdate = { |
| 233 | chat_completion_source: ['#chat_completion_source', 'chat_completion_source', false], | 245 | chat_completion_source: ['#chat_completion_source', 'chat_completion_source', false, true], |
| 234 | temperature: ['#temp_openai', 'temp_openai', false], | 246 | temperature: ['#temp_openai', 'temp_openai', false, false], |
| 235 | frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false], | 247 | frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false, false], |
| 236 | presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false], | 248 | presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false, false], |
| 237 | top_p: ['#top_p_openai', 'top_p_openai', false], | 249 | top_p: ['#top_p_openai', 'top_p_openai', false, false], |
| 238 | top_k: ['#top_k_openai', 'top_k_openai', false], | 250 | top_k: ['#top_k_openai', 'top_k_openai', false, false], |
| 239 | top_a: ['#top_a_openai', 'top_a_openai', false], | 251 | top_a: ['#top_a_openai', 'top_a_openai', false, false], |
| 240 | min_p: ['#min_p_openai', 'min_p_openai', false], | 252 | min_p: ['#min_p_openai', 'min_p_openai', false, false], |
| 241 | repetition_penalty: ['#repetition_penalty_openai', 'repetition_penalty_openai', false], | 253 | repetition_penalty: ['#repetition_penalty_openai', 'repetition_penalty_openai', false, false], |
| 242 | max_context_unlocked: ['#oai_max_context_unlocked', 'max_context_unlocked', true], | 254 | max_context_unlocked: ['#oai_max_context_unlocked', 'max_context_unlocked', true, false], |
| 243 | openai_model: ['#model_openai_select', 'openai_model', false], | 255 | openai_model: ['#model_openai_select', 'openai_model', false, true], |
| 244 | claude_model: ['#model_claude_select', 'claude_model', false], | 256 | claude_model: ['#model_claude_select', 'claude_model', false, true], |
| 245 | windowai_model: ['#model_windowai_select', 'windowai_model', false], | 257 | windowai_model: ['#model_windowai_select', 'windowai_model', false, true], |
| 246 | openrouter_model: ['#model_openrouter_select', 'openrouter_model', false], | 258 | openrouter_model: ['#model_openrouter_select', 'openrouter_model', false, true], |
| 247 | openrouter_use_fallback: ['#openrouter_use_fallback', 'openrouter_use_fallback', true], | 259 | openrouter_use_fallback: ['#openrouter_use_fallback', 'openrouter_use_fallback', true, true], |
| 248 | openrouter_group_models: ['#openrouter_group_models', 'openrouter_group_models', false], | 260 | openrouter_group_models: ['#openrouter_group_models', 'openrouter_group_models', false, true], |
| 249 | openrouter_sort_models: ['#openrouter_sort_models', 'openrouter_sort_models', false], | 261 | openrouter_sort_models: ['#openrouter_sort_models', 'openrouter_sort_models', false, true], |
| 250 | openrouter_providers: ['#openrouter_providers_chat', 'openrouter_providers', false], | 262 | openrouter_providers: ['#openrouter_providers_chat', 'openrouter_providers', false, true], |
| 251 | openrouter_allow_fallbacks: ['#openrouter_allow_fallbacks', 'openrouter_allow_fallbacks', true], | 263 | openrouter_allow_fallbacks: ['#openrouter_allow_fallbacks', 'openrouter_allow_fallbacks', true, true], |
| 252 | openrouter_middleout: ['#openrouter_middleout', 'openrouter_middleout', false], | 264 | openrouter_middleout: ['#openrouter_middleout', 'openrouter_middleout', false, true], |
| 253 | ai21_model: ['#model_ai21_select', 'ai21_model', false], | 265 | ai21_model: ['#model_ai21_select', 'ai21_model', false, true], |
| 254 | mistralai_model: ['#model_mistralai_select', 'mistralai_model', false], | 266 | mistralai_model: ['#model_mistralai_select', 'mistralai_model', false, true], |
| 255 | cohere_model: ['#model_cohere_select', 'cohere_model', false], | 267 | cohere_model: ['#model_cohere_select', 'cohere_model', false, true], |
| 256 | perplexity_model: ['#model_perplexity_select', 'perplexity_model', false], | 268 | perplexity_model: ['#model_perplexity_select', 'perplexity_model', false, true], |
| 257 | groq_model: ['#model_groq_select', 'groq_model', false], | 269 | groq_model: ['#model_groq_select', 'groq_model', false, true], |
| 258 | nanogpt_model: ['#model_nanogpt_select', 'nanogpt_model', false], | 270 | nanogpt_model: ['#model_nanogpt_select', 'nanogpt_model', false, true], |
| 259 | deepseek_model: ['#model_deepseek_select', 'deepseek_model', false], | 271 | deepseek_model: ['#model_deepseek_select', 'deepseek_model', false, true], |
| 260 | zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false], | 272 | zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false, true], |
| 261 | xai_model: ['#model_xai_select', 'xai_model', false], | 273 | xai_model: ['#model_xai_select', 'xai_model', false, true], |
| 262 | custom_model: ['#custom_model_id', 'custom_model', false], | 274 | pollinations_model: ['#model_pollinations_select', 'pollinations_model', false, true], |
| 263 | custom_url: ['#custom_api_url_text', 'custom_url', false], | 275 | custom_model: ['#custom_model_id', 'custom_model', false, true], |
| 264 | custom_include_body: ['#custom_include_body', 'custom_include_body', false], | 276 | custom_url: ['#custom_api_url_text', 'custom_url', false, true], |
| 265 | custom_exclude_body: ['#custom_exclude_body', 'custom_exclude_body', false], | 277 | custom_include_body: ['#custom_include_body', 'custom_include_body', false, true], |
| 266 | custom_include_headers: ['#custom_include_headers', 'custom_include_headers', false], | 278 | custom_exclude_body: ['#custom_exclude_body', 'custom_exclude_body', false, true], |
| 267 | custom_prompt_post_processing: ['#custom_prompt_post_processing', 'custom_prompt_post_processing', false], | 279 | custom_include_headers: ['#custom_include_headers', 'custom_include_headers', false, true], |
| 268 | google_model: ['#model_google_select', 'google_model', false], | 280 | custom_prompt_post_processing: ['#custom_prompt_post_processing', 'custom_prompt_post_processing', false, true], |
| 269 | openai_max_context: ['#openai_max_context', 'openai_max_context', false], | 281 | google_model: ['#model_google_select', 'google_model', false, true], |
| 270 | openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false], | 282 | vertexai_model: ['#model_vertexai_select', 'vertexai_model', false, true], |
| 271 | wrap_in_quotes: ['#wrap_in_quotes', 'wrap_in_quotes', true], | 283 | openai_max_context: ['#openai_max_context', 'openai_max_context', false, false], |
| 272 | names_behavior: ['#names_behavior', 'names_behavior', false], | 284 | openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false, false], |
| 273 | send_if_empty: ['#send_if_empty_textarea', 'send_if_empty', false], | 285 | wrap_in_quotes: ['#wrap_in_quotes', 'wrap_in_quotes', true, false], |
| 274 | impersonation_prompt: ['#impersonation_prompt_textarea', 'impersonation_prompt', false], | 286 | names_behavior: ['#names_behavior', 'names_behavior', false, false], |
| 275 | new_chat_prompt: ['#newchat_prompt_textarea', 'new_chat_prompt', false], | 287 | send_if_empty: ['#send_if_empty_textarea', 'send_if_empty', false, false], |
| 276 | new_group_chat_prompt: ['#newgroupchat_prompt_textarea', 'new_group_chat_prompt', false], | 288 | impersonation_prompt: ['#impersonation_prompt_textarea', 'impersonation_prompt', false, false], |
| 277 | new_example_chat_prompt: ['#newexamplechat_prompt_textarea', 'new_example_chat_prompt', false], | 289 | new_chat_prompt: ['#newchat_prompt_textarea', 'new_chat_prompt', false, false], |
| 278 | continue_nudge_prompt: ['#continue_nudge_prompt_textarea', 'continue_nudge_prompt', false], | 290 | new_group_chat_prompt: ['#newgroupchat_prompt_textarea', 'new_group_chat_prompt', false, false], |
| 279 | bias_preset_selected: ['#openai_logit_bias_preset', 'bias_preset_selected', false], | 291 | new_example_chat_prompt: ['#newexamplechat_prompt_textarea', 'new_example_chat_prompt', false, false], |
| 280 | reverse_proxy: ['#openai_reverse_proxy', 'reverse_proxy', false], | 292 | continue_nudge_prompt: ['#continue_nudge_prompt_textarea', 'continue_nudge_prompt', false, false], |
| 281 | wi_format: ['#wi_format_textarea', 'wi_format', false], | 293 | bias_preset_selected: ['#openai_logit_bias_preset', 'bias_preset_selected', false, false], |
| 282 | scenario_format: ['#scenario_format_textarea', 'scenario_format', false], | 294 | reverse_proxy: ['#openai_reverse_proxy', 'reverse_proxy', false, true], |
| 283 | personality_format: ['#personality_format_textarea', 'personality_format', false], | 295 | wi_format: ['#wi_format_textarea', 'wi_format', false, false], |
| 284 | group_nudge_prompt: ['#group_nudge_prompt_textarea', 'group_nudge_prompt', false], | 296 | scenario_format: ['#scenario_format_textarea', 'scenario_format', false, false], |
| 285 | stream_openai: ['#stream_toggle', 'stream_openai', true], | 297 | personality_format: ['#personality_format_textarea', 'personality_format', false, false], |
| 286 | prompts: ['', 'prompts', false], | 298 | group_nudge_prompt: ['#group_nudge_prompt_textarea', 'group_nudge_prompt', false, false], |
| 287 | prompt_order: ['', 'prompt_order', false], | 299 | stream_openai: ['#stream_toggle', 'stream_openai', true, false], |
| 288 | api_url_scale: ['#api_url_scale', 'api_url_scale', false], | 300 | prompts: ['', 'prompts', false, false], |
| 289 | show_external_models: ['#openai_show_external_models', 'show_external_models', true], | 301 | prompt_order: ['', 'prompt_order', false, false], |
| 290 | proxy_password: ['#openai_proxy_password', 'proxy_password', false], | 302 | api_url_scale: ['#api_url_scale', 'api_url_scale', false, true], |
| 291 | assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false], | 303 | show_external_models: ['#openai_show_external_models', 'show_external_models', true, true], |
| 292 | assistant_impersonation: ['#claude_assistant_impersonation', 'assistant_impersonation', false], | 304 | proxy_password: ['#openai_proxy_password', 'proxy_password', false, true], |
| 293 | claude_use_sysprompt: ['#claude_use_sysprompt', 'claude_use_sysprompt', true], | 305 | assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false, false], |
| 294 | use_makersuite_sysprompt: ['#use_makersuite_sysprompt', 'use_makersuite_sysprompt', true], | 306 | assistant_impersonation: ['#claude_assistant_impersonation', 'assistant_impersonation', false, false], |
| 295 | use_alt_scale: ['#use_alt_scale', 'use_alt_scale', true], | 307 | claude_use_sysprompt: ['#claude_use_sysprompt', 'claude_use_sysprompt', true, false], |
| 296 | squash_system_messages: ['#squash_system_messages', 'squash_system_messages', true], | 308 | use_makersuite_sysprompt: ['#use_makersuite_sysprompt', 'use_makersuite_sysprompt', true, false], |
| 297 | image_inlining: ['#openai_image_inlining', 'image_inlining', true], | 309 | use_alt_scale: ['#use_alt_scale', 'use_alt_scale', true, true], |
| 298 | inline_image_quality: ['#openai_inline_image_quality', 'inline_image_quality', false], | 310 | squash_system_messages: ['#squash_system_messages', 'squash_system_messages', true, false], |
| 299 | continue_prefill: ['#continue_prefill', 'continue_prefill', true], | 311 | image_inlining: ['#openai_image_inlining', 'image_inlining', true, false], |
| 300 | continue_postfix: ['#continue_postfix', 'continue_postfix', false], | 312 | inline_image_quality: ['#openai_inline_image_quality', 'inline_image_quality', false, false], |
| 301 | function_calling: ['#openai_function_calling', 'function_calling', true], | 313 | continue_prefill: ['#continue_prefill', 'continue_prefill', true, false], |
| 302 | show_thoughts: ['#openai_show_thoughts', 'show_thoughts', true], | 314 | continue_postfix: ['#continue_postfix', 'continue_postfix', false, false], |
| 303 | reasoning_effort: ['#openai_reasoning_effort', 'reasoning_effort', false], | 315 | function_calling: ['#openai_function_calling', 'function_calling', true, false], |
| 304 | enable_web_search: ['#openai_enable_web_search', 'enable_web_search', true], | 316 | show_thoughts: ['#openai_show_thoughts', 'show_thoughts', true, false], |
| 305 | seed: ['#seed_openai', 'seed', false], | 317 | reasoning_effort: ['#openai_reasoning_effort', 'reasoning_effort', false, false], |
| 306 | n: ['#n_openai', 'n', false], | 318 | enable_web_search: ['#openai_enable_web_search', 'enable_web_search', true, false], |
| 307 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true], | 319 | seed: ['#seed_openai', 'seed', false, false], |
| 308 | request_images: ['#openai_request_images', 'request_images', true], | 320 | n: ['#n_openai', 'n', false, false], |
| 321 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true, true], | ||
| 322 | request_images: ['#openai_request_images', 'request_images', true, false], | ||
| 309 | }; | 323 | }; |
| 310 | 324 | ||
| 311 | const default_settings = { | 325 | const default_settings = { |
| @@ -339,6 +353,7 @@ const default_settings = { | |||
| 339 | openai_model: 'gpt-4-turbo', | 353 | openai_model: 'gpt-4-turbo', |
| 340 | claude_model: 'claude-3-5-sonnet-20240620', | 354 | claude_model: 'claude-3-5-sonnet-20240620', |
| 341 | google_model: 'gemini-1.5-pro', | 355 | google_model: 'gemini-1.5-pro', |
| 356 | vertexai_model: 'gemini-2.0-flash-001', | ||
| 342 | ai21_model: 'jamba-1.6-large', | 357 | ai21_model: 'jamba-1.6-large', |
| 343 | mistralai_model: 'mistral-large-latest', | 358 | mistralai_model: 'mistral-large-latest', |
| 344 | cohere_model: 'command-r-plus', | 359 | cohere_model: 'command-r-plus', |
| @@ -348,6 +363,7 @@ const default_settings = { | |||
| 348 | zerooneai_model: 'yi-large', | 363 | zerooneai_model: 'yi-large', |
| 349 | deepseek_model: 'deepseek-chat', | 364 | deepseek_model: 'deepseek-chat', |
| 350 | xai_model: 'grok-3-beta', | 365 | xai_model: 'grok-3-beta', |
| 366 | pollinations_model: 'openai', | ||
| 351 | custom_model: '', | 367 | custom_model: '', |
| 352 | custom_url: '', | 368 | custom_url: '', |
| 353 | custom_include_body: '', | 369 | custom_include_body: '', |
| @@ -382,11 +398,12 @@ const default_settings = { | |||
| 382 | continue_postfix: continue_postfix_types.SPACE, | 398 | continue_postfix: continue_postfix_types.SPACE, |
| 383 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, | 399 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 384 | show_thoughts: true, | 400 | show_thoughts: true, |
| 385 | reasoning_effort: 'medium', | 401 | reasoning_effort: reasoning_effort_types.auto, |
| 386 | enable_web_search: false, | 402 | enable_web_search: false, |
| 387 | request_images: false, | 403 | request_images: false, |
| 388 | seed: -1, | 404 | seed: -1, |
| 389 | n: 1, | 405 | n: 1, |
| 406 | bind_preset_to_connection: true, | ||
| 390 | }; | 407 | }; |
| 391 | 408 | ||
| 392 | const oai_settings = { | 409 | const oai_settings = { |
| @@ -420,6 +437,7 @@ const oai_settings = { | |||
| 420 | openai_model: 'gpt-4-turbo', | 437 | openai_model: 'gpt-4-turbo', |
| 421 | claude_model: 'claude-3-5-sonnet-20240620', | 438 | claude_model: 'claude-3-5-sonnet-20240620', |
| 422 | google_model: 'gemini-1.5-pro', | 439 | google_model: 'gemini-1.5-pro', |
| 440 | vertexai_model: 'gemini-2.0-flash-001', | ||
| 423 | ai21_model: 'jamba-1.6-large', | 441 | ai21_model: 'jamba-1.6-large', |
| 424 | mistralai_model: 'mistral-large-latest', | 442 | mistralai_model: 'mistral-large-latest', |
| 425 | cohere_model: 'command-r-plus', | 443 | cohere_model: 'command-r-plus', |
| @@ -429,6 +447,7 @@ const oai_settings = { | |||
| 429 | zerooneai_model: 'yi-large', | 447 | zerooneai_model: 'yi-large', |
| 430 | deepseek_model: 'deepseek-chat', | 448 | deepseek_model: 'deepseek-chat', |
| 431 | xai_model: 'grok-3-beta', | 449 | xai_model: 'grok-3-beta', |
| 450 | pollinations_model: 'openai', | ||
| 432 | custom_model: '', | 451 | custom_model: '', |
| 433 | custom_url: '', | 452 | custom_url: '', |
| 434 | custom_include_body: '', | 453 | custom_include_body: '', |
| @@ -463,11 +482,12 @@ const oai_settings = { | |||
| 463 | continue_postfix: continue_postfix_types.SPACE, | 482 | continue_postfix: continue_postfix_types.SPACE, |
| 464 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, | 483 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 465 | show_thoughts: true, | 484 | show_thoughts: true, |
| 466 | reasoning_effort: 'medium', | 485 | reasoning_effort: reasoning_effort_types.auto, |
| 467 | enable_web_search: false, | 486 | enable_web_search: false, |
| 468 | request_images: false, | 487 | request_images: false, |
| 469 | seed: -1, | 488 | seed: -1, |
| 470 | n: 1, | 489 | n: 1, |
| 490 | bind_preset_to_connection: true, | ||
| 471 | }; | 491 | }; |
| 472 | 492 | ||
| 473 | export let proxies = [ | 493 | export let proxies = [ |
| @@ -747,24 +767,47 @@ async function populationInjectionPrompts(prompts, messages) { | |||
| 747 | // Get prompts for current depth | 767 | // Get prompts for current depth |
| 748 | const depthPrompts = prompts.filter(prompt => prompt.injection_depth === i && prompt.content); | 768 | const depthPrompts = prompts.filter(prompt => prompt.injection_depth === i && prompt.content); |
| 749 | 769 | ||
| 750 | // Order of priority (most important go lower) | ||
| 751 | const roles = ['system', 'user', 'assistant']; | ||
| 752 | const roleMessages = []; | 770 | const roleMessages = []; |
| 753 | const separator = '\n'; | 771 | const separator = '\n'; |
| 754 | const wrap = false; | 772 | const wrap = false; |
| 755 | 773 | ||
| 774 | // Group prompts by priority | ||
| 775 | const extensionPromptsOrder = '100'; | ||
| 776 | const orderGroups = { | ||
| 777 | [extensionPromptsOrder]: [], | ||
| 778 | }; | ||
| 779 | for (const prompt of depthPrompts) { | ||
| 780 | const order = prompt.injection_order ?? 100; | ||
| 781 | if (!orderGroups[order]) { | ||
| 782 | orderGroups[order] = []; | ||
| 783 | } | ||
| 784 | orderGroups[order].push(prompt); | ||
| 785 | } | ||
| 786 | |||
| 787 | // Process each order group in order (b - a = low to high ; a - b = high to low) | ||
| 788 | const orders = Object.keys(orderGroups).sort((a, b) => +b - +a); | ||
| 789 | for (const order of orders) { | ||
| 790 | const orderPrompts = orderGroups[order]; | ||
| 791 | |||
| 792 | // Order of priority for roles (most important go lower) | ||
| 793 | const roles = ['system', 'user', 'assistant']; | ||
| 756 | for (const role of roles) { | 794 | for (const role of roles) { |
| 757 | // Get prompts for current role | 795 | const rolePrompts = orderPrompts |
| 758 | const rolePrompts = depthPrompts.filter(prompt => prompt.role === role).map(x => x.content).join(separator); | 796 | .filter(prompt => prompt.role === role) |
| 759 | // Get extension prompt | 797 | .map(x => x.content) |
| 760 | const extensionPrompt = await getExtensionPrompt(extension_prompt_types.IN_CHAT, i, separator, roleTypes[role], wrap); | 798 | .join(separator); |
| 761 | 799 | ||
| 800 | // Get extension prompt | ||
| 801 | const extensionPrompt = order === extensionPromptsOrder | ||
| 802 | ? await getExtensionPrompt(extension_prompt_types.IN_CHAT, i, separator, roleTypes[role], wrap) | ||
| 803 | : ''; | ||
| 762 | const jointPrompt = [rolePrompts, extensionPrompt].filter(x => x).map(x => x.trim()).join(separator); | 804 | const jointPrompt = [rolePrompts, extensionPrompt].filter(x => x).map(x => x.trim()).join(separator); |
| 763 | 805 | ||
| 764 | if (jointPrompt && jointPrompt.length) { | 806 | if (jointPrompt && jointPrompt.length) { |
| 765 | roleMessages.push({ 'role': role, 'content': jointPrompt, injected: true }); | 807 | roleMessages.push({ 'role': role, 'content': jointPrompt, injected: true }); |
| 766 | } | 808 | } |
| 767 | } | 809 | } |
| 810 | } | ||
| 768 | 811 | ||
| 769 | if (roleMessages.length) { | 812 | if (roleMessages.length) { |
| 770 | const injectIdx = i + totalInsertedMessages; | 813 | const injectIdx = i + totalInsertedMessages; |
| @@ -1172,7 +1215,7 @@ async function populateChatCompletion(prompts, chatCompletion, { bias, quietProm | |||
| 1172 | * Combines system prompts with prompt manager prompts | 1215 | * Combines system prompts with prompt manager prompts |
| 1173 | * | 1216 | * |
| 1174 | * @param {Object} options - An object with optional settings. | 1217 | * @param {Object} options - An object with optional settings. |
| 1175 | * @param {string} options.Scenario - The scenario or context of the dialogue. | 1218 | * @param {string} options.scenario - The scenario or context of the dialogue. |
| 1176 | * @param {string} options.charPersonality - Description of the character's personality. | 1219 | * @param {string} options.charPersonality - Description of the character's personality. |
| 1177 | * @param {string} options.name2 - The second name to be used in the messages. | 1220 | * @param {string} options.name2 - The second name to be used in the messages. |
| 1178 | * @param {string} options.worldInfoBefore - The world info to be added before the main conversation. | 1221 | * @param {string} options.worldInfoBefore - The world info to be added before the main conversation. |
| @@ -1186,8 +1229,8 @@ async function populateChatCompletion(prompts, chatCompletion, { bias, quietProm | |||
| 1186 | * @param {string} options.personaDescription | 1229 | * @param {string} options.personaDescription |
| 1187 | * @returns {Promise<Object>} prompts - The prepared and merged system and user-defined prompts. | 1230 | * @returns {Promise<Object>} prompts - The prepared and merged system and user-defined prompts. |
| 1188 | */ | 1231 | */ |
| 1189 | async function preparePromptsForChatCompletion({ Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride, personaDescription }) { | 1232 | async function preparePromptsForChatCompletion({ scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride, personaDescription }) { |
| 1190 | const scenarioText = Scenario && oai_settings.scenario_format ? substituteParams(oai_settings.scenario_format) : ''; | 1233 | const scenarioText = scenario && oai_settings.scenario_format ? substituteParams(oai_settings.scenario_format) : ''; |
| 1191 | const charPersonalityText = charPersonality && oai_settings.personality_format ? substituteParams(oai_settings.personality_format) : ''; | 1234 | const charPersonalityText = charPersonality && oai_settings.personality_format ? substituteParams(oai_settings.personality_format) : ''; |
| 1192 | const groupNudge = substituteParams(oai_settings.group_nudge_prompt); | 1235 | const groupNudge = substituteParams(oai_settings.group_nudge_prompt); |
| 1193 | const impersonationPrompt = oai_settings.impersonation_prompt ? substituteParams(oai_settings.impersonation_prompt) : ''; | 1236 | const impersonationPrompt = oai_settings.impersonation_prompt ? substituteParams(oai_settings.impersonation_prompt) : ''; |
| @@ -1301,6 +1344,8 @@ async function preparePromptsForChatCompletion({ Scenario, charPersonality, name | |||
| 1301 | prompt.injection_position = collectionPrompt.injection_position ?? prompt.injection_position; | 1344 | prompt.injection_position = collectionPrompt.injection_position ?? prompt.injection_position; |
| 1302 | // Depth for In-Chat | 1345 | // Depth for In-Chat |
| 1303 | prompt.injection_depth = collectionPrompt.injection_depth ?? prompt.injection_depth; | 1346 | prompt.injection_depth = collectionPrompt.injection_depth ?? prompt.injection_depth; |
| 1347 | // Priority for In-Chat | ||
| 1348 | prompt.injection_order = collectionPrompt.injection_order ?? prompt.injection_order; | ||
| 1304 | // Role (system, user, assistant) | 1349 | // Role (system, user, assistant) |
| 1305 | prompt.role = collectionPrompt.role ?? prompt.role; | 1350 | prompt.role = collectionPrompt.role ?? prompt.role; |
| 1306 | } | 1351 | } |
| @@ -1343,7 +1388,7 @@ async function preparePromptsForChatCompletion({ Scenario, charPersonality, name | |||
| 1343 | * @param {string} content.name2 - The second name to be used in the messages. | 1388 | * @param {string} content.name2 - The second name to be used in the messages. |
| 1344 | * @param {string} content.charDescription - Description of the character. | 1389 | * @param {string} content.charDescription - Description of the character. |
| 1345 | * @param {string} content.charPersonality - Description of the character's personality. | 1390 | * @param {string} content.charPersonality - Description of the character's personality. |
| 1346 | * @param {string} content.Scenario - The scenario or context of the dialogue. | 1391 | * @param {string} content.scenario - The scenario or context of the dialogue. |
| 1347 | * @param {string} content.worldInfoBefore - The world info to be added before the main conversation. | 1392 | * @param {string} content.worldInfoBefore - The world info to be added before the main conversation. |
| 1348 | * @param {string} content.worldInfoAfter - The world info to be added after the main conversation. | 1393 | * @param {string} content.worldInfoAfter - The world info to be added after the main conversation. |
| 1349 | * @param {string} content.bias - The bias to be added in the conversation. | 1394 | * @param {string} content.bias - The bias to be added in the conversation. |
| @@ -1364,7 +1409,7 @@ export async function prepareOpenAIMessages({ | |||
| 1364 | name2, | 1409 | name2, |
| 1365 | charDescription, | 1410 | charDescription, |
| 1366 | charPersonality, | 1411 | charPersonality, |
| 1367 | Scenario, | 1412 | scenario, |
| 1368 | worldInfoBefore, | 1413 | worldInfoBefore, |
| 1369 | worldInfoAfter, | 1414 | worldInfoAfter, |
| 1370 | bias, | 1415 | bias, |
| @@ -1391,21 +1436,18 @@ export async function prepareOpenAIMessages({ | |||
| 1391 | try { | 1436 | try { |
| 1392 | // Merge markers and ordered user prompts with system prompts | 1437 | // Merge markers and ordered user prompts with system prompts |
| 1393 | const prompts = await preparePromptsForChatCompletion({ | 1438 | const prompts = await preparePromptsForChatCompletion({ |
| 1394 | Scenario, | 1439 | scenario, |
| 1395 | charPersonality, | 1440 | charPersonality, |
| 1396 | name2, | 1441 | name2, |
| 1397 | worldInfoBefore, | 1442 | worldInfoBefore, |
| 1398 | worldInfoAfter, | 1443 | worldInfoAfter, |
| 1399 | charDescription, | 1444 | charDescription, |
| 1400 | quietPrompt, | 1445 | quietPrompt, |
| 1401 | quietImage, | ||
| 1402 | bias, | 1446 | bias, |
| 1403 | extensionPrompts, | 1447 | extensionPrompts, |
| 1404 | systemPromptOverride, | 1448 | systemPromptOverride, |
| 1405 | jailbreakPromptOverride, | 1449 | jailbreakPromptOverride, |
| 1406 | personaDescription, | 1450 | personaDescription, |
| 1407 | messages, | ||
| 1408 | messageExamples, | ||
| 1409 | }); | 1451 | }); |
| 1410 | 1452 | ||
| 1411 | // Fill the chat completion with as much context as the budget allows | 1453 | // Fill the chat completion with as much context as the budget allows |
| @@ -1629,6 +1671,8 @@ export function getChatCompletionModel(source = null) { | |||
| 1629 | return ''; | 1671 | return ''; |
| 1630 | case chat_completion_sources.MAKERSUITE: | 1672 | case chat_completion_sources.MAKERSUITE: |
| 1631 | return oai_settings.google_model; | 1673 | return oai_settings.google_model; |
| 1674 | case chat_completion_sources.VERTEXAI: | ||
| 1675 | return oai_settings.vertexai_model; | ||
| 1632 | case chat_completion_sources.OPENROUTER: | 1676 | case chat_completion_sources.OPENROUTER: |
| 1633 | return oai_settings.openrouter_model !== openrouter_website_model ? oai_settings.openrouter_model : null; | 1677 | return oai_settings.openrouter_model !== openrouter_website_model ? oai_settings.openrouter_model : null; |
| 1634 | case chat_completion_sources.AI21: | 1678 | case chat_completion_sources.AI21: |
| @@ -1651,8 +1695,11 @@ export function getChatCompletionModel(source = null) { | |||
| 1651 | return oai_settings.deepseek_model; | 1695 | return oai_settings.deepseek_model; |
| 1652 | case chat_completion_sources.XAI: | 1696 | case chat_completion_sources.XAI: |
| 1653 | return oai_settings.xai_model; | 1697 | return oai_settings.xai_model; |
| 1698 | case chat_completion_sources.POLLINATIONS: | ||
| 1699 | return oai_settings.pollinations_model; | ||
| 1654 | default: | 1700 | default: |
| 1655 | throw new Error(`Unknown chat completion source: ${activeSource}`); | 1701 | console.error(`Unknown chat completion source: ${activeSource}`); |
| 1702 | return ''; | ||
| 1656 | } | 1703 | } |
| 1657 | } | 1704 | } |
| 1658 | 1705 | ||
| @@ -1832,6 +1879,24 @@ function saveModelList(data) { | |||
| 1832 | 1879 | ||
| 1833 | $('#model_deepseek_select').val(oai_settings.deepseek_model).trigger('change'); | 1880 | $('#model_deepseek_select').val(oai_settings.deepseek_model).trigger('change'); |
| 1834 | } | 1881 | } |
| 1882 | |||
| 1883 | if (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS) { | ||
| 1884 | $('#model_pollinations_select').empty(); | ||
| 1885 | model_list.forEach((model) => { | ||
| 1886 | $('#model_pollinations_select').append( | ||
| 1887 | $('<option>', { | ||
| 1888 | value: model.id, | ||
| 1889 | text: model.id, | ||
| 1890 | })); | ||
| 1891 | }); | ||
| 1892 | |||
| 1893 | const selectedModel = model_list.find(model => model.id === oai_settings.pollinations_model); | ||
| 1894 | if (model_list.length > 0 && (!selectedModel || !oai_settings.pollinations_model)) { | ||
| 1895 | oai_settings.pollinations_model = model_list[0].id; | ||
| 1896 | } | ||
| 1897 | |||
| 1898 | $('#model_pollinations_select').val(oai_settings.pollinations_model).trigger('change'); | ||
| 1899 | } | ||
| 1835 | } | 1900 | } |
| 1836 | 1901 | ||
| 1837 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { | 1902 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { |
| @@ -1937,6 +2002,32 @@ async function sendAltScaleRequest(messages, logit_bias, signal, type) { | |||
| 1937 | return data.output; | 2002 | return data.output; |
| 1938 | } | 2003 | } |
| 1939 | 2004 | ||
| 2005 | function getReasoningEffort() { | ||
| 2006 | // These sources expect the effort as string. | ||
| 2007 | const reasoningEffortSources = [ | ||
| 2008 | chat_completion_sources.OPENAI, | ||
| 2009 | chat_completion_sources.CUSTOM, | ||
| 2010 | chat_completion_sources.XAI, | ||
| 2011 | chat_completion_sources.OPENROUTER, | ||
| 2012 | chat_completion_sources.POLLINATIONS, | ||
| 2013 | ]; | ||
| 2014 | |||
| 2015 | if (!reasoningEffortSources.includes(oai_settings.chat_completion_source)) { | ||
| 2016 | return oai_settings.reasoning_effort; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | switch (oai_settings.reasoning_effort) { | ||
| 2020 | case reasoning_effort_types.auto: | ||
| 2021 | return undefined; | ||
| 2022 | case reasoning_effort_types.min: | ||
| 2023 | return reasoning_effort_types.low; | ||
| 2024 | case reasoning_effort_types.max: | ||
| 2025 | return reasoning_effort_types.high; | ||
| 2026 | default: | ||
| 2027 | return oai_settings.reasoning_effort; | ||
| 2028 | } | ||
| 2029 | } | ||
| 2030 | |||
| 1940 | /** | 2031 | /** |
| 1941 | * Send a chat completion request to backend | 2032 | * Send a chat completion request to backend |
| 1942 | * @param {string} type (impersonate, quiet, continue, etc) | 2033 | * @param {string} type (impersonate, quiet, continue, etc) |
| @@ -1964,6 +2055,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1964 | const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER; | 2055 | const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER; |
| 1965 | const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE; | 2056 | const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE; |
| 1966 | const isGoogle = oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE; | 2057 | const isGoogle = oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE; |
| 2058 | const isVertexAI = oai_settings.chat_completion_source == chat_completion_sources.VERTEXAI; | ||
| 1967 | const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI; | 2059 | const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI; |
| 1968 | const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; | 2060 | const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; |
| 1969 | const isCustom = oai_settings.chat_completion_source == chat_completion_sources.CUSTOM; | 2061 | const isCustom = oai_settings.chat_completion_source == chat_completion_sources.CUSTOM; |
| @@ -1974,6 +2066,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1974 | const isNano = oai_settings.chat_completion_source == chat_completion_sources.NANOGPT; | 2066 | const isNano = oai_settings.chat_completion_source == chat_completion_sources.NANOGPT; |
| 1975 | const isDeepSeek = oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK; | 2067 | const isDeepSeek = oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK; |
| 1976 | const isXAI = oai_settings.chat_completion_source == chat_completion_sources.XAI; | 2068 | const isXAI = oai_settings.chat_completion_source == chat_completion_sources.XAI; |
| 2069 | const isPollinations = oai_settings.chat_completion_source == chat_completion_sources.POLLINATIONS; | ||
| 1977 | const isTextCompletion = isOAI && textCompletionModels.includes(oai_settings.openai_model); | 2070 | const isTextCompletion = isOAI && textCompletionModels.includes(oai_settings.openai_model); |
| 1978 | const isQuiet = type === 'quiet'; | 2071 | const isQuiet = type === 'quiet'; |
| 1979 | const isImpersonate = type === 'impersonate'; | 2072 | const isImpersonate = type === 'impersonate'; |
| @@ -2023,7 +2116,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2023 | 'char_name': name2, | 2116 | 'char_name': name2, |
| 2024 | 'group_names': getGroupNames(), | 2117 | 'group_names': getGroupNames(), |
| 2025 | 'include_reasoning': Boolean(oai_settings.show_thoughts), | 2118 | 'include_reasoning': Boolean(oai_settings.show_thoughts), |
| 2026 | 'reasoning_effort': String(oai_settings.reasoning_effort), | 2119 | 'reasoning_effort': getReasoningEffort(), |
| 2027 | 'enable_web_search': Boolean(oai_settings.enable_web_search), | 2120 | 'enable_web_search': Boolean(oai_settings.enable_web_search), |
| 2028 | 'request_images': Boolean(oai_settings.request_images), | 2121 | 'request_images': Boolean(oai_settings.request_images), |
| 2029 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, | 2122 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, |
| @@ -2038,8 +2131,8 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2038 | delete generate_data.stop; | 2131 | delete generate_data.stop; |
| 2039 | } | 2132 | } |
| 2040 | 2133 | ||
| 2041 | // Proxy is only supported for Claude, OpenAI, Mistral, and Google MakerSuite | 2134 | // Proxy is only supported for Claude, OpenAI, Mistral, Google MakerSuite, and Vertex AI |
| 2042 | if (oai_settings.reverse_proxy && [chat_completion_sources.CLAUDE, chat_completion_sources.OPENAI, chat_completion_sources.MISTRALAI, chat_completion_sources.MAKERSUITE, chat_completion_sources.DEEPSEEK, chat_completion_sources.XAI].includes(oai_settings.chat_completion_source)) { | 2135 | if (oai_settings.reverse_proxy && [chat_completion_sources.CLAUDE, chat_completion_sources.OPENAI, chat_completion_sources.MISTRALAI, chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI, chat_completion_sources.DEEPSEEK, chat_completion_sources.XAI].includes(oai_settings.chat_completion_source)) { |
| 2043 | await validateReverseProxy(); | 2136 | await validateReverseProxy(); |
| 2044 | generate_data['reverse_proxy'] = oai_settings.reverse_proxy; | 2137 | generate_data['reverse_proxy'] = oai_settings.reverse_proxy; |
| 2045 | generate_data['proxy_password'] = oai_settings.proxy_password; | 2138 | generate_data['proxy_password'] = oai_settings.proxy_password; |
| @@ -2090,7 +2183,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2090 | generate_data['api_url_scale'] = oai_settings.api_url_scale; | 2183 | generate_data['api_url_scale'] = oai_settings.api_url_scale; |
| 2091 | } | 2184 | } |
| 2092 | 2185 | ||
| 2093 | if (isGoogle) { | 2186 | if (isGoogle || isVertexAI) { |
| 2094 | const stopStringsLimit = 5; | 2187 | const stopStringsLimit = 5; |
| 2095 | generate_data['top_k'] = Number(oai_settings.top_k_openai); | 2188 | generate_data['top_k'] = Number(oai_settings.top_k_openai); |
| 2096 | generate_data['stop'] = getCustomStoppingStrings(stopStringsLimit).slice(0, stopStringsLimit).filter(x => x.length >= 1 && x.length <= 16); | 2189 | generate_data['stop'] = getCustomStoppingStrings(stopStringsLimit).slice(0, stopStringsLimit).filter(x => x.length >= 1 && x.length <= 16); |
| @@ -2176,7 +2269,15 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2176 | } | 2269 | } |
| 2177 | } | 2270 | } |
| 2178 | 2271 | ||
| 2179 | if ((isOAI || isOpenRouter || isMistral || isCustom || isCohere || isNano || isXAI) && oai_settings.seed >= 0) { | 2272 | if (isPollinations) { |
| 2273 | delete generate_data.temperature; | ||
| 2274 | delete generate_data.top_p; | ||
| 2275 | delete generate_data.frequency_penalty; | ||
| 2276 | delete generate_data.presence_penalty; | ||
| 2277 | delete generate_data.max_tokens; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | if ((isOAI || isOpenRouter || isMistral || isCustom || isCohere || isNano || isXAI || isPollinations) && oai_settings.seed >= 0) { | ||
| 2180 | generate_data['seed'] = oai_settings.seed; | 2281 | generate_data['seed'] = oai_settings.seed; |
| 2181 | } | 2282 | } |
| 2182 | 2283 | ||
| @@ -2289,7 +2390,7 @@ export function getStreamingReply(data, state, { chatCompletionSource = null, ov | |||
| 2289 | state.reasoning += data?.delta?.thinking || ''; | 2390 | state.reasoning += data?.delta?.thinking || ''; |
| 2290 | } | 2391 | } |
| 2291 | return data?.delta?.text || ''; | 2392 | return data?.delta?.text || ''; |
| 2292 | } else if (chat_completion_source === chat_completion_sources.MAKERSUITE) { | 2393 | } else if ([chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI].includes(chat_completion_source)) { |
| 2293 | const inlineData = data?.candidates?.[0]?.content?.parts?.find(x => x.inlineData)?.inlineData; | 2394 | const inlineData = data?.candidates?.[0]?.content?.parts?.find(x => x.inlineData)?.inlineData; |
| 2294 | if (inlineData) { | 2395 | if (inlineData) { |
| 2295 | state.image = `data:${inlineData.mimeType};base64,${inlineData.data}`; | 2396 | state.image = `data:${inlineData.mimeType};base64,${inlineData.data}`; |
| @@ -2372,13 +2473,14 @@ function parseOpenAIChatLogprobs(logprobs) { | |||
| 2372 | return null; | 2473 | return null; |
| 2373 | } | 2474 | } |
| 2374 | 2475 | ||
| 2375 | /** @type {({ token: string, logprob: number }) => [string, number]} */ | 2476 | /** @type {(x: { token: string, logprob: number }) => [string, number]} */ |
| 2376 | const toTuple = (x) => [x.token, x.logprob]; | 2477 | const toTuple = (x) => [x.token, x.logprob]; |
| 2377 | 2478 | ||
| 2378 | return content.map(({ token, logprob, top_logprobs }) => { | 2479 | return content.map(({ token, logprob, top_logprobs }) => { |
| 2379 | // Add the chosen token to top_logprobs if it's not already there, then | 2480 | // Add the chosen token to top_logprobs if it's not already there, then |
| 2380 | // convert to a list of [token, logprob] pairs | 2481 | // convert to a list of [token, logprob] pairs |
| 2381 | const chosenTopToken = top_logprobs.some((top) => token === top.token); | 2482 | const chosenTopToken = top_logprobs.some((top) => token === top.token); |
| 2483 | /** @type {import('./logprobs.js').Candidate[]} */ | ||
| 2382 | const topLogprobs = chosenTopToken | 2484 | const topLogprobs = chosenTopToken |
| 2383 | ? top_logprobs.map(toTuple) | 2485 | ? top_logprobs.map(toTuple) |
| 2384 | : [...top_logprobs.map(toTuple), [token, logprob]]; | 2486 | : [...top_logprobs.map(toTuple), [token, logprob]]; |
| @@ -2403,6 +2505,7 @@ function parseOpenAITextLogprobs(logprobs) { | |||
| 2403 | return tokens.map((token, i) => { | 2505 | return tokens.map((token, i) => { |
| 2404 | // Add the chosen token to top_logprobs if it's not already there, then | 2506 | // Add the chosen token to top_logprobs if it's not already there, then |
| 2405 | // convert to a list of [token, logprob] pairs | 2507 | // convert to a list of [token, logprob] pairs |
| 2508 | /** @type {any[]} */ | ||
| 2406 | const topLogprobs = top_logprobs[i] ? Object.entries(top_logprobs[i]) : []; | 2509 | const topLogprobs = top_logprobs[i] ? Object.entries(top_logprobs[i]) : []; |
| 2407 | const chosenTopToken = topLogprobs.some(([topToken]) => token === topToken); | 2510 | const chosenTopToken = topLogprobs.some(([topToken]) => token === topToken); |
| 2408 | if (!chosenTopToken) { | 2511 | if (!chosenTopToken) { |
| @@ -2677,7 +2780,13 @@ class Message { | |||
| 2677 | * @returns {Promise<string>} Compressed image as a Data URL. | 2780 | * @returns {Promise<string>} Compressed image as a Data URL. |
| 2678 | */ | 2781 | */ |
| 2679 | async compressImage(image) { | 2782 | async compressImage(image) { |
| 2680 | if ([chat_completion_sources.OPENROUTER, chat_completion_sources.MAKERSUITE, chat_completion_sources.MISTRALAI].includes(oai_settings.chat_completion_source)) { | 2783 | const compressImageSources = [ |
| 2784 | chat_completion_sources.OPENROUTER, | ||
| 2785 | chat_completion_sources.MAKERSUITE, | ||
| 2786 | chat_completion_sources.MISTRALAI, | ||
| 2787 | chat_completion_sources.VERTEXAI, | ||
| 2788 | ]; | ||
| 2789 | if (compressImageSources.includes(oai_settings.chat_completion_source)) { | ||
| 2681 | const sizeThreshold = 2 * 1024 * 1024; | 2790 | const sizeThreshold = 2 * 1024 * 1024; |
| 2682 | const dataSize = image.length * 0.75; | 2791 | const dataSize = image.length * 0.75; |
| 2683 | const maxSide = 1024; | 2792 | const maxSide = 1024; |
| @@ -3227,7 +3336,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3227 | openai_setting_names = arr_holder; | 3336 | openai_setting_names = arr_holder; |
| 3228 | 3337 | ||
| 3229 | oai_settings.preset_settings_openai = settings.preset_settings_openai; | 3338 | oai_settings.preset_settings_openai = settings.preset_settings_openai; |
| 3230 | $(`#settings_preset_openai option[value=${openai_setting_names[oai_settings.preset_settings_openai]}]`).attr('selected', true); | 3339 | $(`#settings_preset_openai option[value=${openai_setting_names[oai_settings.preset_settings_openai]}]`).prop('selected', true); |
| 3231 | 3340 | ||
| 3232 | oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; | 3341 | oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; |
| 3233 | oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; | 3342 | oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; |
| @@ -3265,6 +3374,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3265 | oai_settings.deepseek_model = settings.deepseek_model ?? default_settings.deepseek_model; | 3374 | oai_settings.deepseek_model = settings.deepseek_model ?? default_settings.deepseek_model; |
| 3266 | oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model; | 3375 | oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model; |
| 3267 | oai_settings.xai_model = settings.xai_model ?? default_settings.xai_model; | 3376 | oai_settings.xai_model = settings.xai_model ?? default_settings.xai_model; |
| 3377 | oai_settings.pollinations_model = settings.pollinations_model ?? default_settings.pollinations_model; | ||
| 3268 | oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; | 3378 | oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; |
| 3269 | oai_settings.custom_url = settings.custom_url ?? default_settings.custom_url; | 3379 | oai_settings.custom_url = settings.custom_url ?? default_settings.custom_url; |
| 3270 | oai_settings.custom_include_body = settings.custom_include_body ?? default_settings.custom_include_body; | 3380 | oai_settings.custom_include_body = settings.custom_include_body ?? default_settings.custom_include_body; |
| @@ -3272,6 +3382,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3272 | oai_settings.custom_include_headers = settings.custom_include_headers ?? default_settings.custom_include_headers; | 3382 | oai_settings.custom_include_headers = settings.custom_include_headers ?? default_settings.custom_include_headers; |
| 3273 | oai_settings.custom_prompt_post_processing = settings.custom_prompt_post_processing ?? default_settings.custom_prompt_post_processing; | 3383 | oai_settings.custom_prompt_post_processing = settings.custom_prompt_post_processing ?? default_settings.custom_prompt_post_processing; |
| 3274 | oai_settings.google_model = settings.google_model ?? default_settings.google_model; | 3384 | oai_settings.google_model = settings.google_model ?? default_settings.google_model; |
| 3385 | oai_settings.vertexai_model = settings.vertexai_model ?? default_settings.vertexai_model; | ||
| 3275 | oai_settings.chat_completion_source = settings.chat_completion_source ?? default_settings.chat_completion_source; | 3386 | oai_settings.chat_completion_source = settings.chat_completion_source ?? default_settings.chat_completion_source; |
| 3276 | oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale; | 3387 | oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale; |
| 3277 | oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models; | 3388 | oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models; |
| @@ -3301,6 +3412,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3301 | oai_settings.continue_postfix = settings.continue_postfix ?? default_settings.continue_postfix; | 3412 | oai_settings.continue_postfix = settings.continue_postfix ?? default_settings.continue_postfix; |
| 3302 | oai_settings.function_calling = settings.function_calling ?? default_settings.function_calling; | 3413 | oai_settings.function_calling = settings.function_calling ?? default_settings.function_calling; |
| 3303 | oai_settings.openrouter_providers = settings.openrouter_providers ?? default_settings.openrouter_providers; | 3414 | oai_settings.openrouter_providers = settings.openrouter_providers ?? default_settings.openrouter_providers; |
| 3415 | oai_settings.bind_preset_to_connection = settings.bind_preset_to_connection ?? default_settings.bind_preset_to_connection; | ||
| 3304 | 3416 | ||
| 3305 | // Migrate from old settings | 3417 | // Migrate from old settings |
| 3306 | if (settings.names_in_completion === true) { | 3418 | if (settings.names_in_completion === true) { |
| @@ -3328,30 +3440,34 @@ function loadOpenAISettings(data, settings) { | |||
| 3328 | $(`#openai_inline_image_quality option[value="${oai_settings.inline_image_quality}"]`).prop('selected', true); | 3440 | $(`#openai_inline_image_quality option[value="${oai_settings.inline_image_quality}"]`).prop('selected', true); |
| 3329 | 3441 | ||
| 3330 | $('#model_openai_select').val(oai_settings.openai_model); | 3442 | $('#model_openai_select').val(oai_settings.openai_model); |
| 3331 | $(`#model_openai_select option[value="${oai_settings.openai_model}"`).attr('selected', true); | 3443 | $(`#model_openai_select option[value="${oai_settings.openai_model}"`).prop('selected', true); |
| 3332 | $('#model_claude_select').val(oai_settings.claude_model); | 3444 | $('#model_claude_select').val(oai_settings.claude_model); |
| 3333 | $(`#model_claude_select option[value="${oai_settings.claude_model}"`).attr('selected', true); | 3445 | $(`#model_claude_select option[value="${oai_settings.claude_model}"`).prop('selected', true); |
| 3334 | $('#model_windowai_select').val(oai_settings.windowai_model); | 3446 | $('#model_windowai_select').val(oai_settings.windowai_model); |
| 3335 | $(`#model_windowai_select option[value="${oai_settings.windowai_model}"`).attr('selected', true); | 3447 | $(`#model_windowai_select option[value="${oai_settings.windowai_model}"`).prop('selected', true); |
| 3336 | $('#model_google_select').val(oai_settings.google_model); | 3448 | $('#model_google_select').val(oai_settings.google_model); |
| 3337 | $(`#model_google_select option[value="${oai_settings.google_model}"`).attr('selected', true); | 3449 | $(`#model_google_select option[value="${oai_settings.google_model}"`).prop('selected', true); |
| 3450 | $('#model_vertexai_select').val(oai_settings.vertexai_model); | ||
| 3451 | $(`#model_vertexai_select option[value="${oai_settings.vertexai_model}"`).prop('selected', true); | ||
| 3338 | $('#model_ai21_select').val(oai_settings.ai21_model); | 3452 | $('#model_ai21_select').val(oai_settings.ai21_model); |
| 3339 | $(`#model_ai21_select option[value="${oai_settings.ai21_model}"`).attr('selected', true); | 3453 | $(`#model_ai21_select option[value="${oai_settings.ai21_model}"`).prop('selected', true); |
| 3340 | $('#model_mistralai_select').val(oai_settings.mistralai_model); | 3454 | $('#model_mistralai_select').val(oai_settings.mistralai_model); |
| 3341 | $(`#model_mistralai_select option[value="${oai_settings.mistralai_model}"`).attr('selected', true); | 3455 | $(`#model_mistralai_select option[value="${oai_settings.mistralai_model}"`).prop('selected', true); |
| 3342 | $('#model_cohere_select').val(oai_settings.cohere_model); | 3456 | $('#model_cohere_select').val(oai_settings.cohere_model); |
| 3343 | $(`#model_cohere_select option[value="${oai_settings.cohere_model}"`).attr('selected', true); | 3457 | $(`#model_cohere_select option[value="${oai_settings.cohere_model}"`).prop('selected', true); |
| 3344 | $('#model_perplexity_select').val(oai_settings.perplexity_model); | 3458 | $('#model_perplexity_select').val(oai_settings.perplexity_model); |
| 3345 | $(`#model_perplexity_select option[value="${oai_settings.perplexity_model}"`).attr('selected', true); | 3459 | $(`#model_perplexity_select option[value="${oai_settings.perplexity_model}"`).prop('selected', true); |
| 3346 | $('#model_groq_select').val(oai_settings.groq_model); | 3460 | $('#model_groq_select').val(oai_settings.groq_model); |
| 3347 | $(`#model_groq_select option[value="${oai_settings.groq_model}"`).attr('selected', true); | 3461 | $(`#model_groq_select option[value="${oai_settings.groq_model}"`).prop('selected', true); |
| 3348 | $('#model_nanogpt_select').val(oai_settings.nanogpt_model); | 3462 | $('#model_nanogpt_select').val(oai_settings.nanogpt_model); |
| 3349 | $(`#model_nanogpt_select option[value="${oai_settings.nanogpt_model}"`).attr('selected', true); | 3463 | $(`#model_nanogpt_select option[value="${oai_settings.nanogpt_model}"`).prop('selected', true); |
| 3350 | $('#model_deepseek_select').val(oai_settings.deepseek_model); | 3464 | $('#model_deepseek_select').val(oai_settings.deepseek_model); |
| 3351 | $(`#model_deepseek_select option[value="${oai_settings.deepseek_model}"`).prop('selected', true); | 3465 | $(`#model_deepseek_select option[value="${oai_settings.deepseek_model}"`).prop('selected', true); |
| 3352 | $('#model_01ai_select').val(oai_settings.zerooneai_model); | 3466 | $('#model_01ai_select').val(oai_settings.zerooneai_model); |
| 3353 | $('#model_xai_select').val(oai_settings.xai_model); | 3467 | $('#model_xai_select').val(oai_settings.xai_model); |
| 3354 | $(`#model_xai_select option[value="${oai_settings.xai_model}"`).attr('selected', true); | 3468 | $(`#model_xai_select option[value="${oai_settings.xai_model}"`).prop('selected', true); |
| 3469 | $('#model_pollinations_select').val(oai_settings.pollinations_model); | ||
| 3470 | $(`#model_pollinations_select option[value="${oai_settings.pollinations_model}"`).prop('selected', true); | ||
| 3355 | $('#custom_model_id').val(oai_settings.custom_model); | 3471 | $('#custom_model_id').val(oai_settings.custom_model); |
| 3356 | $('#custom_api_url_text').val(oai_settings.custom_url); | 3472 | $('#custom_api_url_text').val(oai_settings.custom_url); |
| 3357 | $('#openai_max_context').val(oai_settings.openai_max_context); | 3473 | $('#openai_max_context').val(oai_settings.openai_max_context); |
| @@ -3415,6 +3531,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3415 | $('#openai_show_thoughts').prop('checked', oai_settings.show_thoughts); | 3531 | $('#openai_show_thoughts').prop('checked', oai_settings.show_thoughts); |
| 3416 | $('#openai_enable_web_search').prop('checked', oai_settings.enable_web_search); | 3532 | $('#openai_enable_web_search').prop('checked', oai_settings.enable_web_search); |
| 3417 | $('#openai_request_images').prop('checked', oai_settings.request_images); | 3533 | $('#openai_request_images').prop('checked', oai_settings.request_images); |
| 3534 | $('#bind_preset_to_connection').prop('checked', oai_settings.bind_preset_to_connection); | ||
| 3418 | 3535 | ||
| 3419 | $('#openai_reasoning_effort').val(oai_settings.reasoning_effort); | 3536 | $('#openai_reasoning_effort').val(oai_settings.reasoning_effort); |
| 3420 | $(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true); | 3537 | $(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true); |
| @@ -3457,7 +3574,7 @@ function loadOpenAISettings(data, settings) { | |||
| 3457 | $('#chat_completion_source').val(oai_settings.chat_completion_source).trigger('change'); | 3574 | $('#chat_completion_source').val(oai_settings.chat_completion_source).trigger('change'); |
| 3458 | $('#oai_max_context_unlocked').prop('checked', oai_settings.max_context_unlocked); | 3575 | $('#oai_max_context_unlocked').prop('checked', oai_settings.max_context_unlocked); |
| 3459 | $('#custom_prompt_post_processing').val(oai_settings.custom_prompt_post_processing); | 3576 | $('#custom_prompt_post_processing').val(oai_settings.custom_prompt_post_processing); |
| 3460 | $(`#custom_prompt_post_processing option[value="${oai_settings.custom_prompt_post_processing}"]`).attr('selected', true); | 3577 | $(`#custom_prompt_post_processing option[value="${oai_settings.custom_prompt_post_processing}"]`).prop('selected', true); |
| 3461 | } | 3578 | } |
| 3462 | 3579 | ||
| 3463 | function setNamesBehaviorControls() { | 3580 | function setNamesBehaviorControls() { |
| @@ -3527,6 +3644,7 @@ async function getStatusOpen() { | |||
| 3527 | chat_completion_sources.CLAUDE, | 3644 | chat_completion_sources.CLAUDE, |
| 3528 | chat_completion_sources.AI21, | 3645 | chat_completion_sources.AI21, |
| 3529 | chat_completion_sources.MAKERSUITE, | 3646 | chat_completion_sources.MAKERSUITE, |
| 3647 | chat_completion_sources.VERTEXAI, | ||
| 3530 | chat_completion_sources.PERPLEXITY, | 3648 | chat_completion_sources.PERPLEXITY, |
| 3531 | chat_completion_sources.GROQ, | 3649 | chat_completion_sources.GROQ, |
| 3532 | ]; | 3650 | ]; |
| @@ -3548,7 +3666,16 @@ async function getStatusOpen() { | |||
| 3548 | chat_completion_source: oai_settings.chat_completion_source, | 3666 | chat_completion_source: oai_settings.chat_completion_source, |
| 3549 | }; | 3667 | }; |
| 3550 | 3668 | ||
| 3551 | if (oai_settings.reverse_proxy && [chat_completion_sources.CLAUDE, chat_completion_sources.OPENAI, chat_completion_sources.MISTRALAI, chat_completion_sources.MAKERSUITE, chat_completion_sources.DEEPSEEK, chat_completion_sources.XAI].includes(oai_settings.chat_completion_source)) { | 3669 | const validateProxySources = [ |
| 3670 | chat_completion_sources.CLAUDE, | ||
| 3671 | chat_completion_sources.OPENAI, | ||
| 3672 | chat_completion_sources.MISTRALAI, | ||
| 3673 | chat_completion_sources.MAKERSUITE, | ||
| 3674 | chat_completion_sources.VERTEXAI, | ||
| 3675 | chat_completion_sources.DEEPSEEK, | ||
| 3676 | chat_completion_sources.XAI, | ||
| 3677 | ]; | ||
| 3678 | if (oai_settings.reverse_proxy && validateProxySources.includes(oai_settings.chat_completion_source)) { | ||
| 3552 | await validateReverseProxy(); | 3679 | await validateReverseProxy(); |
| 3553 | } | 3680 | } |
| 3554 | 3681 | ||
| @@ -3631,6 +3758,8 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3631 | perplexity_model: settings.perplexity_model, | 3758 | perplexity_model: settings.perplexity_model, |
| 3632 | groq_model: settings.groq_model, | 3759 | groq_model: settings.groq_model, |
| 3633 | zerooneai_model: settings.zerooneai_model, | 3760 | zerooneai_model: settings.zerooneai_model, |
| 3761 | xai_model: settings.xai_model, | ||
| 3762 | pollinations_model: settings.pollinations_model, | ||
| 3634 | custom_model: settings.custom_model, | 3763 | custom_model: settings.custom_model, |
| 3635 | custom_url: settings.custom_url, | 3764 | custom_url: settings.custom_url, |
| 3636 | custom_include_body: settings.custom_include_body, | 3765 | custom_include_body: settings.custom_include_body, |
| @@ -3638,6 +3767,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3638 | custom_include_headers: settings.custom_include_headers, | 3767 | custom_include_headers: settings.custom_include_headers, |
| 3639 | custom_prompt_post_processing: settings.custom_prompt_post_processing, | 3768 | custom_prompt_post_processing: settings.custom_prompt_post_processing, |
| 3640 | google_model: settings.google_model, | 3769 | google_model: settings.google_model, |
| 3770 | vertexai_model: settings.vertexai_model, | ||
| 3641 | temperature: settings.temp_openai, | 3771 | temperature: settings.temp_openai, |
| 3642 | frequency_penalty: settings.freq_pen_openai, | 3772 | frequency_penalty: settings.freq_pen_openai, |
| 3643 | presence_penalty: settings.pres_pen_openai, | 3773 | presence_penalty: settings.pres_pen_openai, |
| @@ -3690,7 +3820,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3690 | n: settings.n, | 3820 | n: settings.n, |
| 3691 | }; | 3821 | }; |
| 3692 | 3822 | ||
| 3693 | const savePresetSettings = await fetch(`/api/presets/save-openai?name=${name}`, { | 3823 | const savePresetSettings = await fetch(`/api/presets/save-openai?name=${encodeURIComponent(name)}`, { |
| 3694 | method: 'POST', | 3824 | method: 'POST', |
| 3695 | headers: getRequestHeaders(), | 3825 | headers: getRequestHeaders(), |
| 3696 | body: JSON.stringify(presetBody), | 3826 | body: JSON.stringify(presetBody), |
| @@ -3703,7 +3833,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3703 | oai_settings.preset_settings_openai = data.name; | 3833 | oai_settings.preset_settings_openai = data.name; |
| 3704 | const value = openai_setting_names[data.name]; | 3834 | const value = openai_setting_names[data.name]; |
| 3705 | Object.assign(openai_settings[value], presetBody); | 3835 | Object.assign(openai_settings[value], presetBody); |
| 3706 | $(`#settings_preset_openai option[value="${value}"]`).attr('selected', true); | 3836 | $(`#settings_preset_openai option[value="${value}"]`).prop('selected', true); |
| 3707 | if (triggerUi) $('#settings_preset_openai').trigger('change'); | 3837 | if (triggerUi) $('#settings_preset_openai').trigger('change'); |
| 3708 | } | 3838 | } |
| 3709 | else { | 3839 | else { |
| @@ -3711,7 +3841,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3711 | openai_setting_names[data.name] = openai_settings.length - 1; | 3841 | openai_setting_names[data.name] = openai_settings.length - 1; |
| 3712 | const option = document.createElement('option'); | 3842 | const option = document.createElement('option'); |
| 3713 | option.selected = true; | 3843 | option.selected = true; |
| 3714 | option.value = openai_settings.length - 1; | 3844 | option.value = String(openai_settings.length - 1); |
| 3715 | option.innerText = data.name; | 3845 | option.innerText = data.name; |
| 3716 | if (triggerUi) $('#settings_preset_openai').append(option).trigger('change'); | 3846 | if (triggerUi) $('#settings_preset_openai').append(option).trigger('change'); |
| 3717 | } | 3847 | } |
| @@ -3817,7 +3947,7 @@ function createLogitBiasListItem(entry) { | |||
| 3817 | } | 3947 | } |
| 3818 | 3948 | ||
| 3819 | async function createNewLogitBiasPreset() { | 3949 | async function createNewLogitBiasPreset() { |
| 3820 | const name = await callPopup('Preset name:', 'input'); | 3950 | const name = await Popup.show.input(t`Preset name:`, null); |
| 3821 | 3951 | ||
| 3822 | if (!name) { | 3952 | if (!name) { |
| 3823 | return; | 3953 | return; |
| @@ -3902,7 +4032,7 @@ async function onPresetImportFileChange(e) { | |||
| 3902 | 4032 | ||
| 3903 | await eventSource.emit(event_types.OAI_PRESET_IMPORT_READY, { data: presetBody, presetName: name }); | 4033 | await eventSource.emit(event_types.OAI_PRESET_IMPORT_READY, { data: presetBody, presetName: name }); |
| 3904 | 4034 | ||
| 3905 | const savePresetSettings = await fetch(`/api/presets/save-openai?name=${name}`, { | 4035 | const savePresetSettings = await fetch(`/api/presets/save-openai?name=${encodeURIComponent(name)}`, { |
| 3906 | method: 'POST', | 4036 | method: 'POST', |
| 3907 | headers: getRequestHeaders(), | 4037 | headers: getRequestHeaders(), |
| 3908 | body: importedFile, | 4038 | body: importedFile, |
| @@ -3919,14 +4049,14 @@ async function onPresetImportFileChange(e) { | |||
| 3919 | oai_settings.preset_settings_openai = data.name; | 4049 | oai_settings.preset_settings_openai = data.name; |
| 3920 | const value = openai_setting_names[data.name]; | 4050 | const value = openai_setting_names[data.name]; |
| 3921 | Object.assign(openai_settings[value], presetBody); | 4051 | Object.assign(openai_settings[value], presetBody); |
| 3922 | $(`#settings_preset_openai option[value="${value}"]`).attr('selected', true); | 4052 | $(`#settings_preset_openai option[value="${value}"]`).prop('selected', true); |
| 3923 | $('#settings_preset_openai').trigger('change'); | 4053 | $('#settings_preset_openai').trigger('change'); |
| 3924 | } else { | 4054 | } else { |
| 3925 | openai_settings.push(presetBody); | 4055 | openai_settings.push(presetBody); |
| 3926 | openai_setting_names[data.name] = openai_settings.length - 1; | 4056 | openai_setting_names[data.name] = openai_settings.length - 1; |
| 3927 | const option = document.createElement('option'); | 4057 | const option = document.createElement('option'); |
| 3928 | option.selected = true; | 4058 | option.selected = true; |
| 3929 | option.value = openai_settings.length - 1; | 4059 | option.value = String(openai_settings.length - 1); |
| 3930 | option.innerText = data.name; | 4060 | option.innerText = data.name; |
| 3931 | $('#settings_preset_openai').append(option).trigger('change'); | 4061 | $('#settings_preset_openai').append(option).trigger('change'); |
| 3932 | } | 4062 | } |
| @@ -3941,7 +4071,7 @@ async function onExportPresetClick() { | |||
| 3941 | const preset = structuredClone(openai_settings[openai_setting_names[oai_settings.preset_settings_openai]]); | 4071 | const preset = structuredClone(openai_settings[openai_setting_names[oai_settings.preset_settings_openai]]); |
| 3942 | 4072 | ||
| 3943 | const fieldValues = sensitiveFields.filter(field => preset[field]).map(field => `<b>${field}</b>: <code>${preset[field]}</code>`); | 4073 | const fieldValues = sensitiveFields.filter(field => preset[field]).map(field => `<b>${field}</b>: <code>${preset[field]}</code>`); |
| 3944 | const shouldConfirm = fieldValues.length > 0; | 4074 | if (fieldValues.length > 0) { |
| 3945 | const textHeader = t`Your preset contains proxy and/or custom endpoint settings.`; | 4075 | const textHeader = t`Your preset contains proxy and/or custom endpoint settings.`; |
| 3946 | const textMessage = '<div>' + t`Do you want to remove these fields before exporting?` + `</div><br>${DOMPurify.sanitize(fieldValues.join('<br>'))}`; | 4076 | const textMessage = '<div>' + t`Do you want to remove these fields before exporting?` + `</div><br>${DOMPurify.sanitize(fieldValues.join('<br>'))}`; |
| 3947 | const cancelButton = { text: 'Cancel', result: POPUP_RESULT.CANCELLED, appendAtEnd: true }; | 4077 | const cancelButton = { text: 'Cancel', result: POPUP_RESULT.CANCELLED, appendAtEnd: true }; |
| @@ -3953,9 +4083,22 @@ async function onExportPresetClick() { | |||
| 3953 | return; | 4083 | return; |
| 3954 | } | 4084 | } |
| 3955 | 4085 | ||
| 3956 | if (!shouldConfirm || popupResult === POPUP_RESULT.AFFIRMATIVE) { | 4086 | if (popupResult === POPUP_RESULT.AFFIRMATIVE) { |
| 3957 | sensitiveFields.forEach(field => delete preset[field]); | 4087 | sensitiveFields.forEach(field => delete preset[field]); |
| 3958 | } | 4088 | } |
| 4089 | } | ||
| 4090 | |||
| 4091 | const exportConnectionTemplate = $(await renderTemplateAsync('exportPreset')); | ||
| 4092 | await new Popup(exportConnectionTemplate, POPUP_TYPE.TEXT).show(); | ||
| 4093 | |||
| 4094 | const removeConnectionData = exportConnectionTemplate.find('input[name="export_connection_data"]:checked').val() === 'false'; | ||
| 4095 | if (removeConnectionData) { | ||
| 4096 | for (const [, [, settingName, , isConnection]] of Object.entries(settingsToUpdate)) { | ||
| 4097 | if (isConnection) { | ||
| 4098 | delete preset[settingName]; | ||
| 4099 | } | ||
| 4100 | } | ||
| 4101 | } | ||
| 3959 | 4102 | ||
| 3960 | await eventSource.emit(event_types.OAI_PRESET_EXPORT_READY, preset); | 4103 | await eventSource.emit(event_types.OAI_PRESET_EXPORT_READY, preset); |
| 3961 | const presetJsonString = JSON.stringify(preset, null, 4); | 4104 | const presetJsonString = JSON.stringify(preset, null, 4); |
| @@ -4031,7 +4174,7 @@ async function onDeletePresetClick() { | |||
| 4031 | if (Object.keys(openai_setting_names).length) { | 4174 | if (Object.keys(openai_setting_names).length) { |
| 4032 | oai_settings.preset_settings_openai = Object.keys(openai_setting_names)[0]; | 4175 | oai_settings.preset_settings_openai = Object.keys(openai_setting_names)[0]; |
| 4033 | const newValue = openai_setting_names[oai_settings.preset_settings_openai]; | 4176 | const newValue = openai_setting_names[oai_settings.preset_settings_openai]; |
| 4034 | $(`#settings_preset_openai option[value="${newValue}"]`).attr('selected', true); | 4177 | $(`#settings_preset_openai option[value="${newValue}"]`).prop('selected', true); |
| 4035 | $('#settings_preset_openai').trigger('change'); | 4178 | $('#settings_preset_openai').trigger('change'); |
| 4036 | } | 4179 | } |
| 4037 | 4180 | ||
| @@ -4063,7 +4206,7 @@ async function onLogitBiasPresetDeleteClick() { | |||
| 4063 | 4206 | ||
| 4064 | if (Object.keys(oai_settings.bias_presets).length) { | 4207 | if (Object.keys(oai_settings.bias_presets).length) { |
| 4065 | oai_settings.bias_preset_selected = Object.keys(oai_settings.bias_presets)[0]; | 4208 | oai_settings.bias_preset_selected = Object.keys(oai_settings.bias_presets)[0]; |
| 4066 | $(`#openai_logit_bias_preset option[value="${oai_settings.bias_preset_selected}"]`).attr('selected', true); | 4209 | $(`#openai_logit_bias_preset option[value="${oai_settings.bias_preset_selected}"]`).prop('selected', true); |
| 4067 | $('#openai_logit_bias_preset').trigger('change'); | 4210 | $('#openai_logit_bias_preset').trigger('change'); |
| 4068 | } | 4211 | } |
| 4069 | 4212 | ||
| @@ -4102,9 +4245,15 @@ function onSettingsPresetChange() { | |||
| 4102 | savePreset: saveOpenAIPreset, | 4245 | savePreset: saveOpenAIPreset, |
| 4103 | presetNameBefore: presetNameBefore, | 4246 | presetNameBefore: presetNameBefore, |
| 4104 | }).finally(r => { | 4247 | }).finally(r => { |
| 4248 | if (oai_settings.bind_preset_to_connection) { | ||
| 4105 | $('.model_custom_select').empty(); | 4249 | $('.model_custom_select').empty(); |
| 4250 | } | ||
| 4251 | |||
| 4252 | for (const [key, [selector, setting, isCheckbox, isConnection]] of Object.entries(settingsToUpdate)) { | ||
| 4253 | if (isConnection && !oai_settings.bind_preset_to_connection) { | ||
| 4254 | continue; | ||
| 4255 | } | ||
| 4106 | 4256 | ||
| 4107 | for (const [key, [selector, setting, isCheckbox]] of Object.entries(settingsToUpdate)) { | ||
| 4108 | if (preset[key] !== undefined) { | 4257 | if (preset[key] !== undefined) { |
| 4109 | if (isCheckbox) { | 4258 | if (isCheckbox) { |
| 4110 | updateCheckbox(selector, preset[key]); | 4259 | updateCheckbox(selector, preset[key]); |
| @@ -4115,9 +4264,13 @@ function onSettingsPresetChange() { | |||
| 4115 | } | 4264 | } |
| 4116 | } | 4265 | } |
| 4117 | 4266 | ||
| 4267 | // These cannot be changed via preset if unbound to connection | ||
| 4268 | if (oai_settings.bind_preset_to_connection) { | ||
| 4118 | $('#chat_completion_source').trigger('change'); | 4269 | $('#chat_completion_source').trigger('change'); |
| 4119 | $('#openai_logit_bias_preset').trigger('change'); | ||
| 4120 | $('#openrouter_providers_chat').trigger('change'); | 4270 | $('#openrouter_providers_chat').trigger('change'); |
| 4271 | } | ||
| 4272 | |||
| 4273 | $('#openai_logit_bias_preset').trigger('change'); | ||
| 4121 | 4274 | ||
| 4122 | saveSettingsDebounced(); | 4275 | saveSettingsDebounced(); |
| 4123 | eventSource.emit(event_types.OAI_PRESET_CHANGED_AFTER); | 4276 | eventSource.emit(event_types.OAI_PRESET_CHANGED_AFTER); |
| @@ -4255,9 +4408,10 @@ function getMistralMaxContext(model, isUnlocked) { | |||
| 4255 | 'codestral-2405': 32768, | 4408 | 'codestral-2405': 32768, |
| 4256 | 'mistral-embed': 32768, | 4409 | 'mistral-embed': 32768, |
| 4257 | 'mistral-large-2402': 32768, | 4410 | 'mistral-large-2402': 32768, |
| 4258 | 'mistral-medium': 32768, | 4411 | 'mistral-medium': 131072, |
| 4259 | 'mistral-medium-2312': 32768, | 4412 | 'mistral-medium-2312': 32768, |
| 4260 | 'mistral-medium-latest': 32768, | 4413 | 'mistral-medium-2505': 131072, |
| 4414 | 'mistral-medium-latest': 131072, | ||
| 4261 | 'mistral-moderation-2411': 32768, | 4415 | 'mistral-moderation-2411': 32768, |
| 4262 | 'mistral-moderation-latest': 32768, | 4416 | 'mistral-moderation-latest': 32768, |
| 4263 | 'mistral-ocr-2503': 32768, | 4417 | 'mistral-ocr-2503': 32768, |
| @@ -4275,6 +4429,8 @@ function getMistralMaxContext(model, isUnlocked) { | |||
| 4275 | 'mistral-tiny-2312': 32768, | 4429 | 'mistral-tiny-2312': 32768, |
| 4276 | 'open-mistral-7b': 32768, | 4430 | 'open-mistral-7b': 32768, |
| 4277 | 'open-mixtral-8x7b': 32768, | 4431 | 'open-mixtral-8x7b': 32768, |
| 4432 | 'devstral-small-2505': 131072, | ||
| 4433 | 'devstral-small-latest': 131072, | ||
| 4278 | }; | 4434 | }; |
| 4279 | 4435 | ||
| 4280 | // Return context size if model found, otherwise default to 32k | 4436 | // Return context size if model found, otherwise default to 32k |
| @@ -4369,6 +4525,11 @@ async function onModelChange() { | |||
| 4369 | oai_settings.google_model = value; | 4525 | oai_settings.google_model = value; |
| 4370 | } | 4526 | } |
| 4371 | 4527 | ||
| 4528 | if ($(this).is('#model_vertexai_select')) { | ||
| 4529 | console.log('Vertex AI model changed to', value); | ||
| 4530 | oai_settings.vertexai_model = value; | ||
| 4531 | } | ||
| 4532 | |||
| 4372 | if ($(this).is('#model_mistralai_select')) { | 4533 | if ($(this).is('#model_mistralai_select')) { |
| 4373 | // Upgrade old mistral models to new naming scheme | 4534 | // Upgrade old mistral models to new naming scheme |
| 4374 | // would have done this in loadOpenAISettings, but it wasn't updating on preset change? | 4535 | // would have done this in loadOpenAISettings, but it wasn't updating on preset change? |
| @@ -4428,6 +4589,11 @@ async function onModelChange() { | |||
| 4428 | $('#custom_model_id').val(value).trigger('input'); | 4589 | $('#custom_model_id').val(value).trigger('input'); |
| 4429 | } | 4590 | } |
| 4430 | 4591 | ||
| 4592 | if (value && $(this).is('#model_pollinations_select')) { | ||
| 4593 | console.log('Pollinations model changed to', value); | ||
| 4594 | oai_settings.pollinations_model = value; | ||
| 4595 | } | ||
| 4596 | |||
| 4431 | if ($(this).is('#model_xai_select')) { | 4597 | if ($(this).is('#model_xai_select')) { |
| 4432 | console.log('XAI model changed to', value); | 4598 | console.log('XAI model changed to', value); |
| 4433 | oai_settings.xai_model = value; | 4599 | oai_settings.xai_model = value; |
| @@ -4444,23 +4610,19 @@ async function onModelChange() { | |||
| 4444 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | 4610 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4445 | } | 4611 | } |
| 4446 | 4612 | ||
| 4447 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { | 4613 | if ([chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI].includes(oai_settings.chat_completion_source)) { |
| 4448 | if (oai_settings.max_context_unlocked) { | 4614 | if (oai_settings.max_context_unlocked) { |
| 4449 | $('#openai_max_context').attr('max', max_2mil); | 4615 | $('#openai_max_context').attr('max', max_2mil); |
| 4450 | } else if (value.includes('gemini-exp-1114') || value.includes('gemini-exp-1121') || value.includes('gemini-2.0-flash-thinking-exp-1219')) { | 4616 | } else if (value.includes('gemini-1.5-pro')) { |
| 4451 | $('#openai_max_context').attr('max', max_32k); | ||
| 4452 | } else if (value.includes('gemini-1.5-pro') || value.includes('gemini-exp-1206') || value.includes('gemini-2.0-pro')) { | ||
| 4453 | $('#openai_max_context').attr('max', max_2mil); | 4617 | $('#openai_max_context').attr('max', max_2mil); |
| 4454 | } else if (value.includes('gemini-1.5-flash') || value.includes('gemini-2.0-flash') || value.includes('gemini-2.5-flash-preview-04-17') || value.includes('gemini-2.5-pro-exp-03-25') || value.includes('gemini-2.5-pro-preview-03-25')) { | 4618 | } else if (value.includes('gemini-1.5-flash') || value.includes('gemini-2.0-flash') || value.includes('gemini-2.0-pro') || value.includes('gemini-exp') || value.includes('gemini-2.5-flash') || value.includes('gemini-2.5-pro') || value.includes('learnlm-2.0-flash')) { |
| 4455 | $('#openai_max_context').attr('max', max_1mil); | 4619 | $('#openai_max_context').attr('max', max_1mil); |
| 4456 | } else if (value.includes('gemini-1.0-pro') || value === 'gemini-pro') { | 4620 | } else if (value.includes('gemma-3-27b-it')) { |
| 4457 | $('#openai_max_context').attr('max', max_32k); | ||
| 4458 | } else if (value.includes('gemini-1.0-ultra') || value === 'gemini-ultra') { | ||
| 4459 | $('#openai_max_context').attr('max', max_32k); | ||
| 4460 | } else if (value.includes('gemma-3')) { | ||
| 4461 | $('#openai_max_context').attr('max', max_128k); | 4621 | $('#openai_max_context').attr('max', max_128k); |
| 4622 | } else if (value.includes('gemma-3') || value.includes('learnlm-1.5-pro-experimental')) { | ||
| 4623 | $('#openai_max_context').attr('max', max_32k); | ||
| 4462 | } else { | 4624 | } else { |
| 4463 | $('#openai_max_context').attr('max', max_4k); | 4625 | $('#openai_max_context').attr('max', max_32k); |
| 4464 | } | 4626 | } |
| 4465 | let makersuite_max_temp = (value.includes('vision') || value.includes('ultra') || value.includes('gemma')) ? 1.0 : 2.0; | 4627 | let makersuite_max_temp = (value.includes('vision') || value.includes('ultra') || value.includes('gemma')) ? 1.0 : 2.0; |
| 4466 | oai_settings.temp_openai = Math.min(makersuite_max_temp, oai_settings.temp_openai); | 4628 | oai_settings.temp_openai = Math.min(makersuite_max_temp, oai_settings.temp_openai); |
| @@ -4499,7 +4661,7 @@ async function onModelChange() { | |||
| 4499 | if (oai_settings.max_context_unlocked) { | 4661 | if (oai_settings.max_context_unlocked) { |
| 4500 | $('#openai_max_context').attr('max', max_200k); | 4662 | $('#openai_max_context').attr('max', max_200k); |
| 4501 | } | 4663 | } |
| 4502 | else if (value == 'claude-2.1' || value.startsWith('claude-3')) { | 4664 | else if (value == 'claude-2.1' || value.startsWith('claude-3') || value.startsWith('claude-opus') || value.startsWith('claude-sonnet')) { |
| 4503 | $('#openai_max_context').attr('max', max_200k); | 4665 | $('#openai_max_context').attr('max', max_200k); |
| 4504 | } | 4666 | } |
| 4505 | else if (value.endsWith('100k') || value.startsWith('claude-2') || value === 'claude-instant-1.2') { | 4667 | else if (value.endsWith('100k') || value.startsWith('claude-2') || value === 'claude-instant-1.2') { |
| @@ -4672,6 +4834,18 @@ async function onModelChange() { | |||
| 4672 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | 4834 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4673 | } | 4835 | } |
| 4674 | 4836 | ||
| 4837 | if (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS) { | ||
| 4838 | if (oai_settings.max_context_unlocked) { | ||
| 4839 | $('#openai_max_context').attr('max', unlocked_max); | ||
| 4840 | } else { | ||
| 4841 | $('#openai_max_context').attr('max', max_128k); | ||
| 4842 | } | ||
| 4843 | |||
| 4844 | oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context); | ||
| 4845 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | ||
| 4846 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | ||
| 4847 | } | ||
| 4848 | |||
| 4675 | if (oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK) { | 4849 | if (oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK) { |
| 4676 | if (oai_settings.max_context_unlocked) { | 4850 | if (oai_settings.max_context_unlocked) { |
| 4677 | $('#openai_max_context').attr('max', unlocked_max); | 4851 | $('#openai_max_context').attr('max', unlocked_max); |
| @@ -4804,6 +4978,19 @@ async function onConnectButtonClick(e) { | |||
| 4804 | } | 4978 | } |
| 4805 | } | 4979 | } |
| 4806 | 4980 | ||
| 4981 | if (oai_settings.chat_completion_source == chat_completion_sources.VERTEXAI) { | ||
| 4982 | const api_key_vertexai = String($('#api_key_vertexai').val()).trim(); | ||
| 4983 | |||
| 4984 | if (api_key_vertexai.length) { | ||
| 4985 | await writeSecret(SECRET_KEYS.VERTEXAI, api_key_vertexai); | ||
| 4986 | } | ||
| 4987 | |||
| 4988 | if (!secret_state[SECRET_KEYS.VERTEXAI] && !oai_settings.reverse_proxy) { | ||
| 4989 | console.log('No secret key saved for Vertex AI'); | ||
| 4990 | return; | ||
| 4991 | } | ||
| 4992 | } | ||
| 4993 | |||
| 4807 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { | 4994 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { |
| 4808 | const api_key_claude = String($('#api_key_claude').val()).trim(); | 4995 | const api_key_claude = String($('#api_key_claude').val()).trim(); |
| 4809 | 4996 | ||
| @@ -4981,6 +5168,9 @@ function toggleChatCompletionForms() { | |||
| 4981 | else if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { | 5168 | else if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { |
| 4982 | $('#model_google_select').trigger('change'); | 5169 | $('#model_google_select').trigger('change'); |
| 4983 | } | 5170 | } |
| 5171 | else if (oai_settings.chat_completion_source == chat_completion_sources.VERTEXAI) { | ||
| 5172 | $('#model_vertexai_select').trigger('change'); | ||
| 5173 | } | ||
| 4984 | else if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) { | 5174 | else if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) { |
| 4985 | $('#model_openrouter_select').trigger('change'); | 5175 | $('#model_openrouter_select').trigger('change'); |
| 4986 | } | 5176 | } |
| @@ -5014,6 +5204,9 @@ function toggleChatCompletionForms() { | |||
| 5014 | else if (oai_settings.chat_completion_source == chat_completion_sources.XAI) { | 5204 | else if (oai_settings.chat_completion_source == chat_completion_sources.XAI) { |
| 5015 | $('#model_xai_select').trigger('change'); | 5205 | $('#model_xai_select').trigger('change'); |
| 5016 | } | 5206 | } |
| 5207 | else if (oai_settings.chat_completion_source == chat_completion_sources.POLLINATIONS) { | ||
| 5208 | $('#model_pollinations_select').trigger('change'); | ||
| 5209 | } | ||
| 5017 | $('[data-source]').each(function () { | 5210 | $('[data-source]').each(function () { |
| 5018 | const validSources = $(this).data('source').split(','); | 5211 | const validSources = $(this).data('source').split(','); |
| 5019 | $(this).toggle(validSources.includes(oai_settings.chat_completion_source)); | 5212 | $(this).toggle(validSources.includes(oai_settings.chat_completion_source)); |
| @@ -5028,7 +5221,7 @@ async function testApiConnection() { | |||
| 5028 | } | 5221 | } |
| 5029 | 5222 | ||
| 5030 | try { | 5223 | try { |
| 5031 | const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }]); | 5224 | const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }], new AbortController().signal); |
| 5032 | console.log(reply); | 5225 | console.log(reply); |
| 5033 | toastr.success(t`API connection successful!`); | 5226 | toastr.success(t`API connection successful!`); |
| 5034 | } | 5227 | } |
| @@ -5098,75 +5291,51 @@ export function isImageInliningSupported() { | |||
| 5098 | 5291 | ||
| 5099 | // gultra just isn't being offered as multimodal, thanks google. | 5292 | // gultra just isn't being offered as multimodal, thanks google. |
| 5100 | const visionSupportedModels = [ | 5293 | const visionSupportedModels = [ |
| 5101 | 'gpt-4-vision', | 5294 | // OpenAI |
| 5102 | 'gemini-2.5-pro-exp-03-25', | 5295 | 'chatgpt-4o-latest', |
| 5103 | 'gemini-2.5-pro-preview-03-25', | ||
| 5104 | 'gemini-2.0-pro-exp', | ||
| 5105 | 'gemini-2.0-pro-exp-02-05', | ||
| 5106 | 'gemini-2.5-flash-preview-04-17', | ||
| 5107 | 'gemini-2.0-flash-lite-preview', | ||
| 5108 | 'gemini-2.0-flash-lite-preview-02-05', | ||
| 5109 | 'gemini-2.0-flash', | ||
| 5110 | 'gemini-2.0-flash-001', | ||
| 5111 | 'gemini-2.0-flash-thinking-exp-1219', | ||
| 5112 | 'gemini-2.0-flash-thinking-exp-01-21', | ||
| 5113 | 'gemini-2.0-flash-thinking-exp', | ||
| 5114 | 'gemini-2.0-flash-exp', | ||
| 5115 | 'gemini-2.0-flash-exp-image-generation', | ||
| 5116 | 'gemini-1.5-flash', | ||
| 5117 | 'gemini-1.5-flash-latest', | ||
| 5118 | 'gemini-1.5-flash-001', | ||
| 5119 | 'gemini-1.5-flash-002', | ||
| 5120 | 'gemini-1.5-flash-exp-0827', | ||
| 5121 | 'gemini-1.5-flash-8b', | ||
| 5122 | 'gemini-1.5-flash-8b-exp-0827', | ||
| 5123 | 'gemini-1.5-flash-8b-exp-0924', | ||
| 5124 | 'gemini-exp-1114', | ||
| 5125 | 'gemini-exp-1121', | ||
| 5126 | 'gemini-exp-1206', | ||
| 5127 | 'gemini-1.0-pro-vision-latest', | ||
| 5128 | 'gemini-1.5-pro', | ||
| 5129 | 'gemini-1.5-pro-latest', | ||
| 5130 | 'gemini-1.5-pro-001', | ||
| 5131 | 'gemini-1.5-pro-002', | ||
| 5132 | 'gemini-1.5-pro-exp-0801', | ||
| 5133 | 'gemini-1.5-pro-exp-0827', | ||
| 5134 | 'claude-3', | ||
| 5135 | 'claude-3-5', | ||
| 5136 | 'claude-3-7', | ||
| 5137 | 'gpt-4-turbo', | 5296 | 'gpt-4-turbo', |
| 5138 | 'gpt-4o', | 5297 | 'gpt-4-vision', |
| 5139 | 'gpt-4o-mini', | 5298 | 'gpt-4.1', |
| 5140 | 'gpt-4.5-preview', | 5299 | 'gpt-4.5-preview', |
| 5141 | 'gpt-4.5-preview-2025-02-27', | 5300 | 'gpt-4o', |
| 5142 | 'o1', | 5301 | 'o1', |
| 5143 | 'o1-2024-12-17', | 5302 | 'o3', |
| 5144 | 'chatgpt-4o-latest', | 5303 | 'o4-mini', |
| 5304 | // 01.AI (Yi) | ||
| 5145 | 'yi-vision', | 5305 | 'yi-vision', |
| 5146 | 'mistral-large-pixtral-2411', | 5306 | // Claude |
| 5307 | 'claude-3', | ||
| 5308 | 'claude-opus-4', | ||
| 5309 | 'claude-sonnet-4', | ||
| 5310 | // Cohere | ||
| 5311 | 'c4ai-aya-vision', | ||
| 5312 | // Google AI Studio | ||
| 5313 | 'gemini-1.5', | ||
| 5314 | 'gemini-2.0', | ||
| 5315 | 'gemini-2.5', | ||
| 5316 | 'gemini-exp-1206', | ||
| 5317 | 'learnlm', | ||
| 5318 | // MistralAI | ||
| 5147 | 'mistral-small-2503', | 5319 | 'mistral-small-2503', |
| 5148 | 'mistral-small-latest', | 5320 | 'mistral-small-latest', |
| 5149 | 'pixtral-12b-latest', | 5321 | 'mistral-medium-latest', |
| 5150 | 'pixtral-12b', | 5322 | 'mistral-medium-2505', |
| 5151 | 'pixtral-12b-2409', | 5323 | 'pixtral', |
| 5152 | 'pixtral-large-latest', | 5324 | // xAI (Grok) |
| 5153 | 'pixtral-large-2411', | ||
| 5154 | 'c4ai-aya-vision-8b', | ||
| 5155 | 'c4ai-aya-vision-32b', | ||
| 5156 | 'grok-2-vision', | 5325 | 'grok-2-vision', |
| 5157 | 'grok-vision', | 5326 | 'grok-vision', |
| 5158 | 'gpt-4.1', | ||
| 5159 | 'o3', | ||
| 5160 | 'o3-2025-04-16', | ||
| 5161 | 'o4-mini', | ||
| 5162 | 'o4-mini-2025-04-16', | ||
| 5163 | ]; | 5327 | ]; |
| 5164 | 5328 | ||
| 5165 | switch (oai_settings.chat_completion_source) { | 5329 | switch (oai_settings.chat_completion_source) { |
| 5166 | case chat_completion_sources.OPENAI: | 5330 | case chat_completion_sources.OPENAI: |
| 5167 | return visionSupportedModels.some(model => oai_settings.openai_model.includes(model) && !oai_settings.openai_model.includes('gpt-4-turbo-preview') && !oai_settings.openai_model.includes('o3-mini')); | 5331 | return visionSupportedModels.some(model => |
| 5332 | oai_settings.openai_model.includes(model) | ||
| 5333 | && ['gpt-4-turbo-preview', 'o1-mini', 'o3-mini'].some(x => !oai_settings.openai_model.includes(x)), | ||
| 5334 | ); | ||
| 5168 | case chat_completion_sources.MAKERSUITE: | 5335 | case chat_completion_sources.MAKERSUITE: |
| 5169 | return visionSupportedModels.some(model => oai_settings.google_model.includes(model)); | 5336 | return visionSupportedModels.some(model => oai_settings.google_model.includes(model)); |
| 5337 | case chat_completion_sources.VERTEXAI: | ||
| 5338 | return visionSupportedModels.some(model => oai_settings.vertexai_model.includes(model)); | ||
| 5170 | case chat_completion_sources.CLAUDE: | 5339 | case chat_completion_sources.CLAUDE: |
| 5171 | return visionSupportedModels.some(model => oai_settings.claude_model.includes(model)); | 5340 | return visionSupportedModels.some(model => oai_settings.claude_model.includes(model)); |
| 5172 | case chat_completion_sources.OPENROUTER: | 5341 | case chat_completion_sources.OPENROUTER: |
| @@ -5181,6 +5350,8 @@ export function isImageInliningSupported() { | |||
| 5181 | return visionSupportedModels.some(model => oai_settings.cohere_model.includes(model)); | 5350 | return visionSupportedModels.some(model => oai_settings.cohere_model.includes(model)); |
| 5182 | case chat_completion_sources.XAI: | 5351 | case chat_completion_sources.XAI: |
| 5183 | return visionSupportedModels.some(model => oai_settings.xai_model.includes(model)); | 5352 | return visionSupportedModels.some(model => oai_settings.xai_model.includes(model)); |
| 5353 | case chat_completion_sources.POLLINATIONS: | ||
| 5354 | return (Array.isArray(model_list) && model_list.find(m => m.id === oai_settings.pollinations_model)?.vision); | ||
| 5184 | default: | 5355 | default: |
| 5185 | return false; | 5356 | return false; |
| 5186 | } | 5357 | } |
| @@ -5253,8 +5424,8 @@ $('#save_proxy').on('click', async function () { | |||
| 5253 | toastr.success(t`Proxy Saved`); | 5424 | toastr.success(t`Proxy Saved`); |
| 5254 | if ($('#openai_proxy_preset').val() !== presetName) { | 5425 | if ($('#openai_proxy_preset').val() !== presetName) { |
| 5255 | const option = document.createElement('option'); | 5426 | const option = document.createElement('option'); |
| 5256 | option.text = presetName; | 5427 | option.text = String(presetName); |
| 5257 | option.value = presetName; | 5428 | option.value = String(presetName); |
| 5258 | 5429 | ||
| 5259 | $('#openai_proxy_preset').append(option); | 5430 | $('#openai_proxy_preset').append(option); |
| 5260 | } | 5431 | } |
| @@ -5759,6 +5930,11 @@ export function initOpenAI() { | |||
| 5759 | saveSettingsDebounced(); | 5930 | saveSettingsDebounced(); |
| 5760 | }); | 5931 | }); |
| 5761 | 5932 | ||
| 5933 | $('#bind_preset_to_connection').on('input', function () { | ||
| 5934 | oai_settings.bind_preset_to_connection = !!$(this).prop('checked'); | ||
| 5935 | saveSettingsDebounced(); | ||
| 5936 | }); | ||
| 5937 | |||
| 5762 | $('#api_button_openai').on('click', onConnectButtonClick); | 5938 | $('#api_button_openai').on('click', onConnectButtonClick); |
| 5763 | $('#openai_reverse_proxy').on('input', onReverseProxyInput); | 5939 | $('#openai_reverse_proxy').on('input', onReverseProxyInput); |
| 5764 | $('#model_openai_select').on('change', onModelChange); | 5940 | $('#model_openai_select').on('change', onModelChange); |
| @@ -5766,6 +5942,7 @@ export function initOpenAI() { | |||
| 5766 | $('#model_windowai_select').on('change', onModelChange); | 5942 | $('#model_windowai_select').on('change', onModelChange); |
| 5767 | $('#model_scale_select').on('change', onModelChange); | 5943 | $('#model_scale_select').on('change', onModelChange); |
| 5768 | $('#model_google_select').on('change', onModelChange); | 5944 | $('#model_google_select').on('change', onModelChange); |
| 5945 | $('#model_vertexai_select').on('change', onModelChange); | ||
| 5769 | $('#model_openrouter_select').on('change', onModelChange); | 5946 | $('#model_openrouter_select').on('change', onModelChange); |
| 5770 | $('#openrouter_group_models').on('change', onOpenrouterModelSortChange); | 5947 | $('#openrouter_group_models').on('change', onOpenrouterModelSortChange); |
| 5771 | $('#openrouter_sort_models').on('change', onOpenrouterModelSortChange); | 5948 | $('#openrouter_sort_models').on('change', onOpenrouterModelSortChange); |
| @@ -5779,6 +5956,7 @@ export function initOpenAI() { | |||
| 5779 | $('#model_01ai_select').on('change', onModelChange); | 5956 | $('#model_01ai_select').on('change', onModelChange); |
| 5780 | $('#model_custom_select').on('change', onModelChange); | 5957 | $('#model_custom_select').on('change', onModelChange); |
| 5781 | $('#model_xai_select').on('change', onModelChange); | 5958 | $('#model_xai_select').on('change', onModelChange); |
| 5959 | $('#model_pollinations_select').on('change', onModelChange); | ||
| 5782 | $('#settings_preset_openai').on('change', onSettingsPresetChange); | 5960 | $('#settings_preset_openai').on('change', onSettingsPresetChange); |
| 5783 | $('#new_oai_preset').on('click', onNewPresetClick); | 5961 | $('#new_oai_preset').on('click', onNewPresetClick); |
| 5784 | $('#delete_oai_preset').on('click', onDeletePresetClick); | 5962 | $('#delete_oai_preset').on('click', onDeletePresetClick); |
| @@ -22,7 +22,7 @@ import { | |||
| 22 | } from '../script.js'; | 22 | } from '../script.js'; |
| 23 | import { persona_description_positions, power_user } from './power-user.js'; | 23 | import { persona_description_positions, power_user } from './power-user.js'; |
| 24 | import { getTokenCountAsync } from './tokenizers.js'; | 24 | import { getTokenCountAsync } from './tokenizers.js'; |
| 25 | import { PAGINATION_TEMPLATE, clearInfoBlock, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, getCharIndex, isFalseBoolean, isTrueBoolean, onlyUnique, parseJsonFile, setInfoBlock } from './utils.js'; | 25 | import { PAGINATION_TEMPLATE, clearInfoBlock, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, getCharIndex, isFalseBoolean, isTrueBoolean, onlyUnique, parseJsonFile, setInfoBlock, localizePagination, renderPaginationDropdown, paginationDropdownChangeHandler } from './utils.js'; |
| 26 | import { debounce_timeout } from './constants.js'; | 26 | import { debounce_timeout } from './constants.js'; |
| 27 | import { FILTER_TYPES, FilterHelper } from './filters.js'; | 27 | import { FILTER_TYPES, FilterHelper } from './filters.js'; |
| 28 | import { groups, selected_group } from './group-chats.js'; | 28 | import { groups, selected_group } from './group-chats.js'; |
| @@ -250,16 +250,18 @@ export async function getUserAvatars(doRender = true, openPageAt = '') { | |||
| 250 | const storageKey = 'Personas_PerPage'; | 250 | const storageKey = 'Personas_PerPage'; |
| 251 | const listId = '#user_avatar_block'; | 251 | const listId = '#user_avatar_block'; |
| 252 | const perPage = Number(accountStorage.getItem(storageKey)) || 5; | 252 | const perPage = Number(accountStorage.getItem(storageKey)) || 5; |
| 253 | const sizeChangerOptions = [5, 10, 25, 50, 100, 250, 500, 1000]; | ||
| 253 | 254 | ||
| 254 | $('#persona_pagination_container').pagination({ | 255 | $('#persona_pagination_container').pagination({ |
| 255 | dataSource: entities, | 256 | dataSource: entities, |
| 256 | pageSize: perPage, | 257 | pageSize: perPage, |
| 257 | sizeChangerOptions: [5, 10, 25, 50, 100, 250, 500, 1000], | 258 | sizeChangerOptions, |
| 258 | pageRange: 1, | 259 | pageRange: 1, |
| 259 | pageNumber: savePersonasPage || 1, | 260 | pageNumber: savePersonasPage || 1, |
| 260 | position: 'top', | 261 | position: 'top', |
| 261 | showPageNumbers: false, | 262 | showPageNumbers: false, |
| 262 | showSizeChanger: true, | 263 | showSizeChanger: true, |
| 264 | formatSizeChanger: renderPaginationDropdown(perPage, sizeChangerOptions), | ||
| 263 | prevText: '<', | 265 | prevText: '<', |
| 264 | nextText: '>', | 266 | nextText: '>', |
| 265 | formatNavigator: PAGINATION_TEMPLATE, | 267 | formatNavigator: PAGINATION_TEMPLATE, |
| @@ -270,9 +272,11 @@ export async function getUserAvatars(doRender = true, openPageAt = '') { | |||
| 270 | $(listId).append(getUserAvatarBlock(item)); | 272 | $(listId).append(getUserAvatarBlock(item)); |
| 271 | } | 273 | } |
| 272 | updatePersonaUIStates(); | 274 | updatePersonaUIStates(); |
| 275 | localizePagination($('#persona_pagination_container')); | ||
| 273 | }, | 276 | }, |
| 274 | afterSizeSelectorChange: function (e) { | 277 | afterSizeSelectorChange: function (e, size) { |
| 275 | accountStorage.setItem(storageKey, e.target.value); | 278 | accountStorage.setItem(storageKey, e.target.value); |
| 279 | paginationDropdownChangeHandler(e, size); | ||
| 276 | }, | 280 | }, |
| 277 | afterPaging: function (e) { | 281 | afterPaging: function (e) { |
| 278 | savePersonasPage = e; | 282 | savePersonasPage = e; |
| @@ -1966,7 +1970,7 @@ export async function initPersonas() { | |||
| 1966 | 1970 | ||
| 1967 | $('#char_connections_button').on('click', showCharConnections); | 1971 | $('#char_connections_button').on('click', showCharConnections); |
| 1968 | 1972 | ||
| 1969 | eventSource.on('charManagementDropdown', (target) => { | 1973 | eventSource.on(event_types.CHARACTER_MANAGEMENT_DROPDOWN, (target) => { |
| 1970 | if (target === 'convert_to_persona') { | 1974 | if (target === 'convert_to_persona') { |
| 1971 | convertCharacterToPersona(); | 1975 | convertCharacterToPersona(); |
| 1972 | } | 1976 | } |
| @@ -1,6 +1,6 @@ | |||
| 1 | import dialogPolyfill from '../lib/dialog-polyfill.esm.js'; | 1 | import dialogPolyfill from '../lib/dialog-polyfill.esm.js'; |
| 2 | import { shouldSendOnEnter } from './RossAscends-mods.js'; | 2 | import { shouldSendOnEnter } from './RossAscends-mods.js'; |
| 3 | import { power_user } from './power-user.js'; | 3 | import { power_user, toastPositionClasses } from './power-user.js'; |
| 4 | import { removeFromArray, runAfterAnimation, uuidv4 } from './utils.js'; | 4 | import { removeFromArray, runAfterAnimation, uuidv4 } from './utils.js'; |
| 5 | 5 | ||
| 6 | /** @readonly */ | 6 | /** @readonly */ |
| @@ -71,7 +71,8 @@ export const POPUP_RESULT = { | |||
| 71 | * @property {string} id - The id for the html element | 71 | * @property {string} id - The id for the html element |
| 72 | * @property {string} label - The label text for the input | 72 | * @property {string} label - The label text for the input |
| 73 | * @property {string?} [tooltip=null] - Optional tooltip icon displayed behind the label | 73 | * @property {string?} [tooltip=null] - Optional tooltip icon displayed behind the label |
| 74 | * @property {boolean?} [defaultState=false] - The default state when opening the popup (false if not set) | 74 | * @property {boolean|string|undefined} [defaultState=false] - The default state when opening the popup (false if not set) |
| 75 | * @property {string?} [type='checkbox'] - The type of the input (default is checkbox) | ||
| 75 | */ | 76 | */ |
| 76 | 77 | ||
| 77 | /** | 78 | /** |
| @@ -157,7 +158,7 @@ export class Popup { | |||
| 157 | 158 | ||
| 158 | /** @type {POPUP_RESULT|number} */ result; | 159 | /** @type {POPUP_RESULT|number} */ result; |
| 159 | /** @type {any} */ value; | 160 | /** @type {any} */ value; |
| 160 | /** @type {Map<string,boolean>?} */ inputResults; | 161 | /** @type {Map<string,string|boolean>?} */ inputResults; |
| 161 | /** @type {any} */ cropData; | 162 | /** @type {any} */ cropData; |
| 162 | 163 | ||
| 163 | /** @type {HTMLElement} */ lastFocus; | 164 | /** @type {HTMLElement} */ lastFocus; |
| @@ -260,13 +261,14 @@ export class Popup { | |||
| 260 | return; | 261 | return; |
| 261 | } | 262 | } |
| 262 | 263 | ||
| 264 | if (!input.type || input.type === 'checkbox') { | ||
| 263 | const label = document.createElement('label'); | 265 | const label = document.createElement('label'); |
| 264 | label.classList.add('checkbox_label', 'justifyCenter'); | 266 | label.classList.add('checkbox_label', 'justifyCenter'); |
| 265 | label.setAttribute('for', input.id); | 267 | label.setAttribute('for', input.id); |
| 266 | const inputElement = document.createElement('input'); | 268 | const inputElement = document.createElement('input'); |
| 267 | inputElement.type = 'checkbox'; | 269 | inputElement.type = 'checkbox'; |
| 268 | inputElement.id = input.id; | 270 | inputElement.id = input.id; |
| 269 | inputElement.checked = input.defaultState ?? false; | 271 | inputElement.checked = Boolean(input.defaultState ?? false); |
| 270 | label.appendChild(inputElement); | 272 | label.appendChild(inputElement); |
| 271 | const labelText = document.createElement('span'); | 273 | const labelText = document.createElement('span'); |
| 272 | labelText.innerText = input.label; | 274 | labelText.innerText = input.label; |
| @@ -282,6 +284,30 @@ export class Popup { | |||
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | this.inputControls.appendChild(label); | 286 | this.inputControls.appendChild(label); |
| 287 | } else if (input.type === 'text') { | ||
| 288 | const label = document.createElement('label'); | ||
| 289 | label.classList.add('text_label', 'justifyCenter'); | ||
| 290 | label.setAttribute('for', input.id); | ||
| 291 | |||
| 292 | const inputElement = document.createElement('input'); | ||
| 293 | inputElement.classList.add('text_pole'); | ||
| 294 | inputElement.type = 'text'; | ||
| 295 | inputElement.id = input.id; | ||
| 296 | inputElement.value = String(input.defaultState ?? ''); | ||
| 297 | inputElement.placeholder = input.tooltip ?? ''; | ||
| 298 | |||
| 299 | const labelText = document.createElement('span'); | ||
| 300 | labelText.innerText = input.label; | ||
| 301 | labelText.dataset.i18n = input.label; | ||
| 302 | |||
| 303 | label.appendChild(labelText); | ||
| 304 | label.appendChild(inputElement); | ||
| 305 | |||
| 306 | this.inputControls.appendChild(label); | ||
| 307 | } else { | ||
| 308 | console.warn('Unknown custom input type. Only checkbox and text are supported.', input); | ||
| 309 | return; | ||
| 310 | } | ||
| 285 | }); | 311 | }); |
| 286 | 312 | ||
| 287 | // Set the default button class | 313 | // Set the default button class |
| @@ -529,7 +555,8 @@ export class Popup { | |||
| 529 | this.inputResults = new Map(this.customInputs.map(input => { | 555 | this.inputResults = new Map(this.customInputs.map(input => { |
| 530 | /** @type {HTMLInputElement} */ | 556 | /** @type {HTMLInputElement} */ |
| 531 | const inputControl = this.dlg.querySelector(`#${input.id}`); | 557 | const inputControl = this.dlg.querySelector(`#${input.id}`); |
| 532 | return [inputControl.id, inputControl.checked]; | 558 | const value = input.type === 'text' ? inputControl.value : inputControl.checked; |
| 559 | return [inputControl.id, value]; | ||
| 533 | })); | 560 | })); |
| 534 | } | 561 | } |
| 535 | 562 | ||
| @@ -619,7 +646,7 @@ export class Popup { | |||
| 619 | /** @readonly @type {Popup[]} Remember all popups */ | 646 | /** @readonly @type {Popup[]} Remember all popups */ |
| 620 | popups: [], | 647 | popups: [], |
| 621 | 648 | ||
| 622 | /** @type {{value: any, result: POPUP_RESULT|number?, inputResults: Map<string, boolean>?}?} Last popup result */ | 649 | /** @type {{value: any, result: POPUP_RESULT|number?, inputResults: Map<string, string|boolean>?}?} Last popup result */ |
| 623 | lastResult: null, | 650 | lastResult: null, |
| 624 | 651 | ||
| 625 | /** @returns {boolean} Checks if any modal popup dialog is open */ | 652 | /** @returns {boolean} Checks if any modal popup dialog is open */ |
| @@ -691,7 +718,6 @@ export function getTopmostModalLayer() { | |||
| 691 | */ | 718 | */ |
| 692 | export function fixToastrForDialogs() { | 719 | export function fixToastrForDialogs() { |
| 693 | // Hacky way of getting toastr to actually display on top of the popup... | 720 | // Hacky way of getting toastr to actually display on top of the popup... |
| 694 | |||
| 695 | const dlg = Array.from(document.querySelectorAll('dialog[open]:not([closing])')).pop(); | 721 | const dlg = Array.from(document.querySelectorAll('dialog[open]:not([closing])')).pop(); |
| 696 | 722 | ||
| 697 | let toastContainer = document.getElementById('toast-container'); | 723 | let toastContainer = document.getElementById('toast-container'); |
| @@ -718,7 +744,8 @@ export function fixToastrForDialogs() { | |||
| 718 | toastContainer.remove(); | 744 | toastContainer.remove(); |
| 719 | } else { | 745 | } else { |
| 720 | document.body.appendChild(toastContainer); | 746 | document.body.appendChild(toastContainer); |
| 721 | toastContainer.classList.add('toast-top-center'); | 747 | toastContainer.classList.remove(...toastPositionClasses); |
| 748 | toastContainer.classList.add(toastr.options.positionClass); | ||
| 722 | } | 749 | } |
| 723 | } | 750 | } |
| 724 | } | 751 | } |
| @@ -25,6 +25,7 @@ import { | |||
| 25 | setActiveCharacter, | 25 | setActiveCharacter, |
| 26 | entitiesFilter, | 26 | entitiesFilter, |
| 27 | doNewChat, | 27 | doNewChat, |
| 28 | messageFormatting, | ||
| 28 | } from '../script.js'; | 29 | } from '../script.js'; |
| 29 | import { isMobile, initMovingUI, favsToHotswap } from './RossAscends-mods.js'; | 30 | import { isMobile, initMovingUI, favsToHotswap } from './RossAscends-mods.js'; |
| 30 | import { | 31 | import { |
| @@ -51,7 +52,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from ' | |||
| 51 | import { AUTOCOMPLETE_SELECT_KEY, AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js'; | 52 | import { AUTOCOMPLETE_SELECT_KEY, AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js'; |
| 52 | import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js'; | 53 | import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js'; |
| 53 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; | 54 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 54 | import { POPUP_TYPE, callGenericPopup } from './popup.js'; | 55 | import { POPUP_TYPE, callGenericPopup, fixToastrForDialogs } from './popup.js'; |
| 55 | import { loadSystemPrompts } from './sysprompt.js'; | 56 | import { loadSystemPrompts } from './sysprompt.js'; |
| 56 | import { fuzzySearchCategories } from './filters.js'; | 57 | import { fuzzySearchCategories } from './filters.js'; |
| 57 | import { accountStorage } from './util/AccountStorage.js'; | 58 | import { accountStorage } from './util/AccountStorage.js'; |
| @@ -69,6 +70,15 @@ export { | |||
| 69 | applyPowerUserSettings, | 70 | applyPowerUserSettings, |
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 73 | export const toastPositionClasses = [ | ||
| 74 | 'toast-top-left', | ||
| 75 | 'toast-top-center', | ||
| 76 | 'toast-top-right', | ||
| 77 | 'toast-bottom-left', | ||
| 78 | 'toast-bottom-center', | ||
| 79 | 'toast-bottom-right', | ||
| 80 | ]; | ||
| 81 | |||
| 72 | export const MAX_CONTEXT_DEFAULT = 8192; | 82 | export const MAX_CONTEXT_DEFAULT = 8192; |
| 73 | export const MAX_RESPONSE_DEFAULT = 2048; | 83 | export const MAX_RESPONSE_DEFAULT = 2048; |
| 74 | const MAX_CONTEXT_UNLOCKED = 512 * 1024; | 84 | const MAX_CONTEXT_UNLOCKED = 512 * 1024; |
| @@ -80,11 +90,13 @@ const maxContextStep = 64; | |||
| 80 | const defaultStoryString = '{{#if system}}{{system}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}\'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}'; | 90 | const defaultStoryString = '{{#if system}}{{system}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}\'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}'; |
| 81 | const defaultExampleSeparator = '***'; | 91 | const defaultExampleSeparator = '***'; |
| 82 | const defaultChatStart = '***'; | 92 | const defaultChatStart = '***'; |
| 93 | const defaultToastPosition = 'toast-top-center'; | ||
| 83 | 94 | ||
| 84 | const avatar_styles = { | 95 | const avatar_styles = { |
| 85 | ROUND: 0, | 96 | ROUND: 0, |
| 86 | RECTANGULAR: 1, | 97 | RECTANGULAR: 1, |
| 87 | SQUARE: 2, | 98 | SQUARE: 2, |
| 99 | ROUNDED: 3, | ||
| 88 | }; | 100 | }; |
| 89 | 101 | ||
| 90 | export const chat_styles = { | 102 | export const chat_styles = { |
| @@ -136,6 +148,7 @@ let power_user = { | |||
| 136 | fast_ui_mode: true, | 148 | fast_ui_mode: true, |
| 137 | avatar_style: avatar_styles.ROUND, | 149 | avatar_style: avatar_styles.ROUND, |
| 138 | chat_display: chat_styles.DEFAULT, | 150 | chat_display: chat_styles.DEFAULT, |
| 151 | toastr_position: defaultToastPosition, | ||
| 139 | chat_width: 50, | 152 | chat_width: 50, |
| 140 | never_resize_avatars: false, | 153 | never_resize_avatars: false, |
| 141 | show_card_avatar_urls: false, | 154 | show_card_avatar_urls: false, |
| @@ -244,7 +257,6 @@ let power_user = { | |||
| 244 | chat_start: defaultChatStart, | 257 | chat_start: defaultChatStart, |
| 245 | example_separator: defaultExampleSeparator, | 258 | example_separator: defaultExampleSeparator, |
| 246 | use_stop_strings: true, | 259 | use_stop_strings: true, |
| 247 | allow_jailbreak: false, | ||
| 248 | names_as_stop_strings: true, | 260 | names_as_stop_strings: true, |
| 249 | }, | 261 | }, |
| 250 | 262 | ||
| @@ -255,6 +267,7 @@ let power_user = { | |||
| 255 | enabled: true, | 267 | enabled: true, |
| 256 | name: 'Neutral - Chat', | 268 | name: 'Neutral - Chat', |
| 257 | content: 'Write {{char}}\'s next reply in a fictional chat between {{char}} and {{user}}.', | 269 | content: 'Write {{char}}\'s next reply in a fictional chat between {{char}} and {{user}}.', |
| 270 | post_history: '', | ||
| 258 | }, | 271 | }, |
| 259 | 272 | ||
| 260 | reasoning: { | 273 | reasoning: { |
| @@ -318,6 +331,8 @@ let power_user = { | |||
| 318 | forbid_external_media: true, | 331 | forbid_external_media: true, |
| 319 | external_media_allowed_overrides: [], | 332 | external_media_allowed_overrides: [], |
| 320 | external_media_forbidden_overrides: [], | 333 | external_media_forbidden_overrides: [], |
| 334 | pin_styles: true, | ||
| 335 | click_to_edit: false, | ||
| 321 | }; | 336 | }; |
| 322 | 337 | ||
| 323 | let themes = []; | 338 | let themes = []; |
| @@ -334,7 +349,6 @@ const contextControls = [ | |||
| 334 | { id: 'context_example_separator', property: 'example_separator', isCheckbox: false, isGlobalSetting: false }, | 349 | { id: 'context_example_separator', property: 'example_separator', isCheckbox: false, isGlobalSetting: false }, |
| 335 | { id: 'context_chat_start', property: 'chat_start', isCheckbox: false, isGlobalSetting: false }, | 350 | { id: 'context_chat_start', property: 'chat_start', isCheckbox: false, isGlobalSetting: false }, |
| 336 | { id: 'context_use_stop_strings', property: 'use_stop_strings', isCheckbox: true, isGlobalSetting: false, defaultValue: false }, | 351 | { id: 'context_use_stop_strings', property: 'use_stop_strings', isCheckbox: true, isGlobalSetting: false, defaultValue: false }, |
| 337 | { id: 'context_allow_jailbreak', property: 'allow_jailbreak', isCheckbox: true, isGlobalSetting: false, defaultValue: false }, | ||
| 338 | { id: 'context_names_as_stop_strings', property: 'names_as_stop_strings', isCheckbox: true, isGlobalSetting: false, defaultValue: true }, | 352 | { id: 'context_names_as_stop_strings', property: 'names_as_stop_strings', isCheckbox: true, isGlobalSetting: false, defaultValue: true }, |
| 339 | 353 | ||
| 340 | // Existing power user settings | 354 | // Existing power user settings |
| @@ -1008,6 +1022,7 @@ function applyNoShadows() { | |||
| 1008 | function applyAvatarStyle() { | 1022 | function applyAvatarStyle() { |
| 1009 | $('body').toggleClass('big-avatars', power_user.avatar_style === avatar_styles.RECTANGULAR); | 1023 | $('body').toggleClass('big-avatars', power_user.avatar_style === avatar_styles.RECTANGULAR); |
| 1010 | $('body').toggleClass('square-avatars', power_user.avatar_style === avatar_styles.SQUARE); | 1024 | $('body').toggleClass('square-avatars', power_user.avatar_style === avatar_styles.SQUARE); |
| 1025 | $('body').toggleClass('rounded-avatars', power_user.avatar_style === avatar_styles.ROUNDED); | ||
| 1011 | $('#avatar_style').val(power_user.avatar_style).prop('selected', true); | 1026 | $('#avatar_style').val(power_user.avatar_style).prop('selected', true); |
| 1012 | } | 1027 | } |
| 1013 | 1028 | ||
| @@ -1042,6 +1057,17 @@ function applyChatDisplay() { | |||
| 1042 | } | 1057 | } |
| 1043 | } | 1058 | } |
| 1044 | 1059 | ||
| 1060 | function applyToastrPosition() { | ||
| 1061 | if (!toastPositionClasses.includes(power_user.toastr_position)) { | ||
| 1062 | power_user.toastr_position = defaultToastPosition; | ||
| 1063 | console.warn(`applyToastrPosition: invalid toastr position, defaulting to ${defaultToastPosition}`); | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | toastr.options.positionClass = power_user.toastr_position; | ||
| 1067 | fixToastrForDialogs(); | ||
| 1068 | $('#toastr_position').val(power_user.toastr_position).prop('selected', true); | ||
| 1069 | } | ||
| 1070 | |||
| 1045 | function applyChatWidth(type) { | 1071 | function applyChatWidth(type) { |
| 1046 | if (type === 'forced') { | 1072 | if (type === 'forced') { |
| 1047 | let r = document.documentElement; | 1073 | let r = document.documentElement; |
| @@ -1084,7 +1110,9 @@ function applyThemeColor(type) { | |||
| 1084 | document.documentElement.style.setProperty('--SmartThemeFastUIBGColor', power_user.fastui_bg_color); | 1110 | document.documentElement.style.setProperty('--SmartThemeFastUIBGColor', power_user.fastui_bg_color); |
| 1085 | } */ | 1111 | } */ |
| 1086 | if (type === 'blurTint') { | 1112 | if (type === 'blurTint') { |
| 1113 | let metaThemeColor = document.querySelector('meta[name=theme-color]'); | ||
| 1087 | document.documentElement.style.setProperty('--SmartThemeBlurTintColor', power_user.blur_tint_color); | 1114 | document.documentElement.style.setProperty('--SmartThemeBlurTintColor', power_user.blur_tint_color); |
| 1115 | metaThemeColor.setAttribute('content', power_user.blur_tint_color); | ||
| 1088 | } | 1116 | } |
| 1089 | if (type === 'chatTint') { | 1117 | if (type === 'chatTint') { |
| 1090 | document.documentElement.style.setProperty('--SmartThemeChatTintColor', power_user.chat_tint_color); | 1118 | document.documentElement.style.setProperty('--SmartThemeChatTintColor', power_user.chat_tint_color); |
| @@ -1205,6 +1233,12 @@ function applyTheme(name) { | |||
| 1205 | }, | 1233 | }, |
| 1206 | }, | 1234 | }, |
| 1207 | { | 1235 | { |
| 1236 | key: 'toastr_position', | ||
| 1237 | action: () => { | ||
| 1238 | applyToastrPosition(); | ||
| 1239 | }, | ||
| 1240 | }, | ||
| 1241 | { | ||
| 1208 | key: 'avatar_style', | 1242 | key: 'avatar_style', |
| 1209 | action: () => { | 1243 | action: () => { |
| 1210 | applyAvatarStyle(); | 1244 | applyAvatarStyle(); |
| @@ -1321,6 +1355,12 @@ function applyTheme(name) { | |||
| 1321 | switchSwipeNumAllMessages(); | 1355 | switchSwipeNumAllMessages(); |
| 1322 | }, | 1356 | }, |
| 1323 | }, | 1357 | }, |
| 1358 | { | ||
| 1359 | key: 'click_to_edit', | ||
| 1360 | action: () => { | ||
| 1361 | $('#click_to_edit').prop('checked', power_user.click_to_edit); | ||
| 1362 | }, | ||
| 1363 | }, | ||
| 1324 | ]; | 1364 | ]; |
| 1325 | 1365 | ||
| 1326 | for (const { key, selector, type, action } of themeProperties) { | 1366 | for (const { key, selector, type, action } of themeProperties) { |
| @@ -1391,6 +1431,50 @@ function applyPowerUserSettings() { | |||
| 1391 | switchSwipeNumAllMessages(); | 1431 | switchSwipeNumAllMessages(); |
| 1392 | } | 1432 | } |
| 1393 | 1433 | ||
| 1434 | export function applyStylePins() { | ||
| 1435 | try { | ||
| 1436 | const existingPins = document.querySelector('#chat > .style-pins'); | ||
| 1437 | if (existingPins) { | ||
| 1438 | existingPins.remove(); | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | if (!power_user.pin_styles) { | ||
| 1442 | return; | ||
| 1443 | } | ||
| 1444 | |||
| 1445 | const firstDisplayed = getFirstDisplayedMessageId(); | ||
| 1446 | if (firstDisplayed === 0 || !isFinite(firstDisplayed)) { | ||
| 1447 | return; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | const chatElement = document.getElementById('chat'); | ||
| 1451 | if (!chatElement) { | ||
| 1452 | return; | ||
| 1453 | } | ||
| 1454 | |||
| 1455 | const firstMessage = chat[0]; | ||
| 1456 | if (!firstMessage) { | ||
| 1457 | return; | ||
| 1458 | } | ||
| 1459 | |||
| 1460 | const formattedMessage = messageFormatting(firstMessage.mes, firstMessage.name, firstMessage.is_system, firstMessage.is_user, 0, {}, false); | ||
| 1461 | const htmlElement = document.createElement('div'); | ||
| 1462 | htmlElement.innerHTML = formattedMessage; | ||
| 1463 | |||
| 1464 | const styleTags = htmlElement.querySelectorAll('style'); | ||
| 1465 | if (styleTags.length === 0) { | ||
| 1466 | return; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | const pinsElement = document.createElement('div'); | ||
| 1470 | pinsElement.classList.add('style-pins'); | ||
| 1471 | pinsElement.append(...Array.from(styleTags)); | ||
| 1472 | chatElement.prepend(pinsElement); | ||
| 1473 | } catch (error) { | ||
| 1474 | console.error('Error applying style pins:', error); | ||
| 1475 | } | ||
| 1476 | } | ||
| 1477 | |||
| 1394 | function getExampleMessagesBehavior() { | 1478 | function getExampleMessagesBehavior() { |
| 1395 | if (power_user.strip_examples) { | 1479 | if (power_user.strip_examples) { |
| 1396 | return 'strip'; | 1480 | return 'strip'; |
| @@ -1403,10 +1487,15 @@ function getExampleMessagesBehavior() { | |||
| 1403 | return 'normal'; | 1487 | return 'normal'; |
| 1404 | } | 1488 | } |
| 1405 | 1489 | ||
| 1490 | //MARK: loadPowerUser | ||
| 1406 | async function loadPowerUserSettings(settings, data) { | 1491 | async function loadPowerUserSettings(settings, data) { |
| 1407 | const defaultStscript = JSON.parse(JSON.stringify(power_user.stscript)); | 1492 | const defaultStscript = JSON.parse(JSON.stringify(power_user.stscript)); |
| 1408 | // Load from settings.json | 1493 | // Load from settings.json |
| 1409 | if (settings.power_user !== undefined) { | 1494 | if (settings.power_user !== undefined) { |
| 1495 | // Migrate old preference to a new setting | ||
| 1496 | if (settings.power_user.click_to_edit === undefined && settings.power_user.chat_display === chat_styles.DOCUMENT) { | ||
| 1497 | settings.power_user.click_to_edit = true; | ||
| 1498 | } | ||
| 1410 | Object.assign(power_user, settings.power_user); | 1499 | Object.assign(power_user, settings.power_user); |
| 1411 | } | 1500 | } |
| 1412 | 1501 | ||
| @@ -1547,6 +1636,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1547 | $('#enableLabMode').prop('checked', power_user.enableLabMode).trigger('input', { fromInit: true }); | 1636 | $('#enableLabMode').prop('checked', power_user.enableLabMode).trigger('input', { fromInit: true }); |
| 1548 | $(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop('checked', true); | 1637 | $(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop('checked', true); |
| 1549 | $(`#chat_display option[value=${power_user.chat_display}]`).attr('selected', true).trigger('change'); | 1638 | $(`#chat_display option[value=${power_user.chat_display}]`).attr('selected', true).trigger('change'); |
| 1639 | $(`#toastr_position option[value=${power_user.toastr_position}]`).attr('selected', true).trigger('change'); | ||
| 1550 | $('#chat_width_slider').val(power_user.chat_width); | 1640 | $('#chat_width_slider').val(power_user.chat_width); |
| 1551 | $('#token_padding').val(power_user.token_padding); | 1641 | $('#token_padding').val(power_user.token_padding); |
| 1552 | $('#aux_field').val(power_user.aux_field); | 1642 | $('#aux_field').val(power_user.aux_field); |
| @@ -1601,6 +1691,8 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1601 | $('#auto-connect-checkbox').prop('checked', power_user.auto_connect); | 1691 | $('#auto-connect-checkbox').prop('checked', power_user.auto_connect); |
| 1602 | $('#auto-load-chat-checkbox').prop('checked', power_user.auto_load_chat); | 1692 | $('#auto-load-chat-checkbox').prop('checked', power_user.auto_load_chat); |
| 1603 | $('#forbid_external_media').prop('checked', power_user.forbid_external_media); | 1693 | $('#forbid_external_media').prop('checked', power_user.forbid_external_media); |
| 1694 | $('#pin_styles').prop('checked', power_user.pin_styles); | ||
| 1695 | $('#click_to_edit').prop('checked', power_user.click_to_edit); | ||
| 1604 | 1696 | ||
| 1605 | for (const theme of themes) { | 1697 | for (const theme of themes) { |
| 1606 | const option = document.createElement('option'); | 1698 | const option = document.createElement('option'); |
| @@ -1633,6 +1725,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1633 | loadMovingUIState(); | 1725 | loadMovingUIState(); |
| 1634 | loadCharListState(); | 1726 | loadCharListState(); |
| 1635 | toggleMDHotkeyIconDisplay(); | 1727 | toggleMDHotkeyIconDisplay(); |
| 1728 | applyToastrPosition(); | ||
| 1636 | } | 1729 | } |
| 1637 | 1730 | ||
| 1638 | function toggleMDHotkeyIconDisplay() { | 1731 | function toggleMDHotkeyIconDisplay() { |
| @@ -2314,6 +2407,7 @@ function getThemeObject(name) { | |||
| 2314 | waifuMode: power_user.waifuMode, | 2407 | waifuMode: power_user.waifuMode, |
| 2315 | avatar_style: power_user.avatar_style, | 2408 | avatar_style: power_user.avatar_style, |
| 2316 | chat_display: power_user.chat_display, | 2409 | chat_display: power_user.chat_display, |
| 2410 | toastr_position: power_user.toastr_position, | ||
| 2317 | noShadows: power_user.noShadows, | 2411 | noShadows: power_user.noShadows, |
| 2318 | chat_width: power_user.chat_width, | 2412 | chat_width: power_user.chat_width, |
| 2319 | timer_enabled: power_user.timer_enabled, | 2413 | timer_enabled: power_user.timer_enabled, |
| @@ -2333,6 +2427,7 @@ function getThemeObject(name) { | |||
| 2333 | reduced_motion: power_user.reduced_motion, | 2427 | reduced_motion: power_user.reduced_motion, |
| 2334 | compact_input_area: power_user.compact_input_area, | 2428 | compact_input_area: power_user.compact_input_area, |
| 2335 | show_swipe_num_all_messages: power_user.show_swipe_num_all_messages, | 2429 | show_swipe_num_all_messages: power_user.show_swipe_num_all_messages, |
| 2430 | click_to_edit: power_user.click_to_edit, | ||
| 2336 | }; | 2431 | }; |
| 2337 | } | 2432 | } |
| 2338 | 2433 | ||
| @@ -3264,6 +3359,13 @@ $(document).ready(() => { | |||
| 3264 | saveSettingsDebounced(); | 3359 | saveSettingsDebounced(); |
| 3265 | }); | 3360 | }); |
| 3266 | 3361 | ||
| 3362 | $('#toastr_position').on('change', function () { | ||
| 3363 | const value = $(this).find(':selected').val(); | ||
| 3364 | power_user.toastr_position = String(value); | ||
| 3365 | applyToastrPosition(); | ||
| 3366 | saveSettingsDebounced(); | ||
| 3367 | }); | ||
| 3368 | |||
| 3267 | $('#chat_width_slider').on('input', function (e, data) { | 3369 | $('#chat_width_slider').on('input', function (e, data) { |
| 3268 | const applyMode = data?.forced ? 'forced' : 'normal'; | 3370 | const applyMode = data?.forced ? 'forced' : 'normal'; |
| 3269 | power_user.chat_width = Number(e.target.value); | 3371 | power_user.chat_width = Number(e.target.value); |
| @@ -3877,6 +3979,17 @@ $(document).ready(() => { | |||
| 3877 | reloadCurrentChat(); | 3979 | reloadCurrentChat(); |
| 3878 | }); | 3980 | }); |
| 3879 | 3981 | ||
| 3982 | $('#pin_styles').on('input', function () { | ||
| 3983 | power_user.pin_styles = !!$(this).prop('checked'); | ||
| 3984 | saveSettingsDebounced(); | ||
| 3985 | applyStylePins(); | ||
| 3986 | }); | ||
| 3987 | |||
| 3988 | $('#click_to_edit').on('input', function () { | ||
| 3989 | power_user.click_to_edit = !!$(this).prop('checked'); | ||
| 3990 | saveSettingsDebounced(); | ||
| 3991 | }); | ||
| 3992 | |||
| 3880 | $('#ui_preset_import_button').on('click', function () { | 3993 | $('#ui_preset_import_button').on('click', function () { |
| 3881 | $('#ui_preset_import_file').trigger('click'); | 3994 | $('#ui_preset_import_file').trigger('click'); |
| 3882 | }); | 3995 | }); |
| @@ -36,7 +36,7 @@ import { | |||
| 36 | textgenerationwebui_presets, | 36 | textgenerationwebui_presets, |
| 37 | textgenerationwebui_settings as textgen_settings, | 37 | textgenerationwebui_settings as textgen_settings, |
| 38 | } from './textgen-settings.js'; | 38 | } from './textgen-settings.js'; |
| 39 | import { download, equalsIgnoreCaseAndAccents, parseJsonFile, waitUntilCondition } from './utils.js'; | 39 | import { download, equalsIgnoreCaseAndAccents, getSanitizedFilename, parseJsonFile, waitUntilCondition } from './utils.js'; |
| 40 | import { t } from './i18n.js'; | 40 | import { t } from './i18n.js'; |
| 41 | import { reasoning_templates } from './reasoning.js'; | 41 | import { reasoning_templates } from './reasoning.js'; |
| 42 | 42 | ||
| @@ -696,13 +696,14 @@ class PresetManager { | |||
| 696 | return; | 696 | return; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | $(this.select).find(`option[value="${value}"]`).remove(); | ||
| 700 | |||
| 701 | if (this.isKeyedApi()) { | 699 | if (this.isKeyedApi()) { |
| 700 | $(this.select).find(`option[value="${value}"]`).remove(); | ||
| 702 | const index = preset_names.indexOf(nameToDelete); | 701 | const index = preset_names.indexOf(nameToDelete); |
| 703 | preset_names.splice(index, 1); | 702 | preset_names.splice(index, 1); |
| 704 | presets.splice(index, 1); | 703 | presets.splice(index, 1); |
| 705 | } else { | 704 | } else { |
| 705 | const index = preset_names[nameToDelete]; | ||
| 706 | $(this.select).find(`option[value="${index}"]`).remove(); | ||
| 706 | delete preset_names[nameToDelete]; | 707 | delete preset_names[nameToDelete]; |
| 707 | } | 708 | } |
| 708 | 709 | ||
| @@ -890,7 +891,7 @@ export async function initPresetManager() { | |||
| 890 | 891 | ||
| 891 | const popupHeader = !presetManager.isAdvancedFormatting() ? t`Rename preset` : t`Rename template`; | 892 | const popupHeader = !presetManager.isAdvancedFormatting() ? t`Rename preset` : t`Rename template`; |
| 892 | const oldName = presetManager.getSelectedPresetName(); | 893 | const oldName = presetManager.getSelectedPresetName(); |
| 893 | const newName = await Popup.show.input(popupHeader, t`Enter a new name:`, oldName); | 894 | const newName = await getSanitizedFilename(await Popup.show.input(popupHeader, t`Enter a new name:`, oldName) || ''); |
| 894 | if (!newName || oldName === newName) { | 895 | if (!newName || oldName === newName) { |
| 895 | console.debug(!presetManager.isAdvancedFormatting() ? 'Preset rename cancelled' : 'Template rename cancelled'); | 896 | console.debug(!presetManager.isAdvancedFormatting() ? 'Preset rename cancelled' : 'Template rename cancelled'); |
| 896 | return; | 897 | return; |
| @@ -114,6 +114,7 @@ export function extractReasoningFromData(data, { | |||
| 114 | case chat_completion_sources.OPENROUTER: | 114 | case chat_completion_sources.OPENROUTER: |
| 115 | return data?.choices?.[0]?.message?.reasoning ?? ''; | 115 | return data?.choices?.[0]?.message?.reasoning ?? ''; |
| 116 | case chat_completion_sources.MAKERSUITE: | 116 | case chat_completion_sources.MAKERSUITE: |
| 117 | case chat_completion_sources.VERTEXAI: | ||
| 117 | return data?.responseContent?.parts?.filter(part => part.thought)?.map(part => part.text)?.join('\n\n') ?? ''; | 118 | return data?.responseContent?.parts?.filter(part => part.thought)?.map(part => part.text)?.join('\n\n') ?? ''; |
| 118 | case chat_completion_sources.CLAUDE: | 119 | case chat_completion_sources.CLAUDE: |
| 119 | return data?.content?.find(part => part.type === 'thinking')?.thinking ?? ''; | 120 | return data?.content?.find(part => part.type === 'thinking')?.thinking ?? ''; |
| @@ -90,6 +90,11 @@ function setSamplerListListeners() { | |||
| 90 | targetDisplayType = 'block'; | 90 | targetDisplayType = 'block'; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | if (samplerName === 'xtc_probability') { | ||
| 94 | relatedDOMElement = $('#xtc_block'); | ||
| 95 | targetDisplayType = 'block'; | ||
| 96 | } | ||
| 97 | |||
| 93 | if (samplerName === 'dynatemp') { | 98 | if (samplerName === 'dynatemp') { |
| 94 | relatedDOMElement = $('#dynatemp_block_ooba'); | 99 | relatedDOMElement = $('#dynatemp_block_ooba'); |
| 95 | targetDisplayType = 'block'; | 100 | targetDisplayType = 'block'; |
| @@ -248,6 +253,10 @@ async function listSamplers(main_api, arrayOnly = false) { | |||
| 248 | targetDOMelement = $('#dryBlock'); | 253 | targetDOMelement = $('#dryBlock'); |
| 249 | displayname = 'DRY Rep Pen Block'; | 254 | displayname = 'DRY Rep Pen Block'; |
| 250 | } | 255 | } |
| 256 | if (sampler === 'xtc_probability') { | ||
| 257 | targetDOMelement = $('#xtc_block'); | ||
| 258 | displayname = 'XTC Block'; | ||
| 259 | } | ||
| 251 | 260 | ||
| 252 | if (sampler === 'dynatemp') { | 261 | if (sampler === 'dynatemp') { |
| 253 | targetDOMelement = $('#dynatemp_block_ooba'); | 262 | targetDOMelement = $('#dynatemp_block_ooba'); |
| @@ -374,6 +383,11 @@ export async function validateDisabledSamplers(redraw = false) { | |||
| 374 | targetDisplayType = 'block'; | 383 | targetDisplayType = 'block'; |
| 375 | } | 384 | } |
| 376 | 385 | ||
| 386 | if (sampler === 'xtc_probability') { | ||
| 387 | relatedDOMElement = $('#xtc_block'); | ||
| 388 | targetDisplayType = 'block'; | ||
| 389 | } | ||
| 390 | |||
| 377 | if (sampler === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block? | 391 | if (sampler === 'penalty_alpha') { //contrastive search only has one sampler, does it need its own block? |
| 378 | relatedDOMElement = $('#contrastiveSearchBlock'); | 392 | relatedDOMElement = $('#contrastiveSearchBlock'); |
| 379 | } | 393 | } |
| @@ -16,6 +16,7 @@ export const SECRET_KEYS = { | |||
| 16 | AI21: 'api_key_ai21', | 16 | AI21: 'api_key_ai21', |
| 17 | SCALE_COOKIE: 'scale_cookie', | 17 | SCALE_COOKIE: 'scale_cookie', |
| 18 | MAKERSUITE: 'api_key_makersuite', | 18 | MAKERSUITE: 'api_key_makersuite', |
| 19 | VERTEXAI: 'api_key_vertexai', | ||
| 19 | SERPAPI: 'api_key_serpapi', | 20 | SERPAPI: 'api_key_serpapi', |
| 20 | MISTRALAI: 'api_key_mistralai', | 21 | MISTRALAI: 'api_key_mistralai', |
| 21 | TOGETHERAI: 'api_key_togetherai', | 22 | TOGETHERAI: 'api_key_togetherai', |
| @@ -56,6 +57,7 @@ const INPUT_MAP = { | |||
| 56 | [SECRET_KEYS.AI21]: '#api_key_ai21', | 57 | [SECRET_KEYS.AI21]: '#api_key_ai21', |
| 57 | [SECRET_KEYS.SCALE_COOKIE]: '#scale_cookie', | 58 | [SECRET_KEYS.SCALE_COOKIE]: '#scale_cookie', |
| 58 | [SECRET_KEYS.MAKERSUITE]: '#api_key_makersuite', | 59 | [SECRET_KEYS.MAKERSUITE]: '#api_key_makersuite', |
| 60 | [SECRET_KEYS.VERTEXAI]: '#api_key_vertexai', | ||
| 59 | [SECRET_KEYS.VLLM]: '#api_key_vllm', | 61 | [SECRET_KEYS.VLLM]: '#api_key_vllm', |
| 60 | [SECRET_KEYS.APHRODITE]: '#api_key_aphrodite', | 62 | [SECRET_KEYS.APHRODITE]: '#api_key_aphrodite', |
| 61 | [SECRET_KEYS.TABBY]: '#api_key_tabby', | 63 | [SECRET_KEYS.TABBY]: '#api_key_tabby', |
| @@ -1,40 +1,39 @@ | |||
| 1 | import { power_user } from './power-user.js'; | 1 | import { power_user } from './power-user.js'; |
| 2 | import { substituteParams } from '../script.js'; | ||
| 2 | 3 | ||
| 3 | // Showdown extension to make chat separators (dinkuses) ignore markdown formatting | 4 | /** |
| 5 | * Showdown extension to make chat separators (dinkuses) ignore markdown formatting | ||
| 6 | * @returns {import('showdown').ShowdownExtension[]} An array of Showdown extensions | ||
| 7 | */ | ||
| 4 | export const markdownExclusionExt = () => { | 8 | export const markdownExclusionExt = () => { |
| 5 | if (!power_user) { | 9 | if (!power_user) { |
| 6 | console.log('Showdown-dinkus extension: power_user wasn\'t found! Returning.'); | 10 | console.log('Showdown-dinkus extension: power_user wasn\'t found! Returning.'); |
| 7 | return []; | 11 | return []; |
| 8 | } | 12 | } |
| 9 | 13 | ||
| 10 | let combinedExcludeString = ''; | 14 | // The extension will only be applied if the user has non-empty "Non-markdown strings" |
| 11 | if (power_user.context.chat_start) { | 15 | // Changing the string in the UI reloads the processor, so we don't need to worry about it |
| 12 | combinedExcludeString += `${power_user.context.chat_start},`; | 16 | if (!power_user.markdown_escape_strings) { |
| 13 | } | 17 | return []; |
| 14 | |||
| 15 | if (power_user.context.example_separator) { | ||
| 16 | combinedExcludeString += `${power_user.context.example_separator},`; | ||
| 17 | } | ||
| 18 | |||
| 19 | if (power_user.markdown_escape_strings) { | ||
| 20 | combinedExcludeString += power_user.markdown_escape_strings; | ||
| 21 | } | 18 | } |
| 22 | 19 | ||
| 23 | const escapedExclusions = combinedExcludeString | 20 | // Escape the strings to be excluded from markdown parsing |
| 21 | // Function is evaluated every time, so we don't care about stale macros in the strings | ||
| 22 | return [{ | ||
| 23 | type: 'lang', | ||
| 24 | filter: (text) => { | ||
| 25 | const escapedExclusions = substituteParams(power_user.markdown_escape_strings) | ||
| 24 | .split(',') | 26 | .split(',') |
| 25 | .filter((element) => element.length > 0) | 27 | .filter((element) => element.length > 0) |
| 26 | .map((element) => `(${element.split('').map((char) => `\\${char}`).join('')})`); | 28 | .map((element) => `(${element.split('').map((char) => `\\${char}`).join('')})`); |
| 27 | 29 | ||
| 28 | |||
| 29 | // No exclusions? No extension! | 30 | // No exclusions? No extension! |
| 30 | if (!combinedExcludeString || combinedExcludeString.length === 0 || escapedExclusions.length === 0) { | 31 | if (escapedExclusions.length === 0) { |
| 31 | return []; | 32 | return text; |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | const replaceRegex = new RegExp(`^(${escapedExclusions.join('|')})\n`, 'gm'); | 35 | const replaceRegex = new RegExp(`^(${escapedExclusions.join('|')})\n`, 'gm'); |
| 35 | return [{ | 36 | return text.replace(replaceRegex, ((match) => match.replace(replaceRegex, `\u0000${match} \n`))); |
| 36 | type: 'lang', | 37 | }, |
| 37 | regex: replaceRegex, | ||
| 38 | replace: ((match) => match.replace(replaceRegex, `\u0000${match} \n`)), | ||
| 39 | }]; | 38 | }]; |
| 40 | }; | 39 | }; |
| @@ -1,4 +1,5 @@ | |||
| 1 | import { Fuse, DOMPurify } from '../lib.js'; | 1 | import { Fuse, DOMPurify } from '../lib.js'; |
| 2 | import { copyText, flashHighlight } from './utils.js'; | ||
| 2 | 3 | ||
| 3 | import { | 4 | import { |
| 4 | Generate, | 5 | Generate, |
| @@ -21,6 +22,7 @@ import { | |||
| 21 | extractMessageBias, | 22 | extractMessageBias, |
| 22 | generateQuietPrompt, | 23 | generateQuietPrompt, |
| 23 | generateRaw, | 24 | generateRaw, |
| 25 | getFirstDisplayedMessageId, | ||
| 24 | getThumbnailUrl, | 26 | getThumbnailUrl, |
| 25 | is_send_press, | 27 | is_send_press, |
| 26 | main_api, | 28 | main_api, |
| @@ -264,6 +266,14 @@ export function initDefaultSlashCommands() { | |||
| 264 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | 266 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), |
| 265 | forceEnum: true, | 267 | forceEnum: true, |
| 266 | }), | 268 | }), |
| 269 | SlashCommandNamedArgument.fromProps({ | ||
| 270 | name: 'raw', | ||
| 271 | description: 'If true, does not alter quoted literal unnamed arguments', | ||
| 272 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 273 | defaultValue: 'true', | ||
| 274 | enumProvider: commonEnumProviders.boolean('trueFalse'), | ||
| 275 | isRequired: false, | ||
| 276 | }), | ||
| 267 | ], | 277 | ], |
| 268 | unnamedArgumentList: [ | 278 | unnamedArgumentList: [ |
| 269 | new SlashCommandArgument( | 279 | new SlashCommandArgument( |
| @@ -314,6 +324,11 @@ export function initDefaultSlashCommands() { | |||
| 314 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 324 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 315 | }), | 325 | }), |
| 316 | SlashCommandNamedArgument.fromProps({ | 326 | SlashCommandNamedArgument.fromProps({ |
| 327 | name: 'name', | ||
| 328 | description: 'Optional custom display name to use for this system narrator message.', | ||
| 329 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 330 | }), | ||
| 331 | SlashCommandNamedArgument.fromProps({ | ||
| 317 | name: 'return', | 332 | name: 'return', |
| 318 | description: 'The way how you want the return value to be provided', | 333 | description: 'The way how you want the return value to be provided', |
| 319 | typeList: [ARGUMENT_TYPE.STRING], | 334 | typeList: [ARGUMENT_TYPE.STRING], |
| @@ -321,6 +336,14 @@ export function initDefaultSlashCommands() { | |||
| 321 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | 336 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), |
| 322 | forceEnum: true, | 337 | forceEnum: true, |
| 323 | }), | 338 | }), |
| 339 | SlashCommandNamedArgument.fromProps({ | ||
| 340 | name: 'raw', | ||
| 341 | description: 'If true, does not alter quoted literal unnamed arguments', | ||
| 342 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 343 | defaultValue: 'true', | ||
| 344 | enumProvider: commonEnumProviders.boolean('trueFalse'), | ||
| 345 | isRequired: false, | ||
| 346 | }), | ||
| 324 | ], | 347 | ], |
| 325 | unnamedArgumentList: [ | 348 | unnamedArgumentList: [ |
| 326 | new SlashCommandArgument( | 349 | new SlashCommandArgument( |
| @@ -385,6 +408,14 @@ export function initDefaultSlashCommands() { | |||
| 385 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | 408 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), |
| 386 | forceEnum: true, | 409 | forceEnum: true, |
| 387 | }), | 410 | }), |
| 411 | SlashCommandNamedArgument.fromProps({ | ||
| 412 | name: 'raw', | ||
| 413 | description: 'If true, does not alter quoted literal unnamed arguments', | ||
| 414 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 415 | defaultValue: 'true', | ||
| 416 | enumProvider: commonEnumProviders.boolean('trueFalse'), | ||
| 417 | isRequired: false, | ||
| 418 | }), | ||
| 388 | ], | 419 | ], |
| 389 | unnamedArgumentList: [ | 420 | unnamedArgumentList: [ |
| 390 | new SlashCommandArgument( | 421 | new SlashCommandArgument( |
| @@ -610,6 +641,14 @@ export function initDefaultSlashCommands() { | |||
| 610 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | 641 | enumList: slashCommandReturnHelper.enumList({ allowObject: true }), |
| 611 | forceEnum: true, | 642 | forceEnum: true, |
| 612 | }), | 643 | }), |
| 644 | SlashCommandNamedArgument.fromProps({ | ||
| 645 | name: 'raw', | ||
| 646 | description: 'If true, does not alter quoted literal unnamed arguments', | ||
| 647 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 648 | defaultValue: 'true', | ||
| 649 | enumProvider: commonEnumProviders.boolean('trueFalse'), | ||
| 650 | isRequired: false, | ||
| 651 | }), | ||
| 613 | ], | 652 | ], |
| 614 | unnamedArgumentList: [ | 653 | unnamedArgumentList: [ |
| 615 | new SlashCommandArgument( | 654 | new SlashCommandArgument( |
| @@ -1006,6 +1045,14 @@ export function initDefaultSlashCommands() { | |||
| 1006 | description: 'a closure to call when the toast is clicked. This executed closure receives scope as provided in the script. Careful about possible side effects when manipulating variables and more.', | 1045 | description: 'a closure to call when the toast is clicked. This executed closure receives scope as provided in the script. Careful about possible side effects when manipulating variables and more.', |
| 1007 | typeList: [ARGUMENT_TYPE.CLOSURE], | 1046 | typeList: [ARGUMENT_TYPE.CLOSURE], |
| 1008 | }), | 1047 | }), |
| 1048 | SlashCommandNamedArgument.fromProps({ | ||
| 1049 | name: 'raw', | ||
| 1050 | description: 'If true, does not alter quoted literal unnamed arguments', | ||
| 1051 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 1052 | defaultValue: 'true', | ||
| 1053 | enumProvider: commonEnumProviders.boolean('trueFalse'), | ||
| 1054 | isRequired: false, | ||
| 1055 | }), | ||
| 1009 | ], | 1056 | ], |
| 1010 | unnamedArgumentList: [ | 1057 | unnamedArgumentList: [ |
| 1011 | new SlashCommandArgument( | 1058 | new SlashCommandArgument( |
| @@ -2077,8 +2124,9 @@ export function initDefaultSlashCommands() { | |||
| 2077 | name: 'replace', | 2124 | name: 'replace', |
| 2078 | aliases: ['re'], | 2125 | aliases: ['re'], |
| 2079 | callback: (async ({ mode = 'literal', pattern, replacer = '' }, text) => { | 2126 | callback: (async ({ mode = 'literal', pattern, replacer = '' }, text) => { |
| 2080 | if (pattern === '') | 2127 | if (!pattern) { |
| 2081 | throw new Error('Argument of \'pattern=\' cannot be empty'); | 2128 | throw new Error('Argument of \'pattern=\' cannot be empty'); |
| 2129 | } | ||
| 2082 | switch (mode) { | 2130 | switch (mode) { |
| 2083 | case 'literal': | 2131 | case 'literal': |
| 2084 | return text.replaceAll(pattern, replacer); | 2132 | return text.replaceAll(pattern, replacer); |
| @@ -2121,14 +2169,199 @@ export function initDefaultSlashCommands() { | |||
| 2121 | </div> | 2169 | </div> |
| 2122 | <div> | 2170 | <div> |
| 2123 | <strong>Example:</strong> | 2171 | <strong>Example:</strong> |
| 2124 | <pre>/let x Blue house and blue car || </pre> | 2172 | <pre><code class="language-stscript">/let x Blue house and blue car || </code></pre> |
| 2125 | <pre>/replace pattern="blue" {{var::x}} | /echo |/# Blue house and car ||</pre> | 2173 | <pre><code class="language-stscript">/replace pattern="blue" {{var::x}} | /echo |/# Blue house and car ||</code></pre> |
| 2126 | <pre>/replace pattern="blue" replacer="red" {{var::x}} | /echo |/# Blue house and red car ||</pre> | 2174 | <pre><code class="language-stscript">/replace pattern="blue" replacer="red" {{var::x}} | /echo |/# Blue house and red car ||</code></pre> |
| 2127 | <pre>/replace mode=regex pattern="/blue/i" replacer="red" {{var::x}} | /echo |/# red house and blue car ||</pre> | 2175 | <pre><code class="language-stscript">/replace mode=regex pattern="/blue/i" replacer="red" {{var::x}} | /echo |/# red house and blue car ||</code></pre> |
| 2128 | <pre>/replace mode=regex pattern="/blue/gi" replacer="red" {{var::x}} | /echo |/# red house and red car ||</pre> | 2176 | <pre><code class="language-stscript">/replace mode=regex pattern="/blue/gi" replacer="red" {{var::x}} | /echo |/# red house and red car ||</code></pre> |
| 2129 | </div> | 2177 | </div> |
| 2130 | `, | 2178 | `, |
| 2131 | })); | 2179 | })); |
| 2180 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 2181 | name: 'test', | ||
| 2182 | callback: (({ pattern }, text) => { | ||
| 2183 | if (!pattern) { | ||
| 2184 | throw new Error('Argument of \'pattern=\' cannot be empty'); | ||
| 2185 | } | ||
| 2186 | const re = regexFromString(pattern.toString()); | ||
| 2187 | if (!re) { | ||
| 2188 | throw new Error('The value of \'pattern\' argument is not a valid regular expression.'); | ||
| 2189 | } | ||
| 2190 | return JSON.stringify(re.test(text.toString())); | ||
| 2191 | }), | ||
| 2192 | returns: 'true | false', | ||
| 2193 | namedArgumentList: [ | ||
| 2194 | new SlashCommandNamedArgument( | ||
| 2195 | 'pattern', 'pattern to find', [ARGUMENT_TYPE.STRING], true, false, | ||
| 2196 | ), | ||
| 2197 | ], | ||
| 2198 | unnamedArgumentList: [ | ||
| 2199 | new SlashCommandArgument( | ||
| 2200 | 'text to test', [ARGUMENT_TYPE.STRING], true, false, | ||
| 2201 | ), | ||
| 2202 | ], | ||
| 2203 | helpString: ` | ||
| 2204 | <div> | ||
| 2205 | Tests text for a regular expression match. | ||
| 2206 | </div> | ||
| 2207 | <div> | ||
| 2208 | Returns <code>true</code> if the match is found, <code>false</code> otherwise. | ||
| 2209 | </div> | ||
| 2210 | <div> | ||
| 2211 | <strong>Example:</strong> | ||
| 2212 | <pre><code class="language-stscript">/let x Blue house and green car ||</code></pre> | ||
| 2213 | <pre><code class="language-stscript">/test pattern="green" {{var::x}} | /echo |/# true ||</code></pre> | ||
| 2214 | <pre><code class="language-stscript">/test pattern="blue" {{var::x}} | /echo |/# false ||</code></pre> | ||
| 2215 | <pre><code class="language-stscript">/test pattern="/blue/i" {{var::x}} | /echo |/# true ||</code></pre> | ||
| 2216 | </div> | ||
| 2217 | `, | ||
| 2218 | })); | ||
| 2219 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 2220 | name: 'match', | ||
| 2221 | callback: (({ pattern }, text) => { | ||
| 2222 | if (!pattern) { | ||
| 2223 | throw new Error('Argument of \'pattern=\' cannot be empty'); | ||
| 2224 | } | ||
| 2225 | const re = regexFromString(pattern.toString()); | ||
| 2226 | if (!re) { | ||
| 2227 | throw new Error('The value of \'pattern\' argument is not a valid regular expression.'); | ||
| 2228 | } | ||
| 2229 | if (re.flags.includes('g')) { | ||
| 2230 | return JSON.stringify([...text.toString().matchAll(re)]); | ||
| 2231 | } else { | ||
| 2232 | const match = text.toString().match(re); | ||
| 2233 | return match ? JSON.stringify(match) : ''; | ||
| 2234 | } | ||
| 2235 | }), | ||
| 2236 | returns: 'group array for each match', | ||
| 2237 | namedArgumentList: [ | ||
| 2238 | new SlashCommandNamedArgument( | ||
| 2239 | 'pattern', 'pattern to find', [ARGUMENT_TYPE.STRING], true, false, | ||
| 2240 | ), | ||
| 2241 | ], | ||
| 2242 | unnamedArgumentList: [ | ||
| 2243 | new SlashCommandArgument( | ||
| 2244 | 'text to match against', [ARGUMENT_TYPE.STRING], true, false, | ||
| 2245 | ), | ||
| 2246 | ], | ||
| 2247 | helpString: ` | ||
| 2248 | <div> | ||
| 2249 | Retrieves regular expression matches in the given text | ||
| 2250 | </div> | ||
| 2251 | <div> | ||
| 2252 | Returns an array of groups (with the first group being the full match). If the regex contains the global flag (i.e. <code>/g</code>), | ||
| 2253 | multiple nested arrays are returned for each match. If the regex is global, returns <code>[]</code> if no matches are found, | ||
| 2254 | otherwise it returns an empty string. | ||
| 2255 | </div> | ||
| 2256 | <div> | ||
| 2257 | <strong>Example:</strong> | ||
| 2258 | <pre><code class="language-stscript">/let x color_green green lamp color_blue ||</code></pre> | ||
| 2259 | <pre><code class="language-stscript">/match pattern="green" {{var::x}} | /echo |/# [ "green" ] ||</code></pre> | ||
| 2260 | <pre><code class="language-stscript">/match pattern="color_(\\w+)" {{var::x}} | /echo |/# [ "color_green", "green" ] ||</code></pre> | ||
| 2261 | <pre><code class="language-stscript">/match pattern="/color_(\\w+)/g" {{var::x}} | /echo |/# [ [ "color_green", "green" ], [ "color_blue", "blue" ] ] ||</code></pre> | ||
| 2262 | <pre><code class="language-stscript">/match pattern="orange" {{var::x}} | /echo |/# ||</code></pre> | ||
| 2263 | <pre><code class="language-stscript">/match pattern="/orange/g" {{var::x}} | /echo |/# [] ||</code></pre> | ||
| 2264 | </div> | ||
| 2265 | `, | ||
| 2266 | })); | ||
| 2267 | |||
| 2268 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 2269 | name: 'chat-jump', | ||
| 2270 | aliases: ['chat-scrollto', 'floor-teleport'], | ||
| 2271 | callback: async (_, index) => { | ||
| 2272 | const messageIndex = Number(index); | ||
| 2273 | |||
| 2274 | if (isNaN(messageIndex) || messageIndex < 0 || messageIndex >= chat.length) { | ||
| 2275 | toastr.warning(t`Invalid message index: ${index}. Please enter a number between 0 and ${chat.length}.`); | ||
| 2276 | console.warn(`WARN: Invalid message index provided for /chat-jump: ${index}. Max index: ${chat.length}`); | ||
| 2277 | return ''; | ||
| 2278 | } | ||
| 2279 | |||
| 2280 | // Load more messages if needed | ||
| 2281 | const firstDisplayedMessageId = getFirstDisplayedMessageId(); | ||
| 2282 | if (isFinite(firstDisplayedMessageId) && messageIndex < firstDisplayedMessageId) { | ||
| 2283 | const needToLoadCount = firstDisplayedMessageId - messageIndex; | ||
| 2284 | await showMoreMessages(needToLoadCount); | ||
| 2285 | await delay(1); | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | const chatContainer = document.getElementById('chat'); | ||
| 2289 | const messageElement = document.querySelector(`#chat .mes[mesid="${messageIndex}"]`); | ||
| 2290 | |||
| 2291 | if (messageElement instanceof HTMLElement && chatContainer instanceof HTMLElement) { | ||
| 2292 | const elementRect = messageElement.getBoundingClientRect(); | ||
| 2293 | const containerRect = chatContainer.getBoundingClientRect(); | ||
| 2294 | |||
| 2295 | const scrollPosition = elementRect.top - containerRect.top + chatContainer.scrollTop; | ||
| 2296 | chatContainer.scrollTo({ | ||
| 2297 | top: scrollPosition, | ||
| 2298 | behavior: 'smooth', | ||
| 2299 | }); | ||
| 2300 | |||
| 2301 | flashHighlight($(messageElement), 2000); | ||
| 2302 | } else { | ||
| 2303 | toastr.warning(t`Could not find element for message ${messageIndex}. It might not be rendered yet or the index is invalid.`); | ||
| 2304 | console.warn(`WARN: Element not found for message index ${messageIndex} in /chat-jump.`); | ||
| 2305 | } | ||
| 2306 | |||
| 2307 | return ''; | ||
| 2308 | }, | ||
| 2309 | unnamedArgumentList: [ | ||
| 2310 | SlashCommandArgument.fromProps({ | ||
| 2311 | description: 'The message index (0-based) to scroll to.', | ||
| 2312 | typeList: [ARGUMENT_TYPE.NUMBER], | ||
| 2313 | isRequired: true, | ||
| 2314 | enumProvider: commonEnumProviders.messages(), | ||
| 2315 | }), | ||
| 2316 | ], | ||
| 2317 | helpString: ` | ||
| 2318 | <div> | ||
| 2319 | Scrolls the chat view to the specified message index. Index starts at 0. | ||
| 2320 | </div> | ||
| 2321 | <div> | ||
| 2322 | <strong>Example:</strong> <pre><code>/chat-jump 10</code></pre> Scrolls to the 11th message (id=10). | ||
| 2323 | </div> | ||
| 2324 | `, | ||
| 2325 | })); | ||
| 2326 | |||
| 2327 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 2328 | name: 'clipboard-get', | ||
| 2329 | returns: 'clipboard text', | ||
| 2330 | callback: async () => { | ||
| 2331 | if (!navigator.clipboard) { | ||
| 2332 | toastr.warning('Clipboard API not available in this context.'); | ||
| 2333 | return ''; | ||
| 2334 | } | ||
| 2335 | |||
| 2336 | try { | ||
| 2337 | const text = await navigator.clipboard.readText(); | ||
| 2338 | return text; | ||
| 2339 | } | ||
| 2340 | catch (error) { | ||
| 2341 | console.error('Error reading clipboard:', error); | ||
| 2342 | toastr.warning('Failed to read clipboard text. Have you granted the permission?'); | ||
| 2343 | return ''; | ||
| 2344 | } | ||
| 2345 | }, | ||
| 2346 | helpString: 'Retrieves the text from the OS clipboard. Only works in secure contexts (HTTPS or localhost). Browser may ask for permission.', | ||
| 2347 | })); | ||
| 2348 | |||
| 2349 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 2350 | name: 'clipboard-set', | ||
| 2351 | callback: async (_, text) => { | ||
| 2352 | await copyText(text.toString()); | ||
| 2353 | return ''; | ||
| 2354 | }, | ||
| 2355 | unnamedArgumentList: [ | ||
| 2356 | SlashCommandArgument.fromProps({ | ||
| 2357 | description: 'text to copy to the clipboard', | ||
| 2358 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 2359 | isRequired: true, | ||
| 2360 | acceptsMultiple: false, | ||
| 2361 | }), | ||
| 2362 | ], | ||
| 2363 | helpString: 'Copies the provided text to the OS clipboard. Returns an empty string.', | ||
| 2364 | })); | ||
| 2132 | 2365 | ||
| 2133 | registerVariableCommands(); | 2366 | registerVariableCommands(); |
| 2134 | } | 2367 | } |
| @@ -3702,7 +3935,7 @@ export async function sendMessageAs(args, text) { | |||
| 3702 | 3935 | ||
| 3703 | export async function sendNarratorMessage(args, text) { | 3936 | export async function sendNarratorMessage(args, text) { |
| 3704 | text = String(text ?? ''); | 3937 | text = String(text ?? ''); |
| 3705 | const name = chat_metadata[NARRATOR_NAME_KEY] || NARRATOR_NAME_DEFAULT; | 3938 | const name = args.name ?? (chat_metadata[NARRATOR_NAME_KEY] || NARRATOR_NAME_DEFAULT); |
| 3706 | // Messages that do nothing but set bias will be hidden from the context | 3939 | // Messages that do nothing but set bias will be hidden from the context |
| 3707 | const bias = extractMessageBias(text); | 3940 | const bias = extractMessageBias(text); |
| 3708 | const isSystem = bias && !removeMacros(text).length; | 3941 | const isSystem = bias && !removeMacros(text).length; |
| @@ -3934,6 +4167,7 @@ function getModelOptions(quiet) { | |||
| 3934 | { id: 'model_openrouter_select', api: 'openai', type: chat_completion_sources.OPENROUTER }, | 4167 | { id: 'model_openrouter_select', api: 'openai', type: chat_completion_sources.OPENROUTER }, |
| 3935 | { id: 'model_ai21_select', api: 'openai', type: chat_completion_sources.AI21 }, | 4168 | { id: 'model_ai21_select', api: 'openai', type: chat_completion_sources.AI21 }, |
| 3936 | { id: 'model_google_select', api: 'openai', type: chat_completion_sources.MAKERSUITE }, | 4169 | { id: 'model_google_select', api: 'openai', type: chat_completion_sources.MAKERSUITE }, |
| 4170 | { id: 'model_vertexai_select', api: 'openai', type: chat_completion_sources.VERTEXAI }, | ||
| 3937 | { id: 'model_mistralai_select', api: 'openai', type: chat_completion_sources.MISTRALAI }, | 4171 | { id: 'model_mistralai_select', api: 'openai', type: chat_completion_sources.MISTRALAI }, |
| 3938 | { id: 'custom_model_id', api: 'openai', type: chat_completion_sources.CUSTOM }, | 4172 | { id: 'custom_model_id', api: 'openai', type: chat_completion_sources.CUSTOM }, |
| 3939 | { id: 'model_cohere_select', api: 'openai', type: chat_completion_sources.COHERE }, | 4173 | { id: 'model_cohere_select', api: 'openai', type: chat_completion_sources.COHERE }, |
| @@ -3943,6 +4177,7 @@ function getModelOptions(quiet) { | |||
| 3943 | { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI }, | 4177 | { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI }, |
| 3944 | { id: 'model_deepseek_select', api: 'openai', type: chat_completion_sources.DEEPSEEK }, | 4178 | { id: 'model_deepseek_select', api: 'openai', type: chat_completion_sources.DEEPSEEK }, |
| 3945 | { id: 'model_xai_select', api: 'openai', type: chat_completion_sources.XAI }, | 4179 | { id: 'model_xai_select', api: 'openai', type: chat_completion_sources.XAI }, |
| 4180 | { id: 'model_pollinations_select', api: 'openai', type: chat_completion_sources.POLLINATIONS }, | ||
| 3946 | { id: 'model_novel_select', api: 'novel', type: null }, | 4181 | { id: 'model_novel_select', api: 'novel', type: null }, |
| 3947 | { id: 'horde_model', api: 'koboldhorde', type: null }, | 4182 | { id: 'horde_model', api: 'koboldhorde', type: null }, |
| 3948 | ]; | 4183 | ]; |
| @@ -266,7 +266,7 @@ export class SlashCommand { | |||
| 266 | rawQuotes.classList.add('rawQuotes'); | 266 | rawQuotes.classList.add('rawQuotes'); |
| 267 | rawQuotes.classList.add('fa-solid'); | 267 | rawQuotes.classList.add('fa-solid'); |
| 268 | rawQuotes.classList.add('fa-quote-left'); | 268 | rawQuotes.classList.add('fa-quote-left'); |
| 269 | rawQuotes.title = t`Does not alter quoted literal unnamed arguments`; | 269 | rawQuotes.title = t`Does not alter quoted literal unnamed arguments. Pass raw=false argument to override.`; |
| 270 | head.append(rawQuotes); | 270 | head.append(rawQuotes); |
| 271 | } | 271 | } |
| 272 | } | 272 | } |
| @@ -1,6 +1,6 @@ | |||
| 1 | import { hljs } from '../../lib.js'; | 1 | import { hljs } from '../../lib.js'; |
| 2 | import { power_user } from '../power-user.js'; | 2 | import { power_user } from '../power-user.js'; |
| 3 | import { isTrueBoolean, uuidv4 } from '../utils.js'; | 3 | import { isFalseBoolean, isTrueBoolean, uuidv4 } from '../utils.js'; |
| 4 | import { SlashCommand } from './SlashCommand.js'; | 4 | import { SlashCommand } from './SlashCommand.js'; |
| 5 | import { ARGUMENT_TYPE, SlashCommandArgument } from './SlashCommandArgument.js'; | 5 | import { ARGUMENT_TYPE, SlashCommandArgument } from './SlashCommandArgument.js'; |
| 6 | import { SlashCommandClosure } from './SlashCommandClosure.js'; | 6 | import { SlashCommandClosure } from './SlashCommandClosure.js'; |
| @@ -975,7 +975,9 @@ export class SlashCommandParser { | |||
| 975 | cmd.startUnnamedArgs = this.index - (/\s(\s*)$/s.exec(this.behind)?.[1]?.length ?? 0); | 975 | cmd.startUnnamedArgs = this.index - (/\s(\s*)$/s.exec(this.behind)?.[1]?.length ?? 0); |
| 976 | cmd.endUnnamedArgs = this.index; | 976 | cmd.endUnnamedArgs = this.index; |
| 977 | if (this.testUnnamedArgument()) { | 977 | if (this.testUnnamedArgument()) { |
| 978 | cmd.unnamedArgumentList = this.parseUnnamedArgument(cmd.command?.unnamedArgumentList?.length && cmd?.command?.splitUnnamedArgument, cmd?.command?.splitUnnamedArgumentCount, cmd?.command?.rawQuotes); | 978 | const rawQuotesArg = cmd?.namedArgumentList?.find(a => a.name === 'raw'); |
| 979 | const rawQuotes = cmd?.command?.rawQuotes && rawQuotesArg ? !isFalseBoolean(rawQuotesArg?.value?.toString()) : cmd?.command?.rawQuotes; | ||
| 980 | cmd.unnamedArgumentList = this.parseUnnamedArgument(cmd.command?.unnamedArgumentList?.length && cmd?.command?.splitUnnamedArgument, cmd?.command?.splitUnnamedArgumentCount, rawQuotes); | ||
| 979 | cmd.endUnnamedArgs = this.index; | 981 | cmd.endUnnamedArgs = this.index; |
| 980 | if (cmd.name == 'let') { | 982 | if (cmd.name == 'let') { |
| 981 | const keyArg = cmd.namedArgumentList.find(it=>it.name == 'key'); | 983 | const keyArg = cmd.namedArgumentList.find(it=>it.name == 'key'); |
| @@ -50,6 +50,8 @@ import { | |||
| 50 | unshallowCharacter, | 50 | unshallowCharacter, |
| 51 | deleteLastMessage, | 51 | deleteLastMessage, |
| 52 | getCharacterCardFields, | 52 | getCharacterCardFields, |
| 53 | swipe_right, | ||
| 54 | swipe_left, | ||
| 53 | } from '../script.js'; | 55 | } from '../script.js'; |
| 54 | import { | 56 | import { |
| 55 | extension_settings, | 57 | extension_settings, |
| @@ -196,6 +198,7 @@ export function getContext() { | |||
| 196 | humanizedDateTime, | 198 | humanizedDateTime, |
| 197 | updateMessageBlock, | 199 | updateMessageBlock, |
| 198 | appendMediaToMessage, | 200 | appendMediaToMessage, |
| 201 | swipe: { left: swipe_left, right: swipe_right }, | ||
| 199 | variables: { | 202 | variables: { |
| 200 | local: { | 203 | local: { |
| 201 | get: getLocalVariable, | 204 | get: getLocalVariable, |
| @@ -17,6 +17,7 @@ export let system_prompts = []; | |||
| 17 | const $enabled = $('#sysprompt_enabled'); | 17 | const $enabled = $('#sysprompt_enabled'); |
| 18 | const $select = $('#sysprompt_select'); | 18 | const $select = $('#sysprompt_select'); |
| 19 | const $content = $('#sysprompt_content'); | 19 | const $content = $('#sysprompt_content'); |
| 20 | const $postHistory = $('#sysprompt_post_history'); | ||
| 20 | const $contentBlock = $('#SystemPromptBlock'); | 21 | const $contentBlock = $('#SystemPromptBlock'); |
| 21 | 22 | ||
| 22 | async function migrateSystemPromptFromInstructMode() { | 23 | async function migrateSystemPromptFromInstructMode() { |
| @@ -25,6 +26,7 @@ async function migrateSystemPromptFromInstructMode() { | |||
| 25 | delete power_user.instruct.system_prompt; | 26 | delete power_user.instruct.system_prompt; |
| 26 | power_user.sysprompt.enabled = power_user.instruct.enabled; | 27 | power_user.sysprompt.enabled = power_user.instruct.enabled; |
| 27 | power_user.sysprompt.content = prompt; | 28 | power_user.sysprompt.content = prompt; |
| 29 | power_user.sysprompt.post_history = ''; | ||
| 28 | 30 | ||
| 29 | const existingPromptName = system_prompts.find(x => x.content === prompt)?.name; | 31 | const existingPromptName = system_prompts.find(x => x.content === prompt)?.name; |
| 30 | 32 | ||
| @@ -59,7 +61,8 @@ export async function loadSystemPrompts(data) { | |||
| 59 | 61 | ||
| 60 | $enabled.prop('checked', power_user.sysprompt.enabled); | 62 | $enabled.prop('checked', power_user.sysprompt.enabled); |
| 61 | $select.val(power_user.sysprompt.name); | 63 | $select.val(power_user.sysprompt.name); |
| 62 | $content.val(power_user.sysprompt.content); | 64 | $content.val(power_user.sysprompt.content || ''); |
| 65 | $postHistory.val(power_user.sysprompt.post_history || ''); | ||
| 63 | if (!CSS.supports('field-sizing', 'content')) { | 66 | if (!CSS.supports('field-sizing', 'content')) { |
| 64 | await resetScrollHeight($content); | 67 | await resetScrollHeight($content); |
| 65 | } | 68 | } |
| @@ -165,13 +168,17 @@ export function initSystemPrompts() { | |||
| 165 | const name = String($(this).val()); | 168 | const name = String($(this).val()); |
| 166 | const prompt = system_prompts.find(p => p.name === name); | 169 | const prompt = system_prompts.find(p => p.name === name); |
| 167 | if (prompt) { | 170 | if (prompt) { |
| 168 | $content.val(prompt.content); | 171 | $content.val(prompt.content || ''); |
| 172 | $postHistory.val(prompt.post_history || ''); | ||
| 173 | |||
| 169 | if (!CSS.supports('field-sizing', 'content')) { | 174 | if (!CSS.supports('field-sizing', 'content')) { |
| 170 | await resetScrollHeight($content); | 175 | await resetScrollHeight($content); |
| 176 | await resetScrollHeight($postHistory); | ||
| 171 | } | 177 | } |
| 172 | 178 | ||
| 173 | power_user.sysprompt.name = name; | 179 | power_user.sysprompt.name = name; |
| 174 | power_user.sysprompt.content = prompt.content; | 180 | power_user.sysprompt.content = prompt.content || ''; |
| 181 | power_user.sysprompt.post_history = prompt.post_history || ''; | ||
| 175 | } | 182 | } |
| 176 | saveSettingsDebounced(); | 183 | saveSettingsDebounced(); |
| 177 | }); | 184 | }); |
| @@ -181,6 +188,11 @@ export function initSystemPrompts() { | |||
| 181 | saveSettingsDebounced(); | 188 | saveSettingsDebounced(); |
| 182 | }); | 189 | }); |
| 183 | 190 | ||
| 191 | $postHistory.on('input', function () { | ||
| 192 | power_user.sysprompt.post_history = String($(this).val()); | ||
| 193 | saveSettingsDebounced(); | ||
| 194 | }); | ||
| 195 | |||
| 184 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 196 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 185 | name: 'sysprompt', | 197 | name: 'sysprompt', |
| 186 | aliases: ['system-prompt'], | 198 | aliases: ['system-prompt'], |
| @@ -27,7 +27,7 @@ import { debounce_timeout } from './constants.js'; | |||
| 27 | import { INTERACTABLE_CONTROL_CLASS } from './keyboard.js'; | 27 | import { INTERACTABLE_CONTROL_CLASS } from './keyboard.js'; |
| 28 | import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js'; | 28 | import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 29 | import { renderTemplateAsync } from './templates.js'; | 29 | import { renderTemplateAsync } from './templates.js'; |
| 30 | import { t } from './i18n.js'; | 30 | import { t, translate } from './i18n.js'; |
| 31 | 31 | ||
| 32 | export { | 32 | export { |
| 33 | TAG_FOLDER_TYPES, | 33 | TAG_FOLDER_TYPES, |
| @@ -136,6 +136,7 @@ const TAG_FOLDER_DEFAULT_TYPE = 'NONE'; | |||
| 136 | * @property {string} [color] - The background color of the tag | 136 | * @property {string} [color] - The background color of the tag |
| 137 | * @property {string} [color2] - The foreground color of the tag | 137 | * @property {string} [color2] - The foreground color of the tag |
| 138 | * @property {number} [create_date] - A number representing the date when this tag was created | 138 | * @property {number} [create_date] - A number representing the date when this tag was created |
| 139 | * @property {boolean} is_hidden_on_character_card - Whether this tag is hidden on the character card | ||
| 139 | * | 140 | * |
| 140 | * @property {function} [action] - An optional function that gets executed when this tag is an actionable tag and is clicked on. | 141 | * @property {function} [action] - An optional function that gets executed when this tag is an actionable tag and is clicked on. |
| 141 | * @property {string} [class] - An optional css class added to the control representing this tag when printed. Used for custom tags in the filters. | 142 | * @property {string} [class] - An optional css class added to the control representing this tag when printed. Used for custom tags in the filters. |
| @@ -318,7 +319,7 @@ function getTagBlock(tag, entities, hidden = 0, isUseless = false) { | |||
| 318 | template.find('.avatar').css({ 'background-color': tag.color, 'color': tag.color2 }).attr('title', `[Folder] ${tag.name}`); | 319 | template.find('.avatar').css({ 'background-color': tag.color, 'color': tag.color2 }).attr('title', `[Folder] ${tag.name}`); |
| 319 | template.find('.ch_name').text(tag.name).attr('title', `[Folder] ${tag.name}`); | 320 | template.find('.ch_name').text(tag.name).attr('title', `[Folder] ${tag.name}`); |
| 320 | template.find('.bogus_folder_hidden_counter').text(hidden > 0 ? `${hidden} hidden` : ''); | 321 | template.find('.bogus_folder_hidden_counter').text(hidden > 0 ? `${hidden} hidden` : ''); |
| 321 | template.find('.bogus_folder_counter').text(`${count} ${count != 1 ? 'characters' : 'character'}`); | 322 | template.find('.bogus_folder_counter').text(`${count} ` + (count != 1 ? t`characters` : t`character`)); |
| 322 | template.find('.bogus_folder_icon').addClass(tagFolder.fa_icon); | 323 | template.find('.bogus_folder_icon').addClass(tagFolder.fa_icon); |
| 323 | if (isUseless) template.addClass('useless'); | 324 | if (isUseless) template.addClass('useless'); |
| 324 | 325 | ||
| @@ -895,6 +896,7 @@ function newTag(tagName) { | |||
| 895 | folder_type: TAG_FOLDER_DEFAULT_TYPE, | 896 | folder_type: TAG_FOLDER_DEFAULT_TYPE, |
| 896 | filter_state: DEFAULT_FILTER_STATE, | 897 | filter_state: DEFAULT_FILTER_STATE, |
| 897 | sort_order: Math.max(0, ...tags.map(t => t.sort_order)) + 1, | 898 | sort_order: Math.max(0, ...tags.map(t => t.sort_order)) + 1, |
| 899 | is_hidden_on_character_card: false, | ||
| 898 | color: '', | 900 | color: '', |
| 899 | color2: '', | 901 | color2: '', |
| 900 | create_date: Date.now(), | 902 | create_date: Date.now(), |
| @@ -909,6 +911,7 @@ function newTag(tagName) { | |||
| 909 | * @property {(tag: Tag)=>boolean} [removeAction=undefined] - Action to perform on tag removal instead of the default remove action. If the action returns false, the tag will not be removed. | 911 | * @property {(tag: Tag)=>boolean} [removeAction=undefined] - Action to perform on tag removal instead of the default remove action. If the action returns false, the tag will not be removed. |
| 910 | * @property {boolean} [isGeneralList=false] - If true, indicates that this is the general list of tags. | 912 | * @property {boolean} [isGeneralList=false] - If true, indicates that this is the general list of tags. |
| 911 | * @property {boolean} [skipExistsCheck=false] - If true, the tag gets added even if a tag with the same id already exists. | 913 | * @property {boolean} [skipExistsCheck=false] - If true, the tag gets added even if a tag with the same id already exists. |
| 914 | * @property {boolean} [isCharacterList=false] - If true, indicates that this is the character's list of tags. | ||
| 912 | */ | 915 | */ |
| 913 | 916 | ||
| 914 | /** | 917 | /** |
| @@ -934,6 +937,10 @@ function printTagList(element, { tags = undefined, addTag = undefined, forEntity | |||
| 934 | const key = forEntityOrKey !== undefined ? getTagKeyForEntity(forEntityOrKey) : getTagKey(); | 937 | const key = forEntityOrKey !== undefined ? getTagKeyForEntity(forEntityOrKey) : getTagKey(); |
| 935 | let printableTags = tags ? (typeof tags === 'function' ? tags() : tags) : getTagsList(key, sort); | 938 | let printableTags = tags ? (typeof tags === 'function' ? tags() : tags) : getTagsList(key, sort); |
| 936 | 939 | ||
| 940 | if (tagOptions.isCharacterList) { | ||
| 941 | printableTags = printableTags.filter(tag => !tag.is_hidden_on_character_card); | ||
| 942 | } | ||
| 943 | |||
| 937 | if (empty === 'always' || (empty && (printableTags?.length > 0 || key))) { | 944 | if (empty === 'always' || (empty && (printableTags?.length > 0 || key))) { |
| 938 | $element.empty(); | 945 | $element.empty(); |
| 939 | } | 946 | } |
| @@ -1057,7 +1064,7 @@ function appendTagToList(listElement, tag, { removable = false, isFilter = false | |||
| 1057 | tagElement.attr('title', tag.title); | 1064 | tagElement.attr('title', tag.title); |
| 1058 | } | 1065 | } |
| 1059 | if (tag.icon) { | 1066 | if (tag.icon) { |
| 1060 | tagElement.find('.tag_name').text('').attr('title', `${tag.name} ${tag.title || ''}`.trim()).addClass(tag.icon); | 1067 | tagElement.find('.tag_name').text('').attr('title', `${translate(tag.name)} ${tag.title || ''}`.trim()).addClass(tag.icon); |
| 1061 | tagElement.addClass('actionable'); | 1068 | tagElement.addClass('actionable'); |
| 1062 | } | 1069 | } |
| 1063 | 1070 | ||
| @@ -1308,7 +1315,7 @@ async function onViewTagsListClick() { | |||
| 1308 | printViewTagList(tagContainer); | 1315 | printViewTagList(tagContainer); |
| 1309 | makeTagListDraggable(tagContainer); | 1316 | makeTagListDraggable(tagContainer); |
| 1310 | 1317 | ||
| 1311 | await callGenericPopup(html, POPUP_TYPE.TEXT, null, { allowVerticalScrolling: true }); | 1318 | await callGenericPopup(html, POPUP_TYPE.TEXT, null, { allowVerticalScrolling: true, wide: true, large: true }); |
| 1312 | } | 1319 | } |
| 1313 | 1320 | ||
| 1314 | /** | 1321 | /** |
| @@ -1594,6 +1601,21 @@ function appendViewTagToList(list, tag, everything) { | |||
| 1594 | colorPicker[0].color = defaultColor; | 1601 | colorPicker[0].color = defaultColor; |
| 1595 | }); | 1602 | }); |
| 1596 | 1603 | ||
| 1604 | const getHideTooltip = () => tag.is_hidden_on_character_card ? t`Hide on character card` : t`Show on character card`; | ||
| 1605 | const hideToggle = template.find('.eye-toggle'); | ||
| 1606 | hideToggle.toggleClass('fa-eye-slash', tag.is_hidden_on_character_card); | ||
| 1607 | hideToggle.toggleClass('fa-eye', !tag.is_hidden_on_character_card); | ||
| 1608 | hideToggle.attr('title', getHideTooltip()); | ||
| 1609 | |||
| 1610 | hideToggle.on('click', () => { | ||
| 1611 | tag.is_hidden_on_character_card = !tag.is_hidden_on_character_card; | ||
| 1612 | hideToggle.toggleClass('fa-eye-slash', tag.is_hidden_on_character_card); | ||
| 1613 | hideToggle.toggleClass('fa-eye', !tag.is_hidden_on_character_card); | ||
| 1614 | hideToggle.attr('title', getHideTooltip()); | ||
| 1615 | printCharactersDebounced(); | ||
| 1616 | saveSettingsDebounced(); | ||
| 1617 | }); | ||
| 1618 | |||
| 1597 | list.append(template); | 1619 | list.append(template); |
| 1598 | 1620 | ||
| 1599 | // We prevent the popup from auto-close on Escape press on the color pickups. If the user really wants to, he can hit it again | 1621 | // We prevent the popup from auto-close on Escape press on the color pickups. If the user really wants to, he can hit it again |
| @@ -1644,6 +1666,7 @@ function updateDrawTagFolder(element, tag) { | |||
| 1644 | 1666 | ||
| 1645 | // Draw/update css attributes for this class | 1667 | // Draw/update css attributes for this class |
| 1646 | folderElement.attr('title', tagFolder.tooltip); | 1668 | folderElement.attr('title', tagFolder.tooltip); |
| 1669 | folderElement.attr('data-i18n', '[title]' + tagFolder.tooltip); | ||
| 1647 | const indicator = folderElement.find('.tag_folder_indicator'); | 1670 | const indicator = folderElement.find('.tag_folder_indicator'); |
| 1648 | indicator.text(tagFolder.icon); | 1671 | indicator.text(tagFolder.icon); |
| 1649 | indicator.css('color', tagFolder.color); | 1672 | indicator.css('color', tagFolder.color); |
| @@ -1655,14 +1678,7 @@ async function onTagDeleteClick() { | |||
| 1655 | const tag = tags.find(x => x.id === id); | 1678 | const tag = tags.find(x => x.id === id); |
| 1656 | const otherTags = sortTags(tags.filter(x => x.id !== id).map(x => ({ id: x.id, name: x.name }))); | 1679 | const otherTags = sortTags(tags.filter(x => x.id !== id).map(x => ({ id: x.id, name: x.name }))); |
| 1657 | 1680 | ||
| 1658 | const popupContent = $(` | 1681 | const popupContent = $(await renderTemplateAsync('deleteTag', { otherTags })); |
| 1659 | <h3>Delete Tag</h3> | ||
| 1660 | <div>Do you want to delete the tag <div id="tag_to_delete" class="tags_inline inline-flex margin-r2"></div>?</div> | ||
| 1661 | <div class="m-t-2 marginBot5">If you want to merge all references to this tag into another tag, select it below:</div> | ||
| 1662 | <select id="merge_tag_select"> | ||
| 1663 | <option value="">--- None ---</option> | ||
| 1664 | ${otherTags.map(x => `<option value="${x.id}">${x.name}</option>`).join('')} | ||
| 1665 | </select>`); | ||
| 1666 | 1682 | ||
| 1667 | appendTagToList(popupContent.find('#tag_to_delete'), tag); | 1683 | appendTagToList(popupContent.find('#tag_to_delete'), tag); |
| 1668 | 1684 | ||
| @@ -1,9 +1,13 @@ | |||
| 1 | <div data-type="assistant_note"> | 1 | <div data-type="assistant_note"> |
| 2 | <div> | 2 | <div class="assistant_note_title"> |
| 3 | <b data-i18n="Note:">Note:</b> <span data-i18n="this chat is temporary and will be deleted as soon as you leave it.">this chat is temporary and will be deleted as soon as you leave it.</span> | 3 | <b data-i18n="Note:">Note:</b> <span data-i18n="this chat is temporary and will be deleted as soon as you leave it.">this chat is temporary and will be deleted as soon as you leave it.</span> |
| 4 | <span data-i18n="Click the button to save it as a file.">Click the button to save it as a file.</span> | ||
| 5 | </div> | 4 | </div> |
| 6 | <div class="assistant_note_export menu_button menu_button_icon" data-i18n="[title]Export as JSONL" title="Export as JSONL"> | 5 | <button class="assistant_note_import menu_button menu_button_icon margin0" data-i18n="[title]Import from JSONL" title="Import from JSONL"> |
| 6 | <i class="fa-solid fa-file-import"></i> | ||
| 7 | <span data-i18n="Load">Load</span> | ||
| 8 | </button> | ||
| 9 | <button class="assistant_note_export menu_button menu_button_icon margin0" data-i18n="[title]Export as JSONL" title="Export as JSONL"> | ||
| 7 | <i class="fa-solid fa-file-export"></i> | 10 | <i class="fa-solid fa-file-export"></i> |
| 8 | </div> | 11 | <span data-i18n="Save">Save</span> |
| 12 | </button> | ||
| 9 | </div> | 13 | </div> |
| @@ -0,0 +1,9 @@ | |||
| 1 | <h3 data-i18n="Delete Tag">Delete Tag</h3> | ||
| 2 | <div><span data-i18n="Do you want to delete the tag">Do you want to delete the tag</span> <div id="tag_to_delete" class="tags_inline inline-flex margin-r2"></div>?</div> | ||
| 3 | <div class="m-t-2 marginBot5" data-i18n="If you want to merge all references to this tag into another tag, select it below:">If you want to merge all references to this tag into another tag, select it below:</div> | ||
| 4 | <select id="merge_tag_select"> | ||
| 5 | <option value="">--- None ---</option> | ||
| 6 | {{#each otherTags}} | ||
| 7 | <option value="{{this.id}}">{{this.name}}</option> | ||
| 8 | {{/each}} | ||
| 9 | </select> | ||
| \ No newline at end of file | 9 | \ No newline at end of file | |
| @@ -0,0 +1,7 @@ | |||
| 1 | <div class="text_block empty_block"> | ||
| 2 | <i class="fa-solid {{icon}} fa-4x"></i> | ||
| 3 | <h1>{{text}}</h1> | ||
| 4 | <p data-i18n="There are no items to display."> | ||
| 5 | There are no items to display. | ||
| 6 | </p> | ||
| 7 | </div> | ||
| @@ -0,0 +1,27 @@ | |||
| 1 | <div class="flex-container flexFlowColumn marginBot10"> | ||
| 2 | <h3 data-i18n="Do you want to export connection data with the preset?"> | ||
| 3 | Do you want to export connection data with the preset? | ||
| 4 | </h3> | ||
| 5 | |||
| 6 | <div data-i18n="This includes the selected source, models, and other preferences set in the API Connections panel."> | ||
| 7 | This includes the selected source, models, and other preferences set in the API Connections panel. | ||
| 8 | </div> | ||
| 9 | |||
| 10 | <strong data-i18n="Your stored API keys are never exported."> | ||
| 11 | Your stored API keys are never exported. | ||
| 12 | </strong> | ||
| 13 | </div> | ||
| 14 | <div class="flex-container flexFlowColumn"> | ||
| 15 | <label class="checkbox_label" for="export_connection_data_yes"> | ||
| 16 | <input type="radio" id="export_connection_data_yes" name="export_connection_data" value="true"> | ||
| 17 | <span data-i18n="Export connection data"> | ||
| 18 | Export connection data | ||
| 19 | </span> | ||
| 20 | </label> | ||
| 21 | <label class="checkbox_label" for="export_connection_data_no"> | ||
| 22 | <input type="radio" id="export_connection_data_no" name="export_connection_data" value="false" checked> | ||
| 23 | <span data-i18n="Do not export connection data"> | ||
| 24 | Do not export connection data | ||
| 25 | </span> | ||
| 26 | </label> | ||
| 27 | </div> | ||
| @@ -0,0 +1,27 @@ | |||
| 1 | <div class="flex-container flexFlowColumn"> | ||
| 2 | <h3 data-i18n="Creator's Notes contain CSS style tags. Do you want to apply them just to Creator's Notes or to the entire application?" class="margin0"> | ||
| 3 | Creator's Notes contain CSS style tags. Do you want to apply them just to Creator's Notes or to the entire application? | ||
| 4 | </h3> | ||
| 5 | <h4 data-i18n="CAUTION: Malformed styles may cause issues." class="neutral_warning"> | ||
| 6 | CAUTION: Malformed styles may cause issues. | ||
| 7 | </h4> | ||
| 8 | <hr> | ||
| 9 | <small> | ||
| 10 | <span data-i18n="To change the preference later, use the"> | ||
| 11 | To change the preference later, use the | ||
| 12 | </span> | ||
| 13 | <code class="fa-solid fa-palette"></code> | ||
| 14 | <span data-i18n="button in the Creator's Notes block."> | ||
| 15 | button in the Creator's Notes block. | ||
| 16 | </span> | ||
| 17 | </small> | ||
| 18 | <textarea class="text_pole textarea_compact monospace" rows="8" readonly></textarea> | ||
| 19 | <small class="justifyLeft"> | ||
| 20 | <b data-i18n="Note:"> | ||
| 21 | Note: | ||
| 22 | </b> | ||
| 23 | <span data-i18n="Class names will be automatically prefixed with 'custom-'."> | ||
| 24 | Class names will be automatically prefixed with 'custom-'. | ||
| 25 | </span> | ||
| 26 | </small> | ||
| 27 | </div> | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | <div class="flex-container flexFlowColumn"> | ||
| 2 | <h3 data-i18n="Choose how to apply CSS style tags if they are defined in Creator's Notes of this character:" class="margin0"> | ||
| 3 | Choose how to apply CSS style tags if they are defined in Creator's Notes of this character: | ||
| 4 | </h3> | ||
| 5 | <h4 data-i18n="CAUTION: Malformed styles may cause issues." class="neutral_warning"> | ||
| 6 | CAUTION: Malformed styles may cause issues. | ||
| 7 | </h4> | ||
| 8 | <label class="checkbox_label" for="global_styles_forbidden"> | ||
| 9 | <input type="radio" id="global_styles_forbidden" name="global_styles_preference" /> | ||
| 10 | <span data-i18n="Just to Creator's Notes">Just to Creator's Notes</span> | ||
| 11 | </label> | ||
| 12 | <label class="checkbox_label" for="global_styles_allowed"> | ||
| 13 | <input type="radio" id="global_styles_allowed" name="global_styles_preference" /> | ||
| 14 | <span data-i18n="Apply to the entire app">Apply to the entire app</span> | ||
| 15 | </label> | ||
| 16 | </div> | ||
| @@ -0,0 +1,6 @@ | |||
| 1 | <div class="text_block hidden_block"> | ||
| 2 | <small> | ||
| 3 | <p>{{text}}</p> | ||
| 4 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Characters and groups hidden by filters or closed folders" title="Characters and groups hidden by filters or closed folders"></div> | ||
| 5 | </small> | ||
| 6 | </div> | ||
| @@ -83,7 +83,10 @@ | |||
| 83 | <div class="tokenItemizingSubclass">{{scenarioTextTokens}}</div> | 83 | <div class="tokenItemizingSubclass">{{scenarioTextTokens}}</div> |
| 84 | </div> | 84 | </div> |
| 85 | <div class="flex-container "> | 85 | <div class="flex-container "> |
| 86 | <div class=" flex1 tokenItemizingSubclass">-- Examples:</div> | 86 | <div class=" flex1 tokenItemizingSubclass"> |
| 87 | <span>-- Examples:</span> | ||
| 88 | {{#if examplesCount}}<small>({{examplesCount}})</small>{{/if}} | ||
| 89 | </div> | ||
| 87 | <div class="tokenItemizingSubclass">{{examplesStringTokens}}</div> | 90 | <div class="tokenItemizingSubclass">{{examplesStringTokens}}</div> |
| 88 | </div> | 91 | </div> |
| 89 | <div class="flex-container "> | 92 | <div class="flex-container "> |
| @@ -96,7 +99,10 @@ | |||
| 96 | <div class="">{{worldInfoStringTokens}}</div> | 99 | <div class="">{{worldInfoStringTokens}}</div> |
| 97 | </div> | 100 | </div> |
| 98 | <div class="wide100p flex-container"> | 101 | <div class="wide100p flex-container"> |
| 99 | <div class="flex1" style="color: palegreen;"><span data-i18n="Chat History:">Chat History:</span></div> | 102 | <div class="flex1" style="color: palegreen;"> |
| 103 | <span data-i18n="Chat History:">Chat History:</span> | ||
| 104 | {{#if messagesCount}}<small>({{messagesCount}})</small>{{/if}} | ||
| 105 | </div> | ||
| 100 | <div class="">{{ActualChatHistoryTokens}}</div> | 106 | <div class="">{{ActualChatHistoryTokens}}</div> |
| 101 | </div> | 107 | </div> |
| 102 | <div class="wide100p flex-container flexNoGap flexFlowColumn"> | 108 | <div class="wide100p flex-container flexNoGap flexFlowColumn"> |
| @@ -51,7 +51,10 @@ | |||
| 51 | <div class="tokenItemizingSubclass">{{scenarioTextTokens}}</div> | 51 | <div class="tokenItemizingSubclass">{{scenarioTextTokens}}</div> |
| 52 | </div> | 52 | </div> |
| 53 | <div class="flex-container"> | 53 | <div class="flex-container"> |
| 54 | <div class=" flex1 tokenItemizingSubclass">-- Examples:</div> | 54 | <div class=" flex1 tokenItemizingSubclass"> |
| 55 | <span>-- Examples:</span> | ||
| 56 | {{#if examplesCount}}<small>({{examplesCount}})</small>{{/if}} | ||
| 57 | </div> | ||
| 55 | <div class="tokenItemizingSubclass"> {{examplesStringTokens}}</div> | 58 | <div class="tokenItemizingSubclass"> {{examplesStringTokens}}</div> |
| 56 | </div> | 59 | </div> |
| 57 | <div class="flex-container"> | 60 | <div class="flex-container"> |
| @@ -68,7 +71,10 @@ | |||
| 68 | <div class="">{{worldInfoStringTokens}}</div> | 71 | <div class="">{{worldInfoStringTokens}}</div> |
| 69 | </div> | 72 | </div> |
| 70 | <div class="wide100p flex-container"> | 73 | <div class="wide100p flex-container"> |
| 71 | <div class="flex1" style="color: palegreen;">Chat History:</div> | 74 | <div class="flex1" style="color: palegreen;"> |
| 75 | <span data-i18n="Chat History:">Chat History:</span> | ||
| 76 | {{#if messagesCount}}<small>({{messagesCount}})</small>{{/if}} | ||
| 77 | </div> | ||
| 72 | <div class=""> {{ActualChatHistoryTokens}}</div> | 78 | <div class=""> {{ActualChatHistoryTokens}}</div> |
| 73 | </div> | 79 | </div> |
| 74 | <div class="wide100p flex-container flexNoGap flexFlowColumn"> | 80 | <div class="wide100p flex-container flexNoGap flexFlowColumn"> |
| @@ -0,0 +1,82 @@ | |||
| 1 | <div class="welcomePanel"> | ||
| 2 | <div class="welcomeHeaderTitle"> | ||
| 3 | <img src="img/logo.png" alt="SillyTavern Logo" class="welcomeHeaderLogo"> | ||
| 4 | <span class="welcomeHeaderVersionDisplay">{{version}}</span> | ||
| 5 | <div class="mes_button showRecentChats" title="Show recent chats" data-i18n="[title]Show recent chats"> | ||
| 6 | <i class="fa-solid fa-circle-chevron-down fa-fw fa-lg"></i> | ||
| 7 | </div> | ||
| 8 | <div class="mes_button hideRecentChats" title="Hide recent chats" data-i18n="[title]Hide recent chats"> | ||
| 9 | <i class="fa-solid fa-circle-xmark fa-fw fa-lg"></i> | ||
| 10 | </div> | ||
| 11 | </div> | ||
| 12 | <div class="welcomeHeader"> | ||
| 13 | <div class="recentChatsTitle" data-i18n="Recent Chats"> | ||
| 14 | Recent Chats | ||
| 15 | </div> | ||
| 16 | <div class="welcomeShortcuts"> | ||
| 17 | <a class="menu_button menu_button_icon" target="_blank" href="https://docs.sillytavern.app/"> | ||
| 18 | <i class="fa-solid fa-question-circle"></i> | ||
| 19 | <span data-i18n="Docs">Docs</span> | ||
| 20 | </a> | ||
| 21 | <a class="menu_button menu_button_icon" target="_blank" href="https://github.com/SillyTavern/SillyTavern"> | ||
| 22 | <i class="fa-brands fa-github"></i> | ||
| 23 | <span data-i18n="GitHub">GitHub</span> | ||
| 24 | </a> | ||
| 25 | <a class="menu_button menu_button_icon" target="_blank" href="https://discord.gg/sillytavern"> | ||
| 26 | <i class="fa-brands fa-discord"></i> | ||
| 27 | <span data-i18n="Discord">Discord</span> | ||
| 28 | </a> | ||
| 29 | <span class="welcomeShortcutsSeparator">|</span> | ||
| 30 | <button class="openTemporaryChat menu_button menu_button_icon"> | ||
| 31 | <i class="fa-solid fa-comment-dots"></i> | ||
| 32 | <span data-i18n="Temporary Chat">Temporary Chat</span> | ||
| 33 | </button> | ||
| 34 | </div> | ||
| 35 | </div> | ||
| 36 | <div class="welcomeRecent"> | ||
| 37 | <div class="recentChatList"> | ||
| 38 | {{#if empty}} | ||
| 39 | <div class="noRecentChat"> | ||
| 40 | <i class="fa-solid fa-comment-dots"></i> | ||
| 41 | <span data-i18n="No recent chats">No recent chats</span> | ||
| 42 | </div> | ||
| 43 | {{/if}} | ||
| 44 | {{#each chats}} | ||
| 45 | {{#with this}} | ||
| 46 | <div class="recentChat {{#if hidden}}hidden{{/if}} {{#if is_group}}group{{/if}}" data-file="{{chat_name}}" data-avatar="{{avatar}}" data-group="{{group}}"> | ||
| 47 | <div class="avatar" title="[Character] {{char_name}} File: {{avatar}}"> | ||
| 48 | <img src="{{char_thumbnail}}" alt="{{char_name}}"> | ||
| 49 | </div> | ||
| 50 | <div class="recentChatInfo"> | ||
| 51 | <div class="chatNameContainer"> | ||
| 52 | <div class="chatName" title="{{file_name}}"> | ||
| 53 | <strong class="characterName">{{char_name}}</strong> | ||
| 54 | <span>–</span> | ||
| 55 | <span>{{chat_name}}</span> | ||
| 56 | </div> | ||
| 57 | <small class="chatDate" title="{{date_long}}">{{date_short}}</small> | ||
| 58 | </div> | ||
| 59 | <div class="chatMessageContainer"> | ||
| 60 | <div class="chatMessage" title="{{mes}}"> | ||
| 61 | {{mes}} | ||
| 62 | </div> | ||
| 63 | <div class="chatStats"> | ||
| 64 | <div class="counterBlock"> | ||
| 65 | <i class="fa-solid fa-comment fa-xs"></i> | ||
| 66 | <small>{{chat_items}}</small> | ||
| 67 | </div> | ||
| 68 | <small class="fileSize">{{file_size}}</small> | ||
| 69 | </div> | ||
| 70 | </div> | ||
| 71 | </div> | ||
| 72 | </div> | ||
| 73 | {{/with}} | ||
| 74 | {{/each}} | ||
| 75 | {{#if more}} | ||
| 76 | <button class="menu_button menu_button_icon showMoreChats"> | ||
| 77 | <small class="fa-solid fa-chevron-down fa-fw fa-1x"></small> | ||
| 78 | </button> | ||
| 79 | {{/if}} | ||
| 80 | </div> | ||
| 81 | </div> | ||
| 82 | </div> | ||
| @@ -1,3 +1,14 @@ | |||
| 1 | <strong data-i18n="If you're connected to an API, try asking me something!"> | 1 | <div class="flex-container"> |
| 2 | If you're connected to an API, try asking me something! | 2 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="sys-settings-button"> |
| 3 | </strong> | 3 | <i class="fa-solid fa-plug"></i> |
| 4 | <span data-i18n="API Connections">API Connections</span> | ||
| 5 | </button> | ||
| 6 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="rightNavHolder"> | ||
| 7 | <i class="fa-solid fa-address-card"></i> | ||
| 8 | <span data-i18n="Character Management">Character Management</span> | ||
| 9 | </button> | ||
| 10 | <button class="menu_button menu_button_icon drawer-opener inline-flex" data-target="extensions-settings-button"> | ||
| 11 | <i class="fa-solid fa-cubes"></i> | ||
| 12 | <span data-i18n="Extensions">Extensions</span> | ||
| 13 | </button> | ||
| 14 | </div> | ||
| @@ -7,6 +7,7 @@ import { renderTemplateAsync } from './templates.js'; | |||
| 7 | import { POPUP_TYPE, callGenericPopup } from './popup.js'; | 7 | import { POPUP_TYPE, callGenericPopup } from './popup.js'; |
| 8 | import { t } from './i18n.js'; | 8 | import { t } from './i18n.js'; |
| 9 | import { accountStorage } from './util/AccountStorage.js'; | 9 | import { accountStorage } from './util/AccountStorage.js'; |
| 10 | import { localizePagination, PAGINATION_TEMPLATE } from './utils.js'; | ||
| 10 | 11 | ||
| 11 | let mancerModels = []; | 12 | let mancerModels = []; |
| 12 | let togetherModels = []; | 13 | let togetherModels = []; |
| @@ -23,66 +24,60 @@ export let openRouterModels = []; | |||
| 23 | * @type {string[]} | 24 | * @type {string[]} |
| 24 | */ | 25 | */ |
| 25 | const OPENROUTER_PROVIDERS = [ | 26 | const OPENROUTER_PROVIDERS = [ |
| 26 | 'OpenAI', | 27 | 'AI21', |
| 27 | 'Anthropic', | 28 | 'AionLabs', |
| 28 | 'Google', | 29 | 'Alibaba', |
| 29 | 'Google AI Studio', | ||
| 30 | 'Amazon Bedrock', | 30 | 'Amazon Bedrock', |
| 31 | 'Groq', | 31 | 'Anthropic', |
| 32 | 'SambaNova', | 32 | 'Atoma', |
| 33 | 'Cohere', | ||
| 34 | 'Mistral', | ||
| 35 | 'Together', | ||
| 36 | 'Together 2', | ||
| 37 | 'Fireworks', | ||
| 38 | 'DeepInfra', | ||
| 39 | 'Lepton', | ||
| 40 | 'Novita', | ||
| 41 | 'Avian', | 33 | 'Avian', |
| 42 | 'Lambda', | ||
| 43 | 'Azure', | 34 | 'Azure', |
| 44 | 'Modal', | 35 | 'Cent-ML', |
| 45 | 'AnyScale', | 36 | 'Cerebras', |
| 46 | 'Replicate', | 37 | 'Chutes', |
| 47 | 'Perplexity', | 38 | 'Cloudflare', |
| 48 | 'Recursal', | 39 | 'Cohere', |
| 49 | 'OctoAI', | 40 | 'Crusoe', |
| 41 | 'DeepInfra', | ||
| 50 | 'DeepSeek', | 42 | 'DeepSeek', |
| 51 | 'Infermatic', | 43 | 'Enfer', |
| 52 | 'AI21', | ||
| 53 | 'Featherless', | 44 | 'Featherless', |
| 45 | 'Fireworks', | ||
| 46 | 'Friendli', | ||
| 47 | 'GMICloud', | ||
| 48 | 'Google', | ||
| 49 | 'Google AI Studio', | ||
| 50 | 'Groq', | ||
| 51 | 'Hyperbolic', | ||
| 52 | 'Inception', | ||
| 53 | 'InferenceNet', | ||
| 54 | 'Infermatic', | ||
| 54 | 'Inflection', | 55 | 'Inflection', |
| 55 | 'xAI', | 56 | 'InoCloud', |
| 56 | 'Cloudflare', | 57 | 'Kluster', |
| 57 | 'SF Compute', | 58 | 'Lambda', |
| 58 | 'Minimax', | ||
| 59 | 'Nineteen', | ||
| 60 | 'Liquid', | 59 | 'Liquid', |
| 61 | 'Stealth', | 60 | 'Mancer', |
| 61 | 'Mancer 2', | ||
| 62 | 'Minimax', | ||
| 63 | 'Mistral', | ||
| 62 | 'NCompass', | 64 | 'NCompass', |
| 63 | 'InferenceNet', | ||
| 64 | 'Friendli', | ||
| 65 | 'AionLabs', | ||
| 66 | 'Alibaba', | ||
| 67 | 'Nebius', | 65 | 'Nebius', |
| 68 | 'Chutes', | 66 | 'NextBit', |
| 69 | 'Kluster', | 67 | 'Nineteen', |
| 70 | 'Crusoe', | 68 | 'Novita', |
| 71 | 'Targon', | 69 | 'OpenAI', |
| 72 | 'Ubicloud', | 70 | 'OpenInference', |
| 73 | 'Parasail', | 71 | 'Parasail', |
| 72 | 'Perplexity', | ||
| 74 | 'Phala', | 73 | 'Phala', |
| 75 | 'Cent-ML', | 74 | 'SambaNova', |
| 75 | 'Stealth', | ||
| 76 | 'Targon', | ||
| 77 | 'Together', | ||
| 78 | 'Ubicloud', | ||
| 76 | 'Venice', | 79 | 'Venice', |
| 77 | '01.AI', | 80 | 'xAI', |
| 78 | 'HuggingFace', | ||
| 79 | 'Mancer', | ||
| 80 | 'Mancer 2', | ||
| 81 | 'Hyperbolic', | ||
| 82 | 'Hyperbolic 2', | ||
| 83 | 'Lynn 2', | ||
| 84 | 'Lynn', | ||
| 85 | 'Reflection', | ||
| 86 | ]; | 81 | ]; |
| 87 | 82 | ||
| 88 | export async function loadOllamaModels(data) { | 83 | export async function loadOllamaModels(data) { |
| @@ -367,9 +362,7 @@ export async function loadFeatherlessModels(data) { | |||
| 367 | showSizeChanger: false, | 362 | showSizeChanger: false, |
| 368 | prevText: '<', | 363 | prevText: '<', |
| 369 | nextText: '>', | 364 | nextText: '>', |
| 370 | formatNavigator: function (currentPage, totalPage) { | 365 | formatNavigator: PAGINATION_TEMPLATE, |
| 371 | return (currentPage - 1) * perPage + 1 + ' - ' + currentPage * perPage + ' of ' + totalPage * perPage; | ||
| 372 | }, | ||
| 373 | showNavigator: true, | 366 | showNavigator: true, |
| 374 | callback: function (modelsOnPage, pagination) { | 367 | callback: function (modelsOnPage, pagination) { |
| 375 | modelCardBlock.innerHTML = ''; | 368 | modelCardBlock.innerHTML = ''; |
| @@ -391,15 +384,15 @@ export async function loadFeatherlessModels(data) { | |||
| 391 | 384 | ||
| 392 | const modelClassDiv = document.createElement('div'); | 385 | const modelClassDiv = document.createElement('div'); |
| 393 | modelClassDiv.classList.add('model-class'); | 386 | modelClassDiv.classList.add('model-class'); |
| 394 | modelClassDiv.textContent = `Class: ${model.model_class || 'N/A'}`; | 387 | modelClassDiv.textContent = t`Class` + `: ${model.model_class || 'N/A'}`; |
| 395 | 388 | ||
| 396 | const contextLengthDiv = document.createElement('div'); | 389 | const contextLengthDiv = document.createElement('div'); |
| 397 | contextLengthDiv.classList.add('model-context-length'); | 390 | contextLengthDiv.classList.add('model-context-length'); |
| 398 | contextLengthDiv.textContent = `Context Length: ${model.context_length}`; | 391 | contextLengthDiv.textContent = t`Context Length` + `: ${model.context_length}`; |
| 399 | 392 | ||
| 400 | const dateAddedDiv = document.createElement('div'); | 393 | const dateAddedDiv = document.createElement('div'); |
| 401 | dateAddedDiv.classList.add('model-date-added'); | 394 | dateAddedDiv.classList.add('model-date-added'); |
| 402 | dateAddedDiv.textContent = `Added On: ${new Date(model.created * 1000).toLocaleDateString()}`; | 395 | dateAddedDiv.textContent = t`Added On` + `: ${new Date(model.created * 1000).toLocaleDateString()}`; |
| 403 | 396 | ||
| 404 | detailsContainer.appendChild(modelClassDiv); | 397 | detailsContainer.appendChild(modelClassDiv); |
| 405 | detailsContainer.appendChild(contextLengthDiv); | 398 | detailsContainer.appendChild(contextLengthDiv); |
| @@ -423,6 +416,7 @@ export async function loadFeatherlessModels(data) { | |||
| 423 | 416 | ||
| 424 | // Update the current page value whenever the page changes | 417 | // Update the current page value whenever the page changes |
| 425 | featherlessCurrentPage = pagination.pageNumber; | 418 | featherlessCurrentPage = pagination.pageNumber; |
| 419 | localizePagination(paginationContainer); | ||
| 426 | }, | 420 | }, |
| 427 | afterSizeSelectorChange: function (e) { | 421 | afterSizeSelectorChange: function (e) { |
| 428 | const newPerPage = e.target.value; | 422 | const newPerPage = e.target.value; |
| @@ -56,10 +56,11 @@ const { | |||
| 56 | } = textgen_types; | 56 | } = textgen_types; |
| 57 | 57 | ||
| 58 | const LLAMACPP_DEFAULT_ORDER = [ | 58 | const LLAMACPP_DEFAULT_ORDER = [ |
| 59 | 'penalties', | ||
| 59 | 'dry', | 60 | 'dry', |
| 61 | 'top_n_sigma', | ||
| 60 | 'top_k', | 62 | 'top_k', |
| 61 | 'tfs_z', | 63 | 'typ_p', |
| 62 | 'typical_p', | ||
| 63 | 'top_p', | 64 | 'top_p', |
| 64 | 'min_p', | 65 | 'min_p', |
| 65 | 'xtc', | 66 | 'xtc', |
| @@ -212,6 +213,7 @@ const settings = { | |||
| 212 | xtc_threshold: 0.1, | 213 | xtc_threshold: 0.1, |
| 213 | xtc_probability: 0, | 214 | xtc_probability: 0, |
| 214 | nsigma: 0.0, | 215 | nsigma: 0.0, |
| 216 | min_keep: 0, | ||
| 215 | featherless_model: '', | 217 | featherless_model: '', |
| 216 | generic_model: '', | 218 | generic_model: '', |
| 217 | }; | 219 | }; |
| @@ -294,6 +296,7 @@ export const setting_names = [ | |||
| 294 | 'xtc_threshold', | 296 | 'xtc_threshold', |
| 295 | 'xtc_probability', | 297 | 'xtc_probability', |
| 296 | 'nsigma', | 298 | 'nsigma', |
| 299 | 'min_keep', | ||
| 297 | 'generic_model', | 300 | 'generic_model', |
| 298 | ]; | 301 | ]; |
| 299 | 302 | ||
| @@ -804,6 +807,7 @@ jQuery(function () { | |||
| 804 | 'xtc_threshold_textgenerationwebui': 0.1, | 807 | 'xtc_threshold_textgenerationwebui': 0.1, |
| 805 | 'xtc_probability_textgenerationwebui': 0, | 808 | 'xtc_probability_textgenerationwebui': 0, |
| 806 | 'nsigma_textgenerationwebui': 0, | 809 | 'nsigma_textgenerationwebui': 0, |
| 810 | 'min_keep_textgenerationwebui': 0, | ||
| 807 | }; | 811 | }; |
| 808 | 812 | ||
| 809 | for (const [id, value] of Object.entries(inputs)) { | 813 | for (const [id, value] of Object.entries(inputs)) { |
| @@ -1146,7 +1150,7 @@ function tryParseStreamingError(response, decoded) { | |||
| 1146 | // No JSON. Do nothing. | 1150 | // No JSON. Do nothing. |
| 1147 | } | 1151 | } |
| 1148 | 1152 | ||
| 1149 | const message = data?.error?.message || data?.message || data?.detail; | 1153 | const message = data?.error?.message || data?.error || data?.message || data?.detail; |
| 1150 | 1154 | ||
| 1151 | if (message) { | 1155 | if (message) { |
| 1152 | toastr.error(message, 'Text Completion API'); | 1156 | toastr.error(message, 'Text Completion API'); |
| @@ -1332,6 +1336,18 @@ export async function getTextGenGenerationData(finalPrompt, maxTokens, isImperso | |||
| 1332 | 'xtc_threshold': settings.xtc_threshold, | 1336 | 'xtc_threshold': settings.xtc_threshold, |
| 1333 | 'xtc_probability': settings.xtc_probability, | 1337 | 'xtc_probability': settings.xtc_probability, |
| 1334 | 'nsigma': settings.nsigma, | 1338 | 'nsigma': settings.nsigma, |
| 1339 | 'top_n_sigma': settings.nsigma, | ||
| 1340 | 'min_keep': settings.min_keep, | ||
| 1341 | parseSequenceBreakers: function () { | ||
| 1342 | try { | ||
| 1343 | return JSON.parse(this.dry_sequence_breakers); | ||
| 1344 | } catch { | ||
| 1345 | if (typeof this.dry_sequence_breakers === 'string') { | ||
| 1346 | return this.dry_sequence_breakers.split(','); | ||
| 1347 | } | ||
| 1348 | return undefined; | ||
| 1349 | } | ||
| 1350 | }, | ||
| 1335 | }; | 1351 | }; |
| 1336 | const nonAphroditeParams = { | 1352 | const nonAphroditeParams = { |
| 1337 | 'rep_pen': settings.rep_pen, | 1353 | 'rep_pen': settings.rep_pen, |
| @@ -1351,7 +1367,6 @@ export async function getTextGenGenerationData(finalPrompt, maxTokens, isImperso | |||
| 1351 | 'json_schema': [TABBY, LLAMACPP].includes(settings.type) ? settings.json_schema : undefined, | 1367 | 'json_schema': [TABBY, LLAMACPP].includes(settings.type) ? settings.json_schema : undefined, |
| 1352 | // llama.cpp aliases. In case someone wants to use LM Studio as Text Completion API | 1368 | // llama.cpp aliases. In case someone wants to use LM Studio as Text Completion API |
| 1353 | 'repeat_penalty': settings.rep_pen, | 1369 | 'repeat_penalty': settings.rep_pen, |
| 1354 | 'tfs_z': settings.tfs, | ||
| 1355 | 'repeat_last_n': settings.rep_pen_range, | 1370 | 'repeat_last_n': settings.rep_pen_range, |
| 1356 | 'n_predict': maxTokens, | 1371 | 'n_predict': maxTokens, |
| 1357 | 'num_predict': maxTokens, | 1372 | 'num_predict': maxTokens, |
| @@ -1434,6 +1449,7 @@ export async function getTextGenGenerationData(finalPrompt, maxTokens, isImperso | |||
| 1434 | params.dynatemp_max = params.dynatemp_high; | 1449 | params.dynatemp_max = params.dynatemp_high; |
| 1435 | delete params.dynatemp_low; | 1450 | delete params.dynatemp_low; |
| 1436 | delete params.dynatemp_high; | 1451 | delete params.dynatemp_high; |
| 1452 | params.dry_sequence_breakers = params.parseSequenceBreakers(); | ||
| 1437 | } | 1453 | } |
| 1438 | 1454 | ||
| 1439 | if (settings.type === TABBY) { | 1455 | if (settings.type === TABBY) { |
| @@ -1469,17 +1485,7 @@ export async function getTextGenGenerationData(finalPrompt, maxTokens, isImperso | |||
| 1469 | : []; | 1485 | : []; |
| 1470 | const tokenBans = toIntArray(banned_tokens); | 1486 | const tokenBans = toIntArray(banned_tokens); |
| 1471 | logitBiasArray.push(...tokenBans.map(x => [Number(x), false])); | 1487 | logitBiasArray.push(...tokenBans.map(x => [Number(x), false])); |
| 1472 | const sequenceBreakers = (() => { | 1488 | const sequenceBreakers = params.parseSequenceBreakers(); |
| 1473 | try { | ||
| 1474 | return JSON.parse(params.dry_sequence_breakers); | ||
| 1475 | } catch { | ||
| 1476 | if (typeof params.dry_sequence_breakers === 'string') { | ||
| 1477 | return params.dry_sequence_breakers.split(','); | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | return undefined; | ||
| 1481 | } | ||
| 1482 | })(); | ||
| 1483 | const llamaCppParams = { | 1489 | const llamaCppParams = { |
| 1484 | 'logit_bias': logitBiasArray, | 1490 | 'logit_bias': logitBiasArray, |
| 1485 | // Conflicts with ooba's grammar_string | 1491 | // Conflicts with ooba's grammar_string |
| @@ -676,6 +676,10 @@ export function getTokenizerModel() { | |||
| 676 | return gemmaTokenizer; | 676 | return gemmaTokenizer; |
| 677 | } | 677 | } |
| 678 | 678 | ||
| 679 | if (oai_settings.chat_completion_source == chat_completion_sources.VERTEXAI) { | ||
| 680 | return gemmaTokenizer; | ||
| 681 | } | ||
| 682 | |||
| 679 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { | 683 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { |
| 680 | return jambaTokenizer; | 684 | return jambaTokenizer; |
| 681 | } | 685 | } |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | 1 | import { DOMPurify } from '../lib.js'; |
| 2 | 2 | ||
| 3 | import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; | 3 | import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; |
| 4 | import { chat_completion_sources, oai_settings } from './openai.js'; | 4 | import { chat_completion_sources, model_list, oai_settings } from './openai.js'; |
| 5 | import { Popup } from './popup.js'; | 5 | import { Popup } from './popup.js'; |
| 6 | import { SlashCommand } from './slash-commands/SlashCommand.js'; | 6 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 7 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; | 7 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| @@ -575,6 +575,18 @@ export class ToolManager { | |||
| 575 | return false; | 575 | return false; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | // Post-processing will forcefully remove past tool calls from the prompt, making them useless | ||
| 579 | if (oai_settings.custom_prompt_post_processing) { | ||
| 580 | return false; | ||
| 581 | } | ||
| 582 | |||
| 583 | if (oai_settings.chat_completion_source === chat_completion_sources.POLLINATIONS && Array.isArray(model_list)) { | ||
| 584 | const currentModel = model_list.find(model => model.id === oai_settings.pollinations_model); | ||
| 585 | if (currentModel) { | ||
| 586 | return currentModel.tools; | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 578 | const supportedSources = [ | 590 | const supportedSources = [ |
| 579 | chat_completion_sources.OPENAI, | 591 | chat_completion_sources.OPENAI, |
| 580 | chat_completion_sources.CUSTOM, | 592 | chat_completion_sources.CUSTOM, |
| @@ -585,8 +597,10 @@ export class ToolManager { | |||
| 585 | chat_completion_sources.COHERE, | 597 | chat_completion_sources.COHERE, |
| 586 | chat_completion_sources.DEEPSEEK, | 598 | chat_completion_sources.DEEPSEEK, |
| 587 | chat_completion_sources.MAKERSUITE, | 599 | chat_completion_sources.MAKERSUITE, |
| 600 | chat_completion_sources.VERTEXAI, | ||
| 588 | chat_completion_sources.AI21, | 601 | chat_completion_sources.AI21, |
| 589 | chat_completion_sources.XAI, | 602 | chat_completion_sources.XAI, |
| 603 | chat_completion_sources.POLLINATIONS, | ||
| 590 | ]; | 604 | ]; |
| 591 | return supportedSources.includes(oai_settings.chat_completion_source); | 605 | return supportedSources.includes(oai_settings.chat_completion_source); |
| 592 | } | 606 | } |
| @@ -903,7 +903,7 @@ async function slugify(text) { | |||
| 903 | async function extendUserSession() { | 903 | async function extendUserSession() { |
| 904 | try { | 904 | try { |
| 905 | const response = await fetch('/api/ping?extend=1', { | 905 | const response = await fetch('/api/ping?extend=1', { |
| 906 | method: 'GET', | 906 | method: 'POST', |
| 907 | headers: getRequestHeaders(), | 907 | headers: getRequestHeaders(), |
| 908 | }); | 908 | }); |
| 909 | 909 | ||
| @@ -20,7 +20,46 @@ import { getCurrentLocale, t } from './i18n.js'; | |||
| 20 | * Pagination status string template. | 20 | * Pagination status string template. |
| 21 | * @type {string} | 21 | * @type {string} |
| 22 | */ | 22 | */ |
| 23 | export const PAGINATION_TEMPLATE = '<%= rangeStart %>-<%= rangeEnd %> of <%= totalNumber %>'; | 23 | export const PAGINATION_TEMPLATE = '<%= rangeStart %>-<%= rangeEnd %> .. <%= totalNumber %>'; |
| 24 | |||
| 25 | export const localizePagination = function(container) { | ||
| 26 | container.find('[title="Next page"]').attr('title', t`Next page`); | ||
| 27 | container.find('[title="Previous page"]').attr('title', t`Previous page`); | ||
| 28 | }; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Renders a dropdown for selecting page size in pagination. | ||
| 32 | * @param {number} pageSize Page size | ||
| 33 | * @param {number[]} sizeChangerOptions Array of page size options | ||
| 34 | * @returns {string} The rendered dropdown element as a string | ||
| 35 | */ | ||
| 36 | export const renderPaginationDropdown = function(pageSize, sizeChangerOptions) { | ||
| 37 | const sizeSelect = document.createElement('select'); | ||
| 38 | sizeSelect.classList.add('J-paginationjs-size-select'); | ||
| 39 | |||
| 40 | if (sizeChangerOptions.indexOf(pageSize) === -1) { | ||
| 41 | sizeChangerOptions.unshift(pageSize); | ||
| 42 | sizeChangerOptions.sort((a, b) => a - b); | ||
| 43 | } | ||
| 44 | |||
| 45 | for (let i = 0; i < sizeChangerOptions.length; i++) { | ||
| 46 | const option = document.createElement('option'); | ||
| 47 | option.value = `${sizeChangerOptions[i]}`; | ||
| 48 | option.textContent = `${sizeChangerOptions[i]} ${t`/ page`}`; | ||
| 49 | if (sizeChangerOptions[i] === pageSize) { | ||
| 50 | option.setAttribute('selected', 'selected'); | ||
| 51 | } | ||
| 52 | sizeSelect.appendChild(option); | ||
| 53 | } | ||
| 54 | |||
| 55 | return sizeSelect.outerHTML; | ||
| 56 | }; | ||
| 57 | |||
| 58 | export const paginationDropdownChangeHandler = function(event, size) { | ||
| 59 | let dropdown = $(event?.originalEvent?.currentTarget || event.delegateTarget).find('select'); | ||
| 60 | dropdown.find('[selected]').removeAttr('selected'); | ||
| 61 | dropdown.find(`[value=${size}]`).attr('selected', ''); | ||
| 62 | }; | ||
| 24 | 63 | ||
| 25 | /** | 64 | /** |
| 26 | * Navigation options for pagination. | 65 | * Navigation options for pagination. |
| @@ -1047,7 +1086,7 @@ export function getImageSizeFromDataURL(dataUrl) { | |||
| 1047 | 1086 | ||
| 1048 | /** | 1087 | /** |
| 1049 | * Gets the filename of the character avatar without extension | 1088 | * Gets the filename of the character avatar without extension |
| 1050 | * @param {number?} [chid=null] - Character ID. If not provided, uses the current character ID | 1089 | * @param {string|number?} [chid=null] - Character ID. If not provided, uses the current character ID |
| 1051 | * @param {object} [options={}] - Options arguments | 1090 | * @param {object} [options={}] - Options arguments |
| 1052 | * @param {string?} [options.manualAvatarKey=null] - Manually take the following avatar key, instead of using the chid to determine the name | 1091 | * @param {string?} [options.manualAvatarKey=null] - Manually take the following avatar key, instead of using the chid to determine the name |
| 1053 | * @returns {string?} The filename of the character avatar without extension, or null if the character ID is invalid | 1092 | * @returns {string?} The filename of the character avatar without extension, or null if the character ID is invalid |
| @@ -0,0 +1,423 @@ | |||
| 1 | import { | ||
| 2 | addOneMessage, | ||
| 3 | characters, | ||
| 4 | chat, | ||
| 5 | displayVersion, | ||
| 6 | doNewChat, | ||
| 7 | event_types, | ||
| 8 | eventSource, | ||
| 9 | getCharacters, | ||
| 10 | getCurrentChatId, | ||
| 11 | getRequestHeaders, | ||
| 12 | getSystemMessageByType, | ||
| 13 | getThumbnailUrl, | ||
| 14 | is_send_press, | ||
| 15 | neutralCharacterName, | ||
| 16 | newAssistantChat, | ||
| 17 | openCharacterChat, | ||
| 18 | printCharactersDebounced, | ||
| 19 | selectCharacterById, | ||
| 20 | system_avatar, | ||
| 21 | system_message_types, | ||
| 22 | this_chid, | ||
| 23 | } from '../script.js'; | ||
| 24 | import { getGroupAvatar, groups, is_group_generating, openGroupById, openGroupChat } from './group-chats.js'; | ||
| 25 | import { t } from './i18n.js'; | ||
| 26 | import { renderTemplateAsync } from './templates.js'; | ||
| 27 | import { accountStorage } from './util/AccountStorage.js'; | ||
| 28 | import { sortMoments, timestampToMoment } from './utils.js'; | ||
| 29 | |||
| 30 | const assistantAvatarKey = 'assistant'; | ||
| 31 | const defaultAssistantAvatar = 'default_Assistant.png'; | ||
| 32 | |||
| 33 | const DEFAULT_DISPLAYED = 3; | ||
| 34 | const MAX_DISPLAYED = 15; | ||
| 35 | |||
| 36 | export function getPermanentAssistantAvatar() { | ||
| 37 | const assistantAvatar = accountStorage.getItem(assistantAvatarKey); | ||
| 38 | if (assistantAvatar === null) { | ||
| 39 | return defaultAssistantAvatar; | ||
| 40 | } | ||
| 41 | |||
| 42 | const character = characters.find(x => x.avatar === assistantAvatar); | ||
| 43 | if (character === undefined) { | ||
| 44 | accountStorage.removeItem(assistantAvatarKey); | ||
| 45 | return defaultAssistantAvatar; | ||
| 46 | } | ||
| 47 | |||
| 48 | return assistantAvatar; | ||
| 49 | } | ||
| 50 | |||
| 51 | export async function openWelcomeScreen() { | ||
| 52 | const currentChatId = getCurrentChatId(); | ||
| 53 | if (currentChatId !== undefined || chat.length > 0) { | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | |||
| 57 | const recentChats = await getRecentChats(); | ||
| 58 | const chatAfterFetch = getCurrentChatId(); | ||
| 59 | if (chatAfterFetch !== currentChatId) { | ||
| 60 | console.debug('Chat changed while fetching recent chats.'); | ||
| 61 | return; | ||
| 62 | } | ||
| 63 | |||
| 64 | await sendWelcomePanel(recentChats); | ||
| 65 | sendAssistantMessage(); | ||
| 66 | sendWelcomePrompt(); | ||
| 67 | } | ||
| 68 | |||
| 69 | function sendAssistantMessage() { | ||
| 70 | const currentAssistantAvatar = getPermanentAssistantAvatar(); | ||
| 71 | const character = characters.find(x => x.avatar === currentAssistantAvatar); | ||
| 72 | const name = character ? character.name : neutralCharacterName; | ||
| 73 | const avatar = character ? getThumbnailUrl('avatar', character.avatar) : system_avatar; | ||
| 74 | |||
| 75 | const message = { | ||
| 76 | name: name, | ||
| 77 | force_avatar: avatar, | ||
| 78 | mes: t`If you're connected to an API, try asking me something!` + '\n***\n' + t`**Hint:** Set any character as your welcome page assistant from their "More..." menu.`, | ||
| 79 | is_system: false, | ||
| 80 | is_user: false, | ||
| 81 | extra: { | ||
| 82 | type: system_message_types.ASSISTANT_MESSAGE, | ||
| 83 | }, | ||
| 84 | }; | ||
| 85 | |||
| 86 | chat.push(message); | ||
| 87 | addOneMessage(message, { scroll: false }); | ||
| 88 | } | ||
| 89 | |||
| 90 | function sendWelcomePrompt() { | ||
| 91 | const message = getSystemMessageByType(system_message_types.WELCOME_PROMPT); | ||
| 92 | chat.push(message); | ||
| 93 | addOneMessage(message, { scroll: false }); | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Sends the welcome panel to the chat. | ||
| 98 | * @param {RecentChat[]} chats List of recent chats | ||
| 99 | */ | ||
| 100 | async function sendWelcomePanel(chats) { | ||
| 101 | try { | ||
| 102 | const chatElement = document.getElementById('chat'); | ||
| 103 | const sendTextArea = document.getElementById('send_textarea'); | ||
| 104 | if (!chatElement) { | ||
| 105 | console.error('Chat element not found'); | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | const templateData = { | ||
| 109 | chats, | ||
| 110 | empty: !chats.length, | ||
| 111 | version: displayVersion, | ||
| 112 | more: chats.some(chat => chat.hidden), | ||
| 113 | }; | ||
| 114 | const template = await renderTemplateAsync('welcomePanel', templateData); | ||
| 115 | const fragment = document.createRange().createContextualFragment(template); | ||
| 116 | fragment.querySelectorAll('.welcomePanel').forEach((root) => { | ||
| 117 | const recentHiddenClass = 'recentHidden'; | ||
| 118 | const recentHiddenKey = 'WelcomePage_RecentChatsHidden'; | ||
| 119 | if (accountStorage.getItem(recentHiddenKey) === 'true') { | ||
| 120 | root.classList.add(recentHiddenClass); | ||
| 121 | } | ||
| 122 | root.querySelectorAll('.showRecentChats').forEach((button) => { | ||
| 123 | button.addEventListener('click', () => { | ||
| 124 | root.classList.remove(recentHiddenClass); | ||
| 125 | accountStorage.setItem(recentHiddenKey, 'false'); | ||
| 126 | }); | ||
| 127 | }); | ||
| 128 | root.querySelectorAll('.hideRecentChats').forEach((button) => { | ||
| 129 | button.addEventListener('click', () => { | ||
| 130 | root.classList.add(recentHiddenClass); | ||
| 131 | accountStorage.setItem(recentHiddenKey, 'true'); | ||
| 132 | }); | ||
| 133 | }); | ||
| 134 | }); | ||
| 135 | fragment.querySelectorAll('.recentChat').forEach((item) => { | ||
| 136 | item.addEventListener('click', () => { | ||
| 137 | const avatarId = item.getAttribute('data-avatar'); | ||
| 138 | const groupId = item.getAttribute('data-group'); | ||
| 139 | const fileName = item.getAttribute('data-file'); | ||
| 140 | if (avatarId && fileName) { | ||
| 141 | void openRecentCharacterChat(avatarId, fileName); | ||
| 142 | } | ||
| 143 | if (groupId && fileName) { | ||
| 144 | void openRecentGroupChat(groupId, fileName); | ||
| 145 | } | ||
| 146 | }); | ||
| 147 | }); | ||
| 148 | const hiddenChats = fragment.querySelectorAll('.recentChat.hidden'); | ||
| 149 | fragment.querySelectorAll('button.showMoreChats').forEach((button) => { | ||
| 150 | const showRecentChatsTitle = t`Show more recent chats`; | ||
| 151 | const hideRecentChatsTitle = t`Show less recent chats`; | ||
| 152 | |||
| 153 | button.setAttribute('title', showRecentChatsTitle); | ||
| 154 | button.addEventListener('click', () => { | ||
| 155 | const rotate = button.classList.contains('rotated'); | ||
| 156 | hiddenChats.forEach((chatItem) => { | ||
| 157 | chatItem.classList.toggle('hidden', rotate); | ||
| 158 | }); | ||
| 159 | button.classList.toggle('rotated', !rotate); | ||
| 160 | button.setAttribute('title', rotate ? showRecentChatsTitle : hideRecentChatsTitle); | ||
| 161 | }); | ||
| 162 | }); | ||
| 163 | fragment.querySelectorAll('button.openTemporaryChat').forEach((button) => { | ||
| 164 | button.addEventListener('click', async () => { | ||
| 165 | await newAssistantChat({ temporary: true }); | ||
| 166 | if (sendTextArea instanceof HTMLTextAreaElement) { | ||
| 167 | sendTextArea.focus(); | ||
| 168 | } | ||
| 169 | }); | ||
| 170 | }); | ||
| 171 | fragment.querySelectorAll('.recentChat.group').forEach((groupChat) => { | ||
| 172 | const groupId = groupChat.getAttribute('data-group'); | ||
| 173 | const group = groups.find(x => x.id === groupId); | ||
| 174 | if (group) { | ||
| 175 | const avatar = groupChat.querySelector('.avatar'); | ||
| 176 | if (!avatar) { | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | const groupAvatar = getGroupAvatar(group); | ||
| 180 | $(avatar).replaceWith(groupAvatar); | ||
| 181 | } | ||
| 182 | }); | ||
| 183 | chatElement.append(fragment.firstChild); | ||
| 184 | } catch (error) { | ||
| 185 | console.error('Welcome screen error:', error); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Opens a recent character chat. | ||
| 191 | * @param {string} avatarId Avatar file name | ||
| 192 | * @param {string} fileName Chat file name | ||
| 193 | */ | ||
| 194 | async function openRecentCharacterChat(avatarId, fileName) { | ||
| 195 | const characterId = characters.findIndex(x => x.avatar === avatarId); | ||
| 196 | if (characterId === -1) { | ||
| 197 | console.error(`Character not found for avatar ID: ${avatarId}`); | ||
| 198 | return; | ||
| 199 | } | ||
| 200 | |||
| 201 | try { | ||
| 202 | await selectCharacterById(characterId); | ||
| 203 | const currentChatId = getCurrentChatId(); | ||
| 204 | if (currentChatId === fileName) { | ||
| 205 | console.debug(`Chat ${fileName} is already open.`); | ||
| 206 | return; | ||
| 207 | } | ||
| 208 | await openCharacterChat(fileName); | ||
| 209 | } catch (error) { | ||
| 210 | console.error('Error opening recent chat:', error); | ||
| 211 | toastr.error(t`Failed to open recent chat. See console for details.`); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | /** | ||
| 216 | * Opens a recent group chat. | ||
| 217 | * @param {string} groupId Group ID | ||
| 218 | * @param {string} fileName Chat file name | ||
| 219 | */ | ||
| 220 | async function openRecentGroupChat(groupId, fileName) { | ||
| 221 | const group = groups.find(x => x.id === groupId); | ||
| 222 | if (!group) { | ||
| 223 | console.error(`Group not found for ID: ${groupId}`); | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | |||
| 227 | try { | ||
| 228 | await openGroupById(groupId); | ||
| 229 | const currentChatId = getCurrentChatId(); | ||
| 230 | if (currentChatId === fileName) { | ||
| 231 | console.debug(`Chat ${fileName} is already open.`); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | await openGroupChat(groupId, fileName); | ||
| 235 | } catch (error) { | ||
| 236 | console.error('Error opening recent group chat:', error); | ||
| 237 | toastr.error(t`Failed to open recent group chat. See console for details.`); | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | /** | ||
| 242 | * Gets the list of recent chats from the server. | ||
| 243 | * @returns {Promise<RecentChat[]>} List of recent chats | ||
| 244 | * | ||
| 245 | * @typedef {object} RecentChat | ||
| 246 | * @property {string} file_name Name of the chat file | ||
| 247 | * @property {string} chat_name Name of the chat (without extension) | ||
| 248 | * @property {string} file_size Size of the chat file | ||
| 249 | * @property {number} chat_items Number of items in the chat | ||
| 250 | * @property {string} mes Last message content | ||
| 251 | * @property {string} last_mes Timestamp of the last message | ||
| 252 | * @property {string} avatar Avatar URL | ||
| 253 | * @property {string} char_thumbnail Thumbnail URL | ||
| 254 | * @property {string} char_name Character or group name | ||
| 255 | * @property {string} date_short Date in short format | ||
| 256 | * @property {string} date_long Date in long format | ||
| 257 | * @property {string} group Group ID (if applicable) | ||
| 258 | * @property {boolean} is_group Indicates if the chat is a group chat | ||
| 259 | * @property {boolean} hidden Chat will be hidden by default | ||
| 260 | */ | ||
| 261 | async function getRecentChats() { | ||
| 262 | const response = await fetch('/api/chats/recent', { | ||
| 263 | method: 'POST', | ||
| 264 | headers: getRequestHeaders(), | ||
| 265 | body: JSON.stringify({ max: MAX_DISPLAYED }), | ||
| 266 | }); | ||
| 267 | |||
| 268 | if (!response.ok) { | ||
| 269 | console.warn('Failed to fetch recent character chats'); | ||
| 270 | return []; | ||
| 271 | } | ||
| 272 | |||
| 273 | /** @type {RecentChat[]} */ | ||
| 274 | const data = await response.json(); | ||
| 275 | |||
| 276 | data.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes))) | ||
| 277 | .map(chat => ({ chat, character: characters.find(x => x.avatar === chat.avatar), group: groups.find(x => x.id === chat.group) })) | ||
| 278 | .filter(t => t.character || t.group) | ||
| 279 | .forEach(({ chat, character, group }, index) => { | ||
| 280 | const chatTimestamp = timestampToMoment(chat.last_mes); | ||
| 281 | chat.char_name = character?.name || group?.name || ''; | ||
| 282 | chat.date_short = chatTimestamp.format('l'); | ||
| 283 | chat.date_long = chatTimestamp.format('LL LT'); | ||
| 284 | chat.chat_name = chat.file_name.replace('.jsonl', ''); | ||
| 285 | chat.char_thumbnail = character ? getThumbnailUrl('avatar', character.avatar) : system_avatar; | ||
| 286 | chat.is_group = !!group; | ||
| 287 | chat.hidden = index >= DEFAULT_DISPLAYED; | ||
| 288 | chat.avatar = chat.avatar || ''; | ||
| 289 | chat.group = chat.group || ''; | ||
| 290 | }); | ||
| 291 | |||
| 292 | return data; | ||
| 293 | } | ||
| 294 | |||
| 295 | export async function openPermanentAssistantChat({ tryCreate = true, created = false } = {}) { | ||
| 296 | const avatar = getPermanentAssistantAvatar(); | ||
| 297 | const characterId = characters.findIndex(x => x.avatar === avatar); | ||
| 298 | if (characterId === -1) { | ||
| 299 | if (!tryCreate) { | ||
| 300 | console.error(`Character not found for avatar ID: ${avatar}. Cannot create.`); | ||
| 301 | return; | ||
| 302 | } | ||
| 303 | |||
| 304 | try { | ||
| 305 | console.log(`Character not found for avatar ID: ${avatar}. Creating new assistant.`); | ||
| 306 | await createPermanentAssistant(); | ||
| 307 | return openPermanentAssistantChat({ tryCreate: false, created: true }); | ||
| 308 | } | ||
| 309 | catch (error) { | ||
| 310 | console.error('Error creating permanent assistant:', error); | ||
| 311 | toastr.error(t`Failed to create ${neutralCharacterName}. See console for details.`); | ||
| 312 | return; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | try { | ||
| 317 | await selectCharacterById(characterId); | ||
| 318 | if (!created) { | ||
| 319 | await doNewChat({ deleteCurrentChat: false }); | ||
| 320 | } | ||
| 321 | console.log(`Opened permanent assistant chat for ${neutralCharacterName}.`, getCurrentChatId()); | ||
| 322 | } catch (error) { | ||
| 323 | console.error('Error opening permanent assistant chat:', error); | ||
| 324 | toastr.error(t`Failed to open permanent assistant chat. See console for details.`); | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | async function createPermanentAssistant() { | ||
| 329 | if (is_group_generating || is_send_press) { | ||
| 330 | throw new Error(t`Cannot create while generating.`); | ||
| 331 | } | ||
| 332 | |||
| 333 | const formData = new FormData(); | ||
| 334 | formData.append('ch_name', neutralCharacterName); | ||
| 335 | formData.append('file_name', defaultAssistantAvatar.replace('.png', '')); | ||
| 336 | formData.append('creator_notes', t`Automatically created character. Feel free to edit.`); | ||
| 337 | |||
| 338 | try { | ||
| 339 | const avatarResponse = await fetch(system_avatar); | ||
| 340 | const avatarBlob = await avatarResponse.blob(); | ||
| 341 | formData.append('avatar', avatarBlob, defaultAssistantAvatar); | ||
| 342 | } catch (error) { | ||
| 343 | console.warn('Error fetching system avatar. Fallback image will be used.', error); | ||
| 344 | } | ||
| 345 | |||
| 346 | const headers = getRequestHeaders(); | ||
| 347 | delete headers['Content-Type']; | ||
| 348 | |||
| 349 | const fetchResult = await fetch('/api/characters/create', { | ||
| 350 | method: 'POST', | ||
| 351 | headers: headers, | ||
| 352 | body: formData, | ||
| 353 | cache: 'no-cache', | ||
| 354 | }); | ||
| 355 | |||
| 356 | if (!fetchResult.ok) { | ||
| 357 | throw new Error(t`Creation request did not succeed.`); | ||
| 358 | } | ||
| 359 | |||
| 360 | await getCharacters(); | ||
| 361 | } | ||
| 362 | |||
| 363 | export async function openPermanentAssistantCard() { | ||
| 364 | const avatar = getPermanentAssistantAvatar(); | ||
| 365 | const characterId = characters.findIndex(x => x.avatar === avatar); | ||
| 366 | if (characterId === -1) { | ||
| 367 | toastr.info(t`Assistant not found. Try sending a chat message.`); | ||
| 368 | return; | ||
| 369 | } | ||
| 370 | |||
| 371 | await selectCharacterById(characterId); | ||
| 372 | } | ||
| 373 | |||
| 374 | /** | ||
| 375 | * Assigns a character as the assistant. | ||
| 376 | * @param {string?} characterId Character ID | ||
| 377 | */ | ||
| 378 | export function assignCharacterAsAssistant(characterId) { | ||
| 379 | if (characterId === undefined) { | ||
| 380 | return; | ||
| 381 | } | ||
| 382 | /** @type {import('./char-data.js').v1CharData} */ | ||
| 383 | const character = characters[characterId]; | ||
| 384 | if (!character) { | ||
| 385 | return; | ||
| 386 | } | ||
| 387 | |||
| 388 | const currentAssistantAvatar = getPermanentAssistantAvatar(); | ||
| 389 | if (currentAssistantAvatar === character.avatar) { | ||
| 390 | if (character.avatar === defaultAssistantAvatar) { | ||
| 391 | toastr.info(t`${character.name} is a system assistant. Choose another character.`); | ||
| 392 | return; | ||
| 393 | } | ||
| 394 | |||
| 395 | toastr.info(t`${character.name} is no longer your assistant.`); | ||
| 396 | accountStorage.removeItem(assistantAvatarKey); | ||
| 397 | return; | ||
| 398 | } | ||
| 399 | |||
| 400 | accountStorage.setItem(assistantAvatarKey, character.avatar); | ||
| 401 | printCharactersDebounced(); | ||
| 402 | toastr.success(t`Set ${character.name} as your assistant.`); | ||
| 403 | } | ||
| 404 | |||
| 405 | export function initWelcomeScreen() { | ||
| 406 | const events = [event_types.CHAT_CHANGED, event_types.APP_READY]; | ||
| 407 | for (const event of events) { | ||
| 408 | eventSource.makeFirst(event, openWelcomeScreen); | ||
| 409 | } | ||
| 410 | |||
| 411 | eventSource.on(event_types.CHARACTER_MANAGEMENT_DROPDOWN, (target) => { | ||
| 412 | if (target !== 'set_as_assistant') { | ||
| 413 | return; | ||
| 414 | } | ||
| 415 | assignCharacterAsAssistant(this_chid); | ||
| 416 | }); | ||
| 417 | |||
| 418 | eventSource.on(event_types.CHARACTER_RENAMED, (oldAvatar, newAvatar) => { | ||
| 419 | if (oldAvatar === getPermanentAssistantAvatar()) { | ||
| 420 | accountStorage.setItem(assistantAvatarKey, newAvatar); | ||
| 421 | } | ||
| 422 | }); | ||
| 423 | } | ||
| @@ -98,11 +98,28 @@ const KNOWN_DECORATORS = ['@@activate', '@@dont_activate']; | |||
| 98 | 98 | ||
| 99 | // Typedef area | 99 | // Typedef area |
| 100 | /** | 100 | /** |
| 101 | * @typedef {object} WIGlobalScanData The chat-independent data to be scanned. Each of | ||
| 102 | * these fields can be enabled for scanning per entry. | ||
| 103 | * @property {string} personaDescription User persona description | ||
| 104 | * @property {string} characterDescription Character description | ||
| 105 | * @property {string} characterPersonality Character personality | ||
| 106 | * @property {string} characterDepthPrompt Character depth prompt (sometimes referred to as character notes) | ||
| 107 | * @property {string} scenario Character defined scenario | ||
| 108 | * @property {string} creatorNotes Character creator notes | ||
| 109 | */ | ||
| 110 | |||
| 111 | /** | ||
| 101 | * @typedef {object} WIScanEntry The entry that triggered the scan | 112 | * @typedef {object} WIScanEntry The entry that triggered the scan |
| 102 | * @property {number} [scanDepth] The depth of the scan | 113 | * @property {number} [scanDepth] The depth of the scan |
| 103 | * @property {boolean} [caseSensitive] If the scan is case sensitive | 114 | * @property {boolean} [caseSensitive] If the scan is case sensitive |
| 104 | * @property {boolean} [matchWholeWords] If the scan should match whole words | 115 | * @property {boolean} [matchWholeWords] If the scan should match whole words |
| 105 | * @property {boolean} [useGroupScoring] If the scan should use group scoring | 116 | * @property {boolean} [useGroupScoring] If the scan should use group scoring |
| 117 | * @property {boolean} [matchPersonaDescription] If the scan should match against the persona description | ||
| 118 | * @property {boolean} [matchCharacterDescription] If the scan should match against the character description | ||
| 119 | * @property {boolean} [matchCharacterPersonality] If the scan should match against the character personality | ||
| 120 | * @property {boolean} [matchCharacterDepthPrompt] If the scan should match against the character depth prompt | ||
| 121 | * @property {boolean} [matchScenario] If the scan should match against the character scenario | ||
| 122 | * @property {boolean} [matchCreatorNotes] If the scan should match against the creator notes | ||
| 106 | * @property {number} [uid] The UID of the entry that triggered the scan | 123 | * @property {number} [uid] The UID of the entry that triggered the scan |
| 107 | * @property {string} [world] The world info book of origin of the entry | 124 | * @property {string} [world] The world info book of origin of the entry |
| 108 | * @property {string[]} [key] The primary keys to scan for | 125 | * @property {string[]} [key] The primary keys to scan for |
| @@ -139,6 +156,11 @@ class WorldInfoBuffer { | |||
| 139 | static externalActivations = new Map(); | 156 | static externalActivations = new Map(); |
| 140 | 157 | ||
| 141 | /** | 158 | /** |
| 159 | * @type {WIGlobalScanData} Chat independent data to be scanned, such as persona and character descriptions | ||
| 160 | */ | ||
| 161 | #globalScanData = null; | ||
| 162 | |||
| 163 | /** | ||
| 142 | * @type {string[]} Array of messages sorted by ascending depth | 164 | * @type {string[]} Array of messages sorted by ascending depth |
| 143 | */ | 165 | */ |
| 144 | #depthBuffer = []; | 166 | #depthBuffer = []; |
| @@ -166,9 +188,11 @@ class WorldInfoBuffer { | |||
| 166 | /** | 188 | /** |
| 167 | * Initialize the buffer with the given messages. | 189 | * Initialize the buffer with the given messages. |
| 168 | * @param {string[]} messages Array of messages to add to the buffer | 190 | * @param {string[]} messages Array of messages to add to the buffer |
| 191 | * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned | ||
| 169 | */ | 192 | */ |
| 170 | constructor(messages) { | 193 | constructor(messages, globalScanData) { |
| 171 | this.#initDepthBuffer(messages); | 194 | this.#initDepthBuffer(messages); |
| 195 | this.#globalScanData = globalScanData; | ||
| 172 | } | 196 | } |
| 173 | 197 | ||
| 174 | /** | 198 | /** |
| @@ -225,6 +249,25 @@ class WorldInfoBuffer { | |||
| 225 | const JOINER = '\n' + MATCHER; | 249 | const JOINER = '\n' + MATCHER; |
| 226 | let result = MATCHER + this.#depthBuffer.slice(this.#startDepth, depth).join(JOINER); | 250 | let result = MATCHER + this.#depthBuffer.slice(this.#startDepth, depth).join(JOINER); |
| 227 | 251 | ||
| 252 | if (entry.matchPersonaDescription && this.#globalScanData.personaDescription) { | ||
| 253 | result += JOINER + this.#globalScanData.personaDescription; | ||
| 254 | } | ||
| 255 | if (entry.matchCharacterDescription && this.#globalScanData.characterDescription) { | ||
| 256 | result += JOINER + this.#globalScanData.characterDescription; | ||
| 257 | } | ||
| 258 | if (entry.matchCharacterPersonality && this.#globalScanData.characterPersonality) { | ||
| 259 | result += JOINER + this.#globalScanData.characterPersonality; | ||
| 260 | } | ||
| 261 | if (entry.matchCharacterDepthPrompt && this.#globalScanData.characterDepthPrompt) { | ||
| 262 | result += JOINER + this.#globalScanData.characterDepthPrompt; | ||
| 263 | } | ||
| 264 | if (entry.matchScenario && this.#globalScanData.scenario) { | ||
| 265 | result += JOINER + this.#globalScanData.scenario; | ||
| 266 | } | ||
| 267 | if (entry.matchCreatorNotes && this.#globalScanData.creatorNotes) { | ||
| 268 | result += JOINER + this.#globalScanData.creatorNotes; | ||
| 269 | } | ||
| 270 | |||
| 228 | if (this.#injectBuffer.length > 0) { | 271 | if (this.#injectBuffer.length > 0) { |
| 229 | result += JOINER + this.#injectBuffer.join(JOINER); | 272 | result += JOINER + this.#injectBuffer.join(JOINER); |
| 230 | } | 273 | } |
| @@ -756,6 +799,7 @@ export const worldInfoCache = new StructuredCloneMap({ cloneOnGet: true, cloneOn | |||
| 756 | * @param {string[]} chat - The chat messages to scan, in reverse order. | 799 | * @param {string[]} chat - The chat messages to scan, in reverse order. |
| 757 | * @param {number} maxContext - The maximum context size of the generation. | 800 | * @param {number} maxContext - The maximum context size of the generation. |
| 758 | * @param {boolean} isDryRun - If true, the function will not emit any events. | 801 | * @param {boolean} isDryRun - If true, the function will not emit any events. |
| 802 | * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned | ||
| 759 | * @typedef {object} WIPromptResult | 803 | * @typedef {object} WIPromptResult |
| 760 | * @property {string} worldInfoString - Complete world info string | 804 | * @property {string} worldInfoString - Complete world info string |
| 761 | * @property {string} worldInfoBefore - World info that goes before the prompt | 805 | * @property {string} worldInfoBefore - World info that goes before the prompt |
| @@ -766,10 +810,10 @@ export const worldInfoCache = new StructuredCloneMap({ cloneOnGet: true, cloneOn | |||
| 766 | * @property {Array} anAfter - Array of entries after Author's Note | 810 | * @property {Array} anAfter - Array of entries after Author's Note |
| 767 | * @returns {Promise<WIPromptResult>} The world info string and depth. | 811 | * @returns {Promise<WIPromptResult>} The world info string and depth. |
| 768 | */ | 812 | */ |
| 769 | export async function getWorldInfoPrompt(chat, maxContext, isDryRun) { | 813 | export async function getWorldInfoPrompt(chat, maxContext, isDryRun, globalScanData) { |
| 770 | let worldInfoString = '', worldInfoBefore = '', worldInfoAfter = ''; | 814 | let worldInfoString = '', worldInfoBefore = '', worldInfoAfter = ''; |
| 771 | 815 | ||
| 772 | const activatedWorldInfo = await checkWorldInfo(chat, maxContext, isDryRun); | 816 | const activatedWorldInfo = await checkWorldInfo(chat, maxContext, isDryRun, globalScanData); |
| 773 | worldInfoBefore = activatedWorldInfo.worldInfoBefore; | 817 | worldInfoBefore = activatedWorldInfo.worldInfoBefore; |
| 774 | worldInfoAfter = activatedWorldInfo.worldInfoAfter; | 818 | worldInfoAfter = activatedWorldInfo.worldInfoAfter; |
| 775 | worldInfoString = worldInfoBefore + worldInfoAfter; | 819 | worldInfoString = worldInfoBefore + worldInfoAfter; |
| @@ -966,7 +1010,7 @@ function registerWorldInfoSlashCommands() { | |||
| 966 | /** | 1010 | /** |
| 967 | * Gets the name of the character-bound lorebook. | 1011 | * Gets the name of the character-bound lorebook. |
| 968 | * @param {import('./slash-commands/SlashCommand.js').NamedArguments} args Named arguments | 1012 | * @param {import('./slash-commands/SlashCommand.js').NamedArguments} args Named arguments |
| 969 | * @param {import('./slash-commands/SlashCommand.js').UnnamedArguments} name Character name | 1013 | * @param {string} name Character name |
| 970 | * @returns {string} The name of the character-bound lorebook, a JSON string of the character's lorebooks, or an empty string | 1014 | * @returns {string} The name of the character-bound lorebook, a JSON string of the character's lorebooks, or an empty string |
| 971 | */ | 1015 | */ |
| 972 | function getCharBookCallback({ type }, name) { | 1016 | function getCharBookCallback({ type }, name) { |
| @@ -2191,6 +2235,12 @@ export const originalWIDataKeyMap = { | |||
| 2191 | 'matchWholeWords': 'extensions.match_whole_words', | 2235 | 'matchWholeWords': 'extensions.match_whole_words', |
| 2192 | 'useGroupScoring': 'extensions.use_group_scoring', | 2236 | 'useGroupScoring': 'extensions.use_group_scoring', |
| 2193 | 'caseSensitive': 'extensions.case_sensitive', | 2237 | 'caseSensitive': 'extensions.case_sensitive', |
| 2238 | 'matchPersonaDescription': 'extensions.match_persona_description', | ||
| 2239 | 'matchCharacterDescription': 'extensions.match_character_description', | ||
| 2240 | 'matchCharacterPersonality': 'extensions.match_character_personality', | ||
| 2241 | 'matchCharacterDepthPrompt': 'extensions.match_character_depth_prompt', | ||
| 2242 | 'matchScenario': 'extensions.match_scenario', | ||
| 2243 | 'matchCreatorNotes': 'extensions.match_creator_notes', | ||
| 2194 | 'scanDepth': 'extensions.scan_depth', | 2244 | 'scanDepth': 'extensions.scan_depth', |
| 2195 | 'automationId': 'extensions.automation_id', | 2245 | 'automationId': 'extensions.automation_id', |
| 2196 | 'vectorized': 'extensions.vectorized', | 2246 | 'vectorized': 'extensions.vectorized', |
| @@ -2608,7 +2658,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2608 | if (!isMobile()) { | 2658 | if (!isMobile()) { |
| 2609 | $(characterFilter).select2({ | 2659 | $(characterFilter).select2({ |
| 2610 | width: '100%', | 2660 | width: '100%', |
| 2611 | placeholder: 'Tie this entry to specific characters or characters with specific tags', | 2661 | placeholder: t`Tie this entry to specific characters or characters with specific tags`, |
| 2612 | allowClear: true, | 2662 | allowClear: true, |
| 2613 | closeOnSelect: false, | 2663 | closeOnSelect: false, |
| 2614 | }); | 2664 | }); |
| @@ -3005,7 +3055,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3005 | 3055 | ||
| 3006 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; | 3056 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; |
| 3007 | template | 3057 | template |
| 3008 | .find(`select[name="position"] option[value=${entry.position}][data-role="${roleValue}"]`) | 3058 | .find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`) |
| 3009 | .prop('selected', true) | 3059 | .prop('selected', true) |
| 3010 | .trigger('input'); | 3060 | .trigger('input'); |
| 3011 | 3061 | ||
| @@ -3208,7 +3258,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3208 | 3258 | ||
| 3209 | // Create wrapper div | 3259 | // Create wrapper div |
| 3210 | const wrapper = document.createElement('div'); | 3260 | const wrapper = document.createElement('div'); |
| 3211 | wrapper.textContent = t`Move "${sourceName}" to:`; | 3261 | wrapper.textContent = t`Move '${sourceName}' to:`; |
| 3212 | 3262 | ||
| 3213 | // Create container and append elements | 3263 | // Create container and append elements |
| 3214 | const container = document.createElement('div'); | 3264 | const container = document.createElement('div'); |
| @@ -3308,6 +3358,28 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3308 | }); | 3358 | }); |
| 3309 | useGroupScoringSelect.val((entry.useGroupScoring === null || entry.useGroupScoring === undefined) ? 'null' : entry.useGroupScoring ? 'true' : 'false').trigger('input'); | 3359 | useGroupScoringSelect.val((entry.useGroupScoring === null || entry.useGroupScoring === undefined) ? 'null' : entry.useGroupScoring ? 'true' : 'false').trigger('input'); |
| 3310 | 3360 | ||
| 3361 | function handleMatchCheckbox(fieldName) { | ||
| 3362 | const key = originalWIDataKeyMap[fieldName]; | ||
| 3363 | const checkBoxElem = template.find(`input[type="checkbox"][name="${fieldName}"]`); | ||
| 3364 | checkBoxElem.data('uid', entry.uid); | ||
| 3365 | checkBoxElem.on('input', async function () { | ||
| 3366 | const uid = $(this).data('uid'); | ||
| 3367 | const value = $(this).prop('checked'); | ||
| 3368 | |||
| 3369 | data.entries[uid][fieldName] = value; | ||
| 3370 | setWIOriginalDataValue(data, uid, key, data.entries[uid][fieldName]); | ||
| 3371 | await saveWorldInfo(name, data); | ||
| 3372 | }); | ||
| 3373 | checkBoxElem.prop('checked', !!entry[fieldName]).trigger('input'); | ||
| 3374 | } | ||
| 3375 | |||
| 3376 | handleMatchCheckbox('matchPersonaDescription'); | ||
| 3377 | handleMatchCheckbox('matchCharacterDescription'); | ||
| 3378 | handleMatchCheckbox('matchCharacterPersonality'); | ||
| 3379 | handleMatchCheckbox('matchCharacterDepthPrompt'); | ||
| 3380 | handleMatchCheckbox('matchScenario'); | ||
| 3381 | handleMatchCheckbox('matchCreatorNotes'); | ||
| 3382 | |||
| 3311 | // automation id | 3383 | // automation id |
| 3312 | const automationIdInput = template.find('input[name="automationId"]'); | 3384 | const automationIdInput = template.find('input[name="automationId"]'); |
| 3313 | automationIdInput.data('uid', entry.uid); | 3385 | automationIdInput.data('uid', entry.uid); |
| @@ -3443,7 +3515,7 @@ function createEntryInputAutocomplete(input, callback, { allowMultiple = false } | |||
| 3443 | }); | 3515 | }); |
| 3444 | 3516 | ||
| 3445 | $(input).on('focus click', function () { | 3517 | $(input).on('focus click', function () { |
| 3446 | $(input).autocomplete('search', allowMultiple ? String($(input).val()).split(/,\s*/).pop() : $(input).val()); | 3518 | $(input).autocomplete('search', allowMultiple ? String($(input).val()).split(/,\s*/).pop() : String($(input).val())); |
| 3447 | }); | 3519 | }); |
| 3448 | } | 3520 | } |
| 3449 | 3521 | ||
| @@ -3514,6 +3586,12 @@ export const newWorldInfoEntryDefinition = { | |||
| 3514 | disable: { default: false, type: 'boolean' }, | 3586 | disable: { default: false, type: 'boolean' }, |
| 3515 | excludeRecursion: { default: false, type: 'boolean' }, | 3587 | excludeRecursion: { default: false, type: 'boolean' }, |
| 3516 | preventRecursion: { default: false, type: 'boolean' }, | 3588 | preventRecursion: { default: false, type: 'boolean' }, |
| 3589 | matchPersonaDescription: { default: false, type: 'boolean' }, | ||
| 3590 | matchCharacterDescription: { default: false, type: 'boolean' }, | ||
| 3591 | matchCharacterPersonality: { default: false, type: 'boolean' }, | ||
| 3592 | matchCharacterDepthPrompt: { default: false, type: 'boolean' }, | ||
| 3593 | matchScenario: { default: false, type: 'boolean' }, | ||
| 3594 | matchCreatorNotes: { default: false, type: 'boolean' }, | ||
| 3517 | delayUntilRecursion: { default: 0, type: 'number' }, | 3595 | delayUntilRecursion: { default: 0, type: 'number' }, |
| 3518 | probability: { default: 100, type: 'number' }, | 3596 | probability: { default: 100, type: 'number' }, |
| 3519 | useProbability: { default: true, type: 'boolean' }, | 3597 | useProbability: { default: true, type: 'boolean' }, |
| @@ -3978,6 +4056,7 @@ function parseDecorators(content) { | |||
| 3978 | * @param {string[]} chat The chat messages to scan, in reverse order. | 4056 | * @param {string[]} chat The chat messages to scan, in reverse order. |
| 3979 | * @param {number} maxContext The maximum context size of the generation. | 4057 | * @param {number} maxContext The maximum context size of the generation. |
| 3980 | * @param {boolean} isDryRun Whether to perform a dry run. | 4058 | * @param {boolean} isDryRun Whether to perform a dry run. |
| 4059 | * @param {WIGlobalScanData} globalScanData Chat independent context to be scanned | ||
| 3981 | * @typedef {object} WIActivated | 4060 | * @typedef {object} WIActivated |
| 3982 | * @property {string} worldInfoBefore The world info before the chat. | 4061 | * @property {string} worldInfoBefore The world info before the chat. |
| 3983 | * @property {string} worldInfoAfter The world info after the chat. | 4062 | * @property {string} worldInfoAfter The world info after the chat. |
| @@ -3988,9 +4067,9 @@ function parseDecorators(content) { | |||
| 3988 | * @property {Set<any>} allActivatedEntries All entries. | 4067 | * @property {Set<any>} allActivatedEntries All entries. |
| 3989 | * @returns {Promise<WIActivated>} The world info activated. | 4068 | * @returns {Promise<WIActivated>} The world info activated. |
| 3990 | */ | 4069 | */ |
| 3991 | export async function checkWorldInfo(chat, maxContext, isDryRun) { | 4070 | export async function checkWorldInfo(chat, maxContext, isDryRun, globalScanData) { |
| 3992 | const context = getContext(); | 4071 | const context = getContext(); |
| 3993 | const buffer = new WorldInfoBuffer(chat); | 4072 | const buffer = new WorldInfoBuffer(chat, globalScanData); |
| 3994 | 4073 | ||
| 3995 | console.debug(`[WI] --- START WI SCAN (on ${chat.length} messages)${isDryRun ? ' (DRY RUN)' : ''} ---`); | 4074 | console.debug(`[WI] --- START WI SCAN (on ${chat.length} messages)${isDryRun ? ' (DRY RUN)' : ''} ---`); |
| 3996 | 4075 | ||
| @@ -4848,6 +4927,12 @@ export function convertCharacterBook(characterBook) { | |||
| 4848 | sticky: entry.extensions?.sticky ?? null, | 4927 | sticky: entry.extensions?.sticky ?? null, |
| 4849 | cooldown: entry.extensions?.cooldown ?? null, | 4928 | cooldown: entry.extensions?.cooldown ?? null, |
| 4850 | delay: entry.extensions?.delay ?? null, | 4929 | delay: entry.extensions?.delay ?? null, |
| 4930 | matchPersonaDescription: entry.extensions?.match_persona_description ?? false, | ||
| 4931 | matchCharacterDescription: entry.extensions?.match_character_description ?? false, | ||
| 4932 | matchCharacterPersonality: entry.extensions?.match_character_personality ?? false, | ||
| 4933 | matchCharacterDepthPrompt: entry.extensions?.match_character_depth_prompt ?? false, | ||
| 4934 | matchScenario: entry.extensions?.match_scenario ?? false, | ||
| 4935 | matchCreatorNotes: entry.extensions?.match_creator_notes ?? false, | ||
| 4851 | extensions: entry.extensions ?? {}, | 4936 | extensions: entry.extensions ?? {}, |
| 4852 | }; | 4937 | }; |
| 4853 | }); | 4938 | }); |
| @@ -4901,7 +4986,7 @@ export function checkEmbeddedWorld(chid) { | |||
| 4901 | toastr.info( | 4986 | toastr.info( |
| 4902 | 'To import and use it, select "Import Card Lore" in the "More..." dropdown menu on the character panel.', | 4987 | 'To import and use it, select "Import Card Lore" in the "More..." dropdown menu on the character panel.', |
| 4903 | `${characters[chid].name} has an embedded World/Lorebook`, | 4988 | `${characters[chid].name} has an embedded World/Lorebook`, |
| 4904 | { timeOut: 5000, extendedTimeOut: 10000, positionClass: 'toast-top-center' }, | 4989 | { timeOut: 5000, extendedTimeOut: 10000 }, |
| 4905 | ); | 4990 | ); |
| 4906 | } | 4991 | } |
| 4907 | } | 4992 | } |
| @@ -5118,7 +5203,7 @@ export function openWorldInfoEditor(worldName) { | |||
| 5118 | 5203 | ||
| 5119 | /** | 5204 | /** |
| 5120 | * Assigns a lorebook to the current chat. | 5205 | * Assigns a lorebook to the current chat. |
| 5121 | * @param {PointerEvent} event Pointer event | 5206 | * @param {JQuery.ClickEvent<Document, undefined, any, any>} event Pointer event |
| 5122 | * @returns {Promise<void>} | 5207 | * @returns {Promise<void>} |
| 5123 | */ | 5208 | */ |
| 5124 | export async function assignLorebookToChat(event) { | 5209 | export async function assignLorebookToChat(event) { |
| @@ -5157,11 +5242,106 @@ export async function assignLorebookToChat(event) { | |||
| 5157 | saveMetadata(); | 5242 | saveMetadata(); |
| 5158 | }); | 5243 | }); |
| 5159 | 5244 | ||
| 5160 | return callGenericPopup(template, POPUP_TYPE.TEXT); | 5245 | await callGenericPopup(template, POPUP_TYPE.TEXT); |
| 5246 | } | ||
| 5247 | |||
| 5248 | /** | ||
| 5249 | * Moves a World Info entry from a source lorebook to a target lorebook. | ||
| 5250 | * | ||
| 5251 | * @param {string} sourceName - The name of the source lorebook file. | ||
| 5252 | * @param {string} targetName - The name of the target lorebook file. | ||
| 5253 | * @param {string|number} uid - The UID of the entry to move from the source lorebook. | ||
| 5254 | * @returns {Promise<boolean>} True if the move was successful, false otherwise. | ||
| 5255 | */ | ||
| 5256 | export async function moveWorldInfoEntry(sourceName, targetName, uid) { | ||
| 5257 | if (sourceName === targetName) { | ||
| 5258 | return false; | ||
| 5259 | } | ||
| 5260 | |||
| 5261 | if (!world_names.includes(sourceName)) { | ||
| 5262 | toastr.error(t`Source lorebook '${sourceName}' not found.`); | ||
| 5263 | console.error(`[WI Move] Source lorebook '${sourceName}' does not exist.`); | ||
| 5264 | return false; | ||
| 5265 | } | ||
| 5266 | |||
| 5267 | if (!world_names.includes(targetName)) { | ||
| 5268 | toastr.error(t`Target lorebook '${targetName}' not found.`); | ||
| 5269 | console.error(`[WI Move] Target lorebook '${targetName}' does not exist.`); | ||
| 5270 | return false; | ||
| 5271 | } | ||
| 5272 | |||
| 5273 | const entryUidString = String(uid); | ||
| 5274 | |||
| 5275 | try { | ||
| 5276 | const sourceData = await loadWorldInfo(sourceName); | ||
| 5277 | const targetData = await loadWorldInfo(targetName); | ||
| 5278 | |||
| 5279 | if (!sourceData || !sourceData.entries) { | ||
| 5280 | toastr.error(t`Failed to load data for source lorebook '${sourceName}'.`); | ||
| 5281 | console.error(`[WI Move] Could not load source data for '${sourceName}'.`); | ||
| 5282 | return false; | ||
| 5283 | } | ||
| 5284 | if (!targetData || !targetData.entries) { | ||
| 5285 | toastr.error(t`Failed to load data for target lorebook '${targetName}'.`); | ||
| 5286 | console.error(`[WI Move] Could not load target data for '${targetName}'.`); | ||
| 5287 | return false; | ||
| 5288 | } | ||
| 5289 | |||
| 5290 | if (!sourceData.entries[entryUidString]) { | ||
| 5291 | toastr.error(t`Entry not found in source lorebook '${sourceName}'.`); | ||
| 5292 | console.error(`[WI Move] Entry UID ${entryUidString} not found in '${sourceName}'.`); | ||
| 5293 | return false; | ||
| 5294 | } | ||
| 5295 | |||
| 5296 | const entryToMove = structuredClone(sourceData.entries[entryUidString]); | ||
| 5297 | |||
| 5298 | |||
| 5299 | const newUid = getFreeWorldEntryUid(targetData); | ||
| 5300 | if (newUid === null) { | ||
| 5301 | console.error(`[WI Move] Failed to get a free UID in '${targetName}'.`); | ||
| 5302 | return false; | ||
| 5303 | } | ||
| 5304 | |||
| 5305 | entryToMove.uid = newUid; | ||
| 5306 | // Place the entry at the end of the target lorebook | ||
| 5307 | const maxDisplayIndex = Object.values(targetData.entries).reduce((max, entry) => Math.max(max, entry.displayIndex ?? -1), -1); | ||
| 5308 | entryToMove.displayIndex = maxDisplayIndex + 1; | ||
| 5309 | |||
| 5310 | targetData.entries[newUid] = entryToMove; | ||
| 5311 | |||
| 5312 | delete sourceData.entries[entryUidString]; | ||
| 5313 | // Remove from originalData if it exists | ||
| 5314 | deleteWIOriginalDataValue(sourceData, entryUidString); | ||
| 5315 | // TODO: setWIOriginalDataValue | ||
| 5316 | console.debug(`[WI Move] Removed entry UID ${entryUidString} from source '${sourceName}'.`); | ||
| 5317 | |||
| 5318 | |||
| 5319 | await saveWorldInfo(targetName, targetData, true); | ||
| 5320 | console.debug(`[WI Move] Saved target lorebook '${targetName}'.`); | ||
| 5321 | await saveWorldInfo(sourceName, sourceData, true); | ||
| 5322 | console.debug(`[WI Move] Saved source lorebook '${sourceName}'.`); | ||
| 5323 | |||
| 5324 | |||
| 5325 | console.log(`[WI Move] ${entryToMove.comment} moved successfully to '${targetName}'.`); | ||
| 5326 | |||
| 5327 | // Check if the currently viewed book in the editor is the source or target and reload it | ||
| 5328 | const currentEditorBookIndex = Number($('#world_editor_select').val()); | ||
| 5329 | if (!isNaN(currentEditorBookIndex)) { | ||
| 5330 | const currentEditorBookName = world_names[currentEditorBookIndex]; | ||
| 5331 | if (currentEditorBookName === sourceName || currentEditorBookName === targetName) { | ||
| 5332 | reloadEditor(currentEditorBookName); | ||
| 5333 | } | ||
| 5161 | } | 5334 | } |
| 5162 | 5335 | ||
| 5163 | jQuery(() => { | 5336 | return true; |
| 5337 | } catch (error) { | ||
| 5338 | toastr.error(t`An unexpected error occurred while moving the entry: ${error.message}`); | ||
| 5339 | console.error('[WI Move] Unexpected error:', error); | ||
| 5340 | return false; | ||
| 5341 | } | ||
| 5342 | } | ||
| 5164 | 5343 | ||
| 5344 | export function initWorldInfo() { | ||
| 5165 | $('#world_info').on('mousedown change', async function (e) { | 5345 | $('#world_info').on('mousedown change', async function (e) { |
| 5166 | // If there's no world names, don't do anything | 5346 | // If there's no world names, don't do anything |
| 5167 | if (world_names.length === 0) { | 5347 | if (world_names.length === 0) { |
| @@ -5348,7 +5528,7 @@ jQuery(() => { | |||
| 5348 | if (!isMobile()) { | 5528 | if (!isMobile()) { |
| 5349 | $('#world_info').select2({ | 5529 | $('#world_info').select2({ |
| 5350 | width: '100%', | 5530 | width: '100%', |
| 5351 | placeholder: 'No Worlds active. Click here to select.', | 5531 | placeholder: t`No Worlds active. Click here to select.`, |
| 5352 | allowClear: true, | 5532 | allowClear: true, |
| 5353 | closeOnSelect: false, | 5533 | closeOnSelect: false, |
| 5354 | }); | 5534 | }); |
| @@ -5373,100 +5553,4 @@ jQuery(() => { | |||
| 5373 | } | 5553 | } |
| 5374 | }); | 5554 | }); |
| 5375 | }); | 5555 | }); |
| 5376 | }); | ||
| 5377 | |||
| 5378 | /** | ||
| 5379 | * Moves a World Info entry from a source lorebook to a target lorebook. | ||
| 5380 | * | ||
| 5381 | * @param {string} sourceName - The name of the source lorebook file. | ||
| 5382 | * @param {string} targetName - The name of the target lorebook file. | ||
| 5383 | * @param {string|number} uid - The UID of the entry to move from the source lorebook. | ||
| 5384 | * @returns {Promise<boolean>} True if the move was successful, false otherwise. | ||
| 5385 | */ | ||
| 5386 | export async function moveWorldInfoEntry(sourceName, targetName, uid) { | ||
| 5387 | if (sourceName === targetName) { | ||
| 5388 | return false; | ||
| 5389 | } | ||
| 5390 | |||
| 5391 | if (!world_names.includes(sourceName)) { | ||
| 5392 | toastr.error(t`Source lorebook '${sourceName}' not found.`); | ||
| 5393 | console.error(`[WI Move] Source lorebook '${sourceName}' does not exist.`); | ||
| 5394 | return false; | ||
| 5395 | } | ||
| 5396 | |||
| 5397 | if (!world_names.includes(targetName)) { | ||
| 5398 | toastr.error(t`Target lorebook '${targetName}' not found.`); | ||
| 5399 | console.error(`[WI Move] Target lorebook '${targetName}' does not exist.`); | ||
| 5400 | return false; | ||
| 5401 | } | ||
| 5402 | |||
| 5403 | const entryUidString = String(uid); | ||
| 5404 | |||
| 5405 | try { | ||
| 5406 | const sourceData = await loadWorldInfo(sourceName); | ||
| 5407 | const targetData = await loadWorldInfo(targetName); | ||
| 5408 | |||
| 5409 | if (!sourceData || !sourceData.entries) { | ||
| 5410 | toastr.error(t`Failed to load data for source lorebook '${sourceName}'.`); | ||
| 5411 | console.error(`[WI Move] Could not load source data for '${sourceName}'.`); | ||
| 5412 | return false; | ||
| 5413 | } | ||
| 5414 | if (!targetData || !targetData.entries) { | ||
| 5415 | toastr.error(t`Failed to load data for target lorebook '${targetName}'.`); | ||
| 5416 | console.error(`[WI Move] Could not load target data for '${targetName}'.`); | ||
| 5417 | return false; | ||
| 5418 | } | ||
| 5419 | |||
| 5420 | if (!sourceData.entries[entryUidString]) { | ||
| 5421 | toastr.error(t`Entry not found in source lorebook '${sourceName}'.`); | ||
| 5422 | console.error(`[WI Move] Entry UID ${entryUidString} not found in '${sourceName}'.`); | ||
| 5423 | return false; | ||
| 5424 | } | ||
| 5425 | |||
| 5426 | const entryToMove = structuredClone(sourceData.entries[entryUidString]); | ||
| 5427 | |||
| 5428 | |||
| 5429 | const newUid = getFreeWorldEntryUid(targetData); | ||
| 5430 | if (newUid === null) { | ||
| 5431 | console.error(`[WI Move] Failed to get a free UID in '${targetName}'.`); | ||
| 5432 | return false; | ||
| 5433 | } | ||
| 5434 | |||
| 5435 | entryToMove.uid = newUid; | ||
| 5436 | // Place the entry at the end of the target lorebook | ||
| 5437 | const maxDisplayIndex = Object.values(targetData.entries).reduce((max, entry) => Math.max(max, entry.displayIndex ?? -1), -1); | ||
| 5438 | entryToMove.displayIndex = maxDisplayIndex + 1; | ||
| 5439 | |||
| 5440 | targetData.entries[newUid] = entryToMove; | ||
| 5441 | |||
| 5442 | delete sourceData.entries[entryUidString]; | ||
| 5443 | // Remove from originalData if it exists | ||
| 5444 | deleteWIOriginalDataValue(sourceData, entryUidString); | ||
| 5445 | // TODO: setWIOriginalDataValue | ||
| 5446 | console.debug(`[WI Move] Removed entry UID ${entryUidString} from source '${sourceName}'.`); | ||
| 5447 | |||
| 5448 | |||
| 5449 | await saveWorldInfo(targetName, targetData, true); | ||
| 5450 | console.debug(`[WI Move] Saved target lorebook '${targetName}'.`); | ||
| 5451 | await saveWorldInfo(sourceName, sourceData, true); | ||
| 5452 | console.debug(`[WI Move] Saved source lorebook '${sourceName}'.`); | ||
| 5453 | |||
| 5454 | |||
| 5455 | console.log(`[WI Move] ${entryToMove.comment} moved successfully to '${targetName}'.`); | ||
| 5456 | |||
| 5457 | // Check if the currently viewed book in the editor is the source or target and reload it | ||
| 5458 | const currentEditorBookIndex = Number($('#world_editor_select').val()); | ||
| 5459 | if (!isNaN(currentEditorBookIndex)) { | ||
| 5460 | const currentEditorBookName = world_names[currentEditorBookIndex]; | ||
| 5461 | if (currentEditorBookName === sourceName || currentEditorBookName === targetName) { | ||
| 5462 | reloadEditor(currentEditorBookName); | ||
| 5463 | } | ||
| 5464 | } | ||
| 5465 | |||
| 5466 | return true; | ||
| 5467 | } catch (error) { | ||
| 5468 | toastr.error(t`An unexpected error occurred while moving the entry: ${error.message}`); | ||
| 5469 | console.error('[WI Move] Unexpected error:', error); | ||
| 5470 | return false; | ||
| 5471 | } | ||
| 5472 | } | 5556 | } |
| @@ -10,6 +10,7 @@ | |||
| 10 | @import url(css/accounts.css); | 10 | @import url(css/accounts.css); |
| 11 | @import url(css/tags.css); | 11 | @import url(css/tags.css); |
| 12 | @import url(css/scrollable-button.css); | 12 | @import url(css/scrollable-button.css); |
| 13 | @import url(css/welcome.css); | ||
| 13 | 14 | ||
| 14 | :root { | 15 | :root { |
| 15 | --doc-height: 100%; | 16 | --doc-height: 100%; |
| @@ -116,6 +117,7 @@ | |||
| 116 | --avatar-base-width: 50px; | 117 | --avatar-base-width: 50px; |
| 117 | --avatar-base-border-radius: 2px; | 118 | --avatar-base-border-radius: 2px; |
| 118 | --avatar-base-border-radius-round: 50%; | 119 | --avatar-base-border-radius-round: 50%; |
| 120 | --avatar-base-border-radius-rounded: 10px; | ||
| 119 | --inline-avatar-small-factor: 0.6; | 121 | --inline-avatar-small-factor: 0.6; |
| 120 | 122 | ||
| 121 | --animation-duration: 125ms; | 123 | --animation-duration: 125ms; |
| @@ -157,11 +159,27 @@ body { | |||
| 157 | } | 159 | } |
| 158 | 160 | ||
| 159 | ::-webkit-scrollbar { | 161 | ::-webkit-scrollbar { |
| 160 | width: 10px; | 162 | width: 0.7rem; |
| 161 | height: 10px; | ||
| 162 | scrollbar-gutter: stable; | 163 | scrollbar-gutter: stable; |
| 163 | } | 164 | } |
| 164 | 165 | ||
| 166 | ::-webkit-scrollbar-track { | ||
| 167 | cursor: default; | ||
| 168 | } | ||
| 169 | |||
| 170 | ::-webkit-scrollbar-track:hover { | ||
| 171 | /* Adaptive, but won't contrast with neutral-gray. */ | ||
| 172 | background-color: rgba(126, 126, 126, 0.2); | ||
| 173 | } | ||
| 174 | |||
| 175 | ::-webkit-scrollbar-thumb { | ||
| 176 | cursor: grab; | ||
| 177 | } | ||
| 178 | |||
| 179 | ::-webkit-scrollbar-thumb:active { | ||
| 180 | cursor: grabbing; | ||
| 181 | } | ||
| 182 | |||
| 165 | .scrollY { | 183 | .scrollY { |
| 166 | overflow-y: auto !important; | 184 | overflow-y: auto !important; |
| 167 | } | 185 | } |
| @@ -231,6 +249,7 @@ table.responsiveTable { | |||
| 231 | .has_hover_label .label_icon { | 249 | .has_hover_label .label_icon { |
| 232 | transition: opacity var(--animation-duration) ease, max-width var(--animation-duration) ease; | 250 | transition: opacity var(--animation-duration) ease, max-width var(--animation-duration) ease; |
| 233 | } | 251 | } |
| 252 | |||
| 234 | .has_hover_label .label { | 253 | .has_hover_label .label { |
| 235 | transition: opacity var(--animation-duration-slow) ease, max-width var(--animation-duration-slow) ease; | 254 | transition: opacity var(--animation-duration-slow) ease, max-width var(--animation-duration-slow) ease; |
| 236 | /* Prevent double gap on hidden icon */ | 255 | /* Prevent double gap on hidden icon */ |
| @@ -241,6 +260,7 @@ table.responsiveTable { | |||
| 241 | .has_hover_label .label { | 260 | .has_hover_label .label { |
| 242 | transition-delay: var(--animation-duration-slow); | 261 | transition-delay: var(--animation-duration-slow); |
| 243 | } | 262 | } |
| 263 | |||
| 244 | .has_hover_label.fast .label_icon, | 264 | .has_hover_label.fast .label_icon, |
| 245 | .has_hover_label.fast .label { | 265 | .has_hover_label.fast .label { |
| 246 | transition-delay: var(--animation-duration); | 266 | transition-delay: var(--animation-duration); |
| @@ -487,6 +507,7 @@ input[type='checkbox']:focus-visible { | |||
| 487 | .mes_text em { | 507 | .mes_text em { |
| 488 | color: var(--SmartThemeEmColor); | 508 | color: var(--SmartThemeEmColor); |
| 489 | } | 509 | } |
| 510 | |||
| 490 | .mes_reasoning i, | 511 | .mes_reasoning i, |
| 491 | .mes_reasoning em { | 512 | .mes_reasoning em { |
| 492 | color: hsl(from var(--reasoning-em-color) h calc(s * var(--reasoning-saturation)) l); | 513 | color: hsl(from var(--reasoning-em-color) h calc(s * var(--reasoning-saturation)) l); |
| @@ -496,6 +517,7 @@ input[type='checkbox']:focus-visible { | |||
| 496 | .mes_text q em { | 517 | .mes_text q em { |
| 497 | color: inherit; | 518 | color: inherit; |
| 498 | } | 519 | } |
| 520 | |||
| 499 | .mes_reasoning q i, | 521 | .mes_reasoning q i, |
| 500 | .mes_reasoning q em { | 522 | .mes_reasoning q em { |
| 501 | color: hsl(from var(--SmartThemeQuoteColor) h calc(s * var(--reasoning-saturation)) l); | 523 | color: hsl(from var(--SmartThemeQuoteColor) h calc(s * var(--reasoning-saturation)) l); |
| @@ -504,6 +526,7 @@ input[type='checkbox']:focus-visible { | |||
| 504 | .mes_text u { | 526 | .mes_text u { |
| 505 | color: var(--SmartThemeUnderlineColor); | 527 | color: var(--SmartThemeUnderlineColor); |
| 506 | } | 528 | } |
| 529 | |||
| 507 | .mes_reasoning u { | 530 | .mes_reasoning u { |
| 508 | color: hsl(from var(--SmartThemeUnderlineColor) h calc(s * var(--reasoning-saturation)) l); | 531 | color: hsl(from var(--SmartThemeUnderlineColor) h calc(s * var(--reasoning-saturation)) l); |
| 509 | } | 532 | } |
| @@ -511,6 +534,7 @@ input[type='checkbox']:focus-visible { | |||
| 511 | .mes_text q { | 534 | .mes_text q { |
| 512 | color: var(--SmartThemeQuoteColor); | 535 | color: var(--SmartThemeQuoteColor); |
| 513 | } | 536 | } |
| 537 | |||
| 514 | .mes_reasoning q { | 538 | .mes_reasoning q { |
| 515 | color: hsl(from var(--SmartThemeQuoteColor) h calc(s * var(--reasoning-saturation)) l); | 539 | color: hsl(from var(--SmartThemeQuoteColor) h calc(s * var(--reasoning-saturation)) l); |
| 516 | } | 540 | } |
| @@ -1190,6 +1214,17 @@ body .panelControlBar { | |||
| 1190 | background-color: rgb(102, 0, 0); | 1214 | background-color: rgb(102, 0, 0); |
| 1191 | } | 1215 | } |
| 1192 | 1216 | ||
| 1217 | #chat .style-pins { | ||
| 1218 | visibility: hidden; | ||
| 1219 | position: fixed; | ||
| 1220 | left: -9999px; | ||
| 1221 | top: -9999px; | ||
| 1222 | width: 0; | ||
| 1223 | height: 0; | ||
| 1224 | opacity: 0; | ||
| 1225 | pointer-events: none; | ||
| 1226 | } | ||
| 1227 | |||
| 1193 | .mes q:before, | 1228 | .mes q:before, |
| 1194 | .mes q:after { | 1229 | .mes q:after { |
| 1195 | content: ''; | 1230 | content: ''; |
| @@ -3105,7 +3140,7 @@ input[type=search]:focus::-webkit-search-cancel-button { | |||
| 3105 | .missing-avatar.inline_avatar { | 3140 | .missing-avatar.inline_avatar { |
| 3106 | padding: unset; | 3141 | padding: unset; |
| 3107 | border-radius: var(--avatar-base-border-radius-round); | 3142 | border-radius: var(--avatar-base-border-radius-round); |
| 3108 | width: fit-content; | 3143 | font-size: 20px; |
| 3109 | } | 3144 | } |
| 3110 | 3145 | ||
| 3111 | /*applies to char list and mes_text char display name*/ | 3146 | /*applies to char list and mes_text char display name*/ |
| @@ -3905,14 +3940,38 @@ grammarly-extension { | |||
| 3905 | 3940 | ||
| 3906 | 3941 | ||
| 3907 | /* Override toastr default styles */ | 3942 | /* Override toastr default styles */ |
| 3908 | body #toast-container { | 3943 | body>#toast-container { |
| 3909 | top: var(--topBarBlockSize); | 3944 | margin-top: var(--topBarBlockSize); |
| 3910 | } | 3945 | } |
| 3911 | 3946 | ||
| 3912 | body #toast-container>div { | 3947 | body #toast-container>div { |
| 3913 | opacity: 1; | 3948 | opacity: 1; |
| 3914 | filter: unset; | 3949 | filter: unset; |
| 3915 | -ms-filter: unset; | 3950 | -ms-filter: unset; |
| 3951 | padding: 10px 10px 10px 50px; | ||
| 3952 | font-size: calc(var(--mainFontSize) * 0.95); | ||
| 3953 | width: 300px; | ||
| 3954 | } | ||
| 3955 | |||
| 3956 | body #toast-container .toast-success { | ||
| 3957 | background-color: #5d9e5d; | ||
| 3958 | } | ||
| 3959 | |||
| 3960 | body #toast-container .toast-error { | ||
| 3961 | background-color: #a83c36; | ||
| 3962 | } | ||
| 3963 | |||
| 3964 | body #toast-container .toast-info { | ||
| 3965 | background-color: #4092aa; | ||
| 3966 | } | ||
| 3967 | |||
| 3968 | body #toast-container .toast-warning { | ||
| 3969 | background-color: #e29325; | ||
| 3970 | } | ||
| 3971 | |||
| 3972 | button.toast-close-button { | ||
| 3973 | padding-right: 5px; | ||
| 3974 | padding-top: 3px; | ||
| 3916 | } | 3975 | } |
| 3917 | 3976 | ||
| 3918 | #dialogue_del_mes { | 3977 | #dialogue_del_mes { |
| @@ -4002,6 +4061,7 @@ input[type='checkbox'].del_checkbox { | |||
| 4002 | .avatar-container:not(.locked_to_chat) .locked_to_chat_label { | 4061 | .avatar-container:not(.locked_to_chat) .locked_to_chat_label { |
| 4003 | display: none; | 4062 | display: none; |
| 4004 | } | 4063 | } |
| 4064 | |||
| 4005 | .avatar-container:not(.locked_to_character) .locked_to_character_label { | 4065 | .avatar-container:not(.locked_to_character) .locked_to_character_label { |
| 4006 | display: none; | 4066 | display: none; |
| 4007 | } | 4067 | } |
| @@ -4021,7 +4081,7 @@ input[type='checkbox'].del_checkbox { | |||
| 4021 | } | 4081 | } |
| 4022 | 4082 | ||
| 4023 | #lock_user_name.locked { | 4083 | #lock_user_name.locked { |
| 4024 | border-color: color-mix(in srgb, var(--SmartThemeQuoteColor) 50%, var(--SmartThemeBorderColor));; | 4084 | border-color: color-mix(in srgb, var(--SmartThemeQuoteColor) 50%, var(--SmartThemeBorderColor)); |
| 4025 | } | 4085 | } |
| 4026 | 4086 | ||
| 4027 | #lock_persona_to_char.locked { | 4087 | #lock_persona_to_char.locked { |
| @@ -5091,7 +5151,7 @@ body:not(.sd) .mes_img_swipes { | |||
| 5091 | display: flex; | 5151 | display: flex; |
| 5092 | flex-direction: column; | 5152 | flex-direction: column; |
| 5093 | justify-content: center; | 5153 | justify-content: center; |
| 5094 | padding: 10px; | 5154 | padding: 0px; |
| 5095 | height: 100%; | 5155 | height: 100%; |
| 5096 | width: 100%; | 5156 | width: 100%; |
| 5097 | } | 5157 | } |
| @@ -5700,6 +5760,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5700 | width: unset; | 5760 | width: unset; |
| 5701 | margin: 0; | 5761 | margin: 0; |
| 5702 | font-size: calc(var(--mainFontSize) * 0.85); | 5762 | font-size: calc(var(--mainFontSize) * 0.85); |
| 5763 | padding-right: 20px; | ||
| 5703 | } | 5764 | } |
| 5704 | 5765 | ||
| 5705 | .paginationjs-pages ul li a { | 5766 | .paginationjs-pages ul li a { |
| @@ -6033,12 +6094,12 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 6033 | flex-wrap: nowrap; | 6094 | flex-wrap: nowrap; |
| 6034 | justify-content: space-between; | 6095 | justify-content: space-between; |
| 6035 | align-items: center; | 6096 | align-items: center; |
| 6036 | gap: 10px; | 6097 | gap: 5px; |
| 6037 | padding: 0 2px; | ||
| 6038 | } | 6098 | } |
| 6039 | 6099 | ||
| 6040 | .mes_text div[data-type="assistant_note"]:has(.assistant_note_export)>div:not(.assistant_note_export) { | 6100 | .mes_text div[data-type="assistant_note"]:has(.assistant_note_export)>div { |
| 6041 | flex: 1; | 6101 | flex: 1; |
| 6102 | text-align: left; | ||
| 6042 | } | 6103 | } |
| 6043 | 6104 | ||
| 6044 | .oneline-dropdown label { | 6105 | .oneline-dropdown label { |
| @@ -1,393 +1,15 @@ | |||
| 1 | #!/usr/bin/env node | 1 | #!/usr/bin/env node |
| 2 | |||
| 3 | // native node modules | ||
| 4 | import path from 'node:path'; | ||
| 5 | import util from 'node:util'; | ||
| 6 | import net from 'node:net'; | ||
| 7 | import dns from 'node:dns'; | ||
| 8 | import process from 'node:process'; | ||
| 9 | import { fileURLToPath } from 'node:url'; | ||
| 10 | |||
| 11 | import cors from 'cors'; | ||
| 12 | import { csrfSync } from 'csrf-sync'; | ||
| 13 | import express from 'express'; | ||
| 14 | import compression from 'compression'; | ||
| 15 | import cookieSession from 'cookie-session'; | ||
| 16 | import multer from 'multer'; | ||
| 17 | import responseTime from 'response-time'; | ||
| 18 | import helmet from 'helmet'; | ||
| 19 | import bodyParser from 'body-parser'; | ||
| 20 | import open from 'open'; | ||
| 21 | |||
| 22 | // local library imports | ||
| 23 | import './src/fetch-patch.js'; | ||
| 24 | import { serverEvents, EVENT_NAMES } from './src/server-events.js'; | ||
| 25 | import { CommandLineParser } from './src/command-line.js'; | 2 | import { CommandLineParser } from './src/command-line.js'; |
| 26 | import { loadPlugins } from './src/plugin-loader.js'; | ||
| 27 | import { | ||
| 28 | initUserStorage, | ||
| 29 | getCookieSecret, | ||
| 30 | getCookieSessionName, | ||
| 31 | ensurePublicDirectoriesExist, | ||
| 32 | getUserDirectoriesList, | ||
| 33 | migrateSystemPrompts, | ||
| 34 | migrateUserData, | ||
| 35 | requireLoginMiddleware, | ||
| 36 | setUserDataMiddleware, | ||
| 37 | shouldRedirectToLogin, | ||
| 38 | cleanUploads, | ||
| 39 | getSessionCookieAge, | ||
| 40 | verifySecuritySettings, | ||
| 41 | loginPageMiddleware, | ||
| 42 | } from './src/users.js'; | ||
| 43 | |||
| 44 | import getWebpackServeMiddleware from './src/middleware/webpack-serve.js'; | ||
| 45 | import basicAuthMiddleware from './src/middleware/basicAuth.js'; | ||
| 46 | import getWhitelistMiddleware from './src/middleware/whitelist.js'; | ||
| 47 | import accessLoggerMiddleware, { getAccessLogPath, migrateAccessLog } from './src/middleware/accessLogWriter.js'; | ||
| 48 | import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js'; | ||
| 49 | import initRequestProxy from './src/request-proxy.js'; | ||
| 50 | import getCacheBusterMiddleware from './src/middleware/cacheBuster.js'; | ||
| 51 | import corsProxyMiddleware from './src/middleware/corsProxy.js'; | ||
| 52 | import { | ||
| 53 | getVersion, | ||
| 54 | color, | ||
| 55 | removeColorFormatting, | ||
| 56 | getSeparator, | ||
Diff truncated