Merge branch 'staging' into top-nsigma
| @@ -229,6 +229,46 @@ SillyTavern сохраняет ключи от ваших API в файле `sec | |||
| 229 | 1. Зайдите в файл `config.yaml` и установите `allowKeysExposure` в положение `true`. | 229 | 1. Зайдите в файл `config.yaml` и установите `allowKeysExposure` в положение `true`. |
| 230 | 2. Перезапустите сервер SillyTavern. | 230 | 2. Перезапустите сервер SillyTavern. |
| 231 | 231 | ||
| 232 | ## Аргументы командной строки | ||
| 233 | |||
| 234 | Вы можете передавать аргументы командной строки при запуске сервера SillyTavern, чтобы переопределять настройки из `config.yaml`. | ||
| 235 | |||
| 236 | ### Примеры | ||
| 237 | |||
| 238 | ```shell | ||
| 239 | node server.js --port 8000 --listen false | ||
| 240 | # или | ||
| 241 | npm run start -- --port 8000 --listen false | ||
| 242 | # или (только на Windows) | ||
| 243 | Start.bat --port 8000 --listen false | ||
| 244 | ``` | ||
| 245 | |||
| 246 | ### Поддерживаемые аргументы | ||
| 247 | |||
| 248 | | Аргумент | Описание | Тип | | ||
| 249 | |-------------------------|----------------------------------------------------------------------------------------------------------------|----------| | ||
| 250 | | `--version` | Показывает номер версии. | boolean | | ||
| 251 | | `--enableIPv6` | Включает IPv6. | boolean | | ||
| 252 | | `--enableIPv4` | Включает IPv4. | boolean | | ||
| 253 | | `--port` | Устанавливает порт, котрый будет использовать SillyTavern. Если не указан, то используется yaml-конфиг 'port'. | number | | ||
| 254 | | `--dnsPreferIPv6` | Отдает предпочтение IPv6 для dns. Если не указан, то используется yaml-конфиг 'preferIPv6'. | boolean | | ||
| 255 | | `--autorun` | Автоматический запуск SillyTavern в браузере. Если не указан, то используется yaml-конфиг 'autorun'. | boolean | | ||
| 256 | | `--autorunHostname` | Имя хоста автозапуска, лучше оставить на 'auto'. | string | | ||
| 257 | | `--autorunPortOverride` | Переопределяет порт для автозапуска. | string | | ||
| 258 | | `--listen` | SillyTavern будет прослушивать все сетевые интерфейсы. Если не указан, то используется yaml-конфиг 'listen'. | boolean | | ||
| 259 | | `--corsProxy` | Включает CORS-прокси. Если не указан, то используется yaml-конфиг 'enableCorsProxy'. | boolean | | ||
| 260 | | `--disableCsrf` | Отключает защиту от CSRF. | boolean | | ||
| 261 | | `--ssl` | Включает SSL. | boolean | | ||
| 262 | | `--certPath` | Путь к файлу c сертификатом. | string | | ||
| 263 | | `--keyPath` | Путь к файлу с закрытым ключом. | string | | ||
| 264 | | `--whitelist` | Включает режим белого списка. | boolean | | ||
| 265 | | `--dataRoot` | Корневой каталог для хранения данных. | string | | ||
| 266 | | `--avoidLocalhost` | Избегает использования 'localhost' для автозапуска в режиме 'auto'. | boolean | | ||
| 267 | | `--basicAuthMode` | Включает простую аутентификацию. | boolean | | ||
| 268 | | `--requestProxyEnabled` | Разрешает использование прокси для исходящих запросов. | boolean | | ||
| 269 | | `--requestProxyUrl` | URL-адрес прокси (протоколы HTTP или SOCKS). | string | | ||
| 270 | | `--requestProxyBypass` | Bypass список прокси (список хостов, разделенных пробелами). | array | | ||
| 271 | |||
| 232 | ## Удалённое подключение | 272 | ## Удалённое подключение |
| 233 | 273 | ||
| 234 | В основном этим пользуются тогда, когда хотят использовать SillyTavern с телефона, запустив сервер SillyTavern на стационарном ПК в той же Wi-Fi-сети. | 274 | В основном этим пользуются тогда, когда хотят использовать SillyTavern с телефона, запустив сервер SillyTavern на стационарном ПК в той же Wi-Fi-сети. |
| @@ -91,9 +91,6 @@ | |||
| 91 | <div class="margin0 title_restorable standoutHeader"> | 91 | <div class="margin0 title_restorable standoutHeader"> |
| 92 | <strong> | 92 | <strong> |
| 93 | <span data-i18n="kobldpresets">Kobold Presets</span> | 93 | <span data-i18n="kobldpresets">Kobold Presets</span> |
| 94 | <a href="https://docs.sillytavern.app/usage/api-connections/koboldai/" class="notes-link" target="_blank"> | ||
| 95 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 96 | </a> | ||
| 97 | </strong> | 94 | </strong> |
| 98 | 95 | ||
| 99 | <div class="flex-container gap3px"> | 96 | <div class="flex-container gap3px"> |
| @@ -1973,7 +1970,7 @@ | |||
| 1973 | </div> | 1970 | </div> |
| 1974 | </div> | 1971 | </div> |
| 1975 | </div> | 1972 | </div> |
| 1976 | <div class="range-block m-t-1" data-source="openai,openrouter,scale"> | 1973 | <div class="range-block m-t-1" data-source="openai,openrouter,scale,custom"> |
| 1977 | <div id="logit_bias_openai" class="range-block-title openai_restorable" data-i18n="Logit Bias"> | 1974 | <div id="logit_bias_openai" class="range-block-title openai_restorable" data-i18n="Logit Bias"> |
| 1978 | Logit Bias | 1975 | Logit Bias |
| 1979 | </div> | 1976 | </div> |
| @@ -2748,6 +2745,7 @@ | |||
| 2748 | </optgroup> | 2745 | </optgroup> |
| 2749 | <optgroup label="GPT-4o"> | 2746 | <optgroup label="GPT-4o"> |
| 2750 | <option value="gpt-4o">gpt-4o</option> | 2747 | <option value="gpt-4o">gpt-4o</option> |
| 2748 | <option value="gpt-4o-2024-11-20">gpt-4o-2024-11-20</option> | ||
| 2751 | <option value="gpt-4o-2024-08-06">gpt-4o-2024-08-06</option> | 2749 | <option value="gpt-4o-2024-08-06">gpt-4o-2024-08-06</option> |
| 2752 | <option value="gpt-4o-2024-05-13">gpt-4o-2024-05-13</option> | 2750 | <option value="gpt-4o-2024-05-13">gpt-4o-2024-05-13</option> |
| 2753 | <option value="chatgpt-4o-latest">chatgpt-4o-latest</option> | 2751 | <option value="chatgpt-4o-latest">chatgpt-4o-latest</option> |
| @@ -2815,9 +2813,6 @@ | |||
| 2815 | <option value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> | 2813 | <option value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> |
| 2816 | <option value="claude-2.1">claude-2.1</option> | 2814 | <option value="claude-2.1">claude-2.1</option> |
| 2817 | <option value="claude-2.0">claude-2.0</option> | 2815 | <option value="claude-2.0">claude-2.0</option> |
| 2818 | <option value="claude-1.3">claude-1.3</option> | ||
| 2819 | <option value="claude-instant-1.2">claude-instant-1.2</option> | ||
| 2820 | <option value="claude-instant-1.1">claude-instant-1.1</option> | ||
| 2821 | </optgroup> | 2816 | </optgroup> |
| 2822 | </select> | 2817 | </select> |
| 2823 | </div> | 2818 | </div> |
| @@ -2987,6 +2982,7 @@ | |||
| 2987 | <option value="chat-bison-001">PaLM 2 Chat (Legacy)</option> | 2982 | <option value="chat-bison-001">PaLM 2 Chat (Legacy)</option> |
| 2988 | </optgroup> | 2983 | </optgroup> |
| 2989 | <optgroup label="Subversions"> | 2984 | <optgroup label="Subversions"> |
| 2985 | <option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option> | ||
| 2990 | <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option> | 2986 | <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option> |
| 2991 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option> | 2987 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option> |
| 2992 | <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experiment 2024-08-27</option> | 2988 | <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experiment 2024-08-27</option> |
| @@ -3167,6 +3163,8 @@ | |||
| 3167 | <h4 data-i18n="Cohere Model">Cohere Model</h4> | 3163 | <h4 data-i18n="Cohere Model">Cohere Model</h4> |
| 3168 | <select id="model_cohere_select"> | 3164 | <select id="model_cohere_select"> |
| 3169 | <optgroup label="Stable"> | 3165 | <optgroup label="Stable"> |
| 3166 | <option value="c4ai-aya-expanse-32b">c4ai-aya-expanse-32b</option> | ||
| 3167 | <option value="c4ai-aya-expanse-8b">c4ai-aya-expanse-8b</option> | ||
| 3170 | <option value="c4ai-aya-23-35b">c4ai-aya-23-35b</option> | 3168 | <option value="c4ai-aya-23-35b">c4ai-aya-23-35b</option> |
| 3171 | <option value="c4ai-aya-23-8b">c4ai-aya-23-8b</option> | 3169 | <option value="c4ai-aya-23-8b">c4ai-aya-23-8b</option> |
| 3172 | <option value="command-light">command-light</option> | 3170 | <option value="command-light">command-light</option> |
| @@ -3278,8 +3276,14 @@ | |||
| 3278 | </div> | 3276 | </div> |
| 3279 | <div id="AdvancedFormatting" class="drawer-content"> | 3277 | <div id="AdvancedFormatting" class="drawer-content"> |
| 3280 | <div class="flex-container alignItemsBaseline"> | 3278 | <div class="flex-container alignItemsBaseline"> |
| 3281 | <h3 class="margin0 flex1" data-i18n="Advanced Formatting"> | 3279 | <h3 class="margin0 flex1 flex-container alignItemsBaseline"> |
| 3280 | <span data-i18n="Advanced Formatting"> | ||
| 3282 | Advanced Formatting | 3281 | Advanced Formatting |
| 3282 | </span> | ||
| 3283 | |||
| 3284 | <a href="https://docs.sillytavern.app/usage/prompts/" class="notes-link" target="_blank"> | ||
| 3285 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 3286 | </a> | ||
| 3283 | </h3> | 3287 | </h3> |
| 3284 | <div class="flex-container"> | 3288 | <div class="flex-container"> |
| 3285 | <input id="af_master_import_file" type="file" hidden accept=".json" class="displayNone"> | 3289 | <input id="af_master_import_file" type="file" hidden accept=".json" class="displayNone"> |
| @@ -3299,9 +3303,12 @@ | |||
| 3299 | <h4 class="standoutHeader title_restorable"> | 3303 | <h4 class="standoutHeader title_restorable"> |
| 3300 | <div> | 3304 | <div> |
| 3301 | <span data-i18n="Context Template">Context Template</span> | 3305 | <span data-i18n="Context Template">Context Template</span> |
| 3302 | <a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#context-template" class="notes-link" target="_blank"> | 3306 | </div> |
| 3303 | <span class="fa-solid fa-circle-question note-link-span"></span> | 3307 | <div class="flex-container"> |
| 3304 | </a> | 3308 | <label for="context_derived" class="checkbox_label flex1" title="Derive from Model Metadata, if possible." data-i18n="[title]context_derived"> |
| 3309 | <input id="context_derived" type="checkbox" style="display:none;" /> | ||
| 3310 | <small><i class="fa-solid fa-bolt menu_button margin0"></i></small> | ||
| 3311 | </label> | ||
| 3305 | </div> | 3312 | </div> |
| 3306 | </h4> | 3313 | </h4> |
| 3307 | <div class="flex-container" title="Select your current Context Template" data-i18n="[title]Select your current Context Template"> | 3314 | <div class="flex-container" title="Select your current Context Template" data-i18n="[title]Select your current Context Template"> |
| @@ -3398,11 +3405,12 @@ | |||
| 3398 | <h4 class="standoutHeader title_restorable justifySpaceBetween"> | 3405 | <h4 class="standoutHeader title_restorable justifySpaceBetween"> |
| 3399 | <div class="flex-container"> | 3406 | <div class="flex-container"> |
| 3400 | <span data-i18n="Instruct Template">Instruct Template</span> | 3407 | <span data-i18n="Instruct Template">Instruct Template</span> |
| 3401 | <a href="https://docs.sillytavern.app/usage/core-concepts/instructmode/" class="notes-link" target="_blank"> | ||
| 3402 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 3403 | </a> | ||
| 3404 | </div> | 3408 | </div> |
| 3405 | <div class="flex-container"> | 3409 | <div class="flex-container"> |
| 3410 | <label for="instruct_derived" class="checkbox_label flex1" title="Derive from Model Metadata, if possible." data-i18n="[title]instruct_derived"> | ||
| 3411 | <input id="instruct_derived" type="checkbox" style="display:none;" /> | ||
| 3412 | <small><i class="fa-solid fa-bolt menu_button margin0"></i></small> | ||
| 3413 | </label> | ||
| 3406 | <label for="instruct_bind_to_context" class="checkbox_label flex1" title="Bind to Context
If enabled, Context templates will be automatically selected based on selected Instruct template name or by preference." data-i18n="[title]instruct_bind_to_context"> | 3414 | <label for="instruct_bind_to_context" class="checkbox_label flex1" title="Bind to Context
If enabled, Context templates will be automatically selected based on selected Instruct template name or by preference." data-i18n="[title]instruct_bind_to_context"> |
| 3407 | <input id="instruct_bind_to_context" type="checkbox" style="display:none;" /> | 3415 | <input id="instruct_bind_to_context" type="checkbox" style="display:none;" /> |
| 3408 | <small><i class="fa-solid fa-link menu_button margin0"></i></small> | 3416 | <small><i class="fa-solid fa-link menu_button margin0"></i></small> |
| @@ -3583,9 +3591,6 @@ | |||
| 3583 | <h4 class="standoutHeader title_restorable justifySpaceBetween"> | 3591 | <h4 class="standoutHeader title_restorable justifySpaceBetween"> |
| 3584 | <div class="flex-container"> | 3592 | <div class="flex-container"> |
| 3585 | <span data-i18n="System Prompt">System Prompt</span> | 3593 | <span data-i18n="System Prompt">System Prompt</span> |
| 3586 | <a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#system-prompt" class="notes-link" target="_blank"> | ||
| 3587 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 3588 | </a> | ||
| 3589 | </div> | 3594 | </div> |
| 3590 | <div class="flex-container"> | 3595 | <div class="flex-container"> |
| 3591 | <label id="sysprompt_enabled_label" for="sysprompt_enabled" class="checkbox_label flex1" title="Enable System Prompt" data-i18n="[title]sysprompt_enabled"> | 3596 | <label id="sysprompt_enabled_label" for="sysprompt_enabled" class="checkbox_label flex1" title="Enable System Prompt" data-i18n="[title]sysprompt_enabled"> |
| @@ -3653,7 +3658,7 @@ | |||
| 3653 | <div name="tokenizerSettingsBlock"> | 3658 | <div name="tokenizerSettingsBlock"> |
| 3654 | <div name="tokenizerSelectorBlock"> | 3659 | <div name="tokenizerSelectorBlock"> |
| 3655 | <h4 class="standoutHeader"><span data-i18n="Tokenizer">Tokenizer</span> | 3660 | <h4 class="standoutHeader"><span data-i18n="Tokenizer">Tokenizer</span> |
| 3656 | <a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#tokenizer" class="notes-link" target="_blank"> | 3661 | <a href="https://docs.sillytavern.app/usage/prompts/tokenizer/" class="notes-link" target="_blank"> |
| 3657 | <span class="fa-solid fa-circle-question note-link-span"></span> | 3662 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 3658 | </a> | 3663 | </a> |
| 3659 | </h4> | 3664 | </h4> |
| @@ -3679,10 +3684,8 @@ | |||
| 3679 | </div> | 3684 | </div> |
| 3680 | <div class="range-block flex-container flexnowrap" name="tokenPaddingBlock"> | 3685 | <div class="range-block flex-container flexnowrap" name="tokenPaddingBlock"> |
| 3681 | <div class="range-block-title justifyLeft"> | 3686 | <div class="range-block-title justifyLeft"> |
| 3682 | <small data-i18n="Token Padding" class="flex-container">Token Padding | 3687 | <small data-i18n="Token Padding"> |
| 3683 | <a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#token-padding" class="notes-link" target="_blank"> | 3688 | Token Padding |
| 3684 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 3685 | </a> | ||
| 3686 | </small> | 3689 | </small> |
| 3687 | </div> | 3690 | </div> |
| 3688 | <input id="token_padding" class="text_pole textarea_compact" type="number" min="-2048" max="2048" /> | 3691 | <input id="token_padding" class="text_pole textarea_compact" type="number" min="-2048" max="2048" /> |
| @@ -3740,7 +3743,7 @@ | |||
| 3740 | </div> | 3743 | </div> |
| 3741 | <h3 class="margin0"> | 3744 | <h3 class="margin0"> |
| 3742 | <span data-i18n="Worlds/Lorebooks">Worlds/Lorebooks</span> | 3745 | <span data-i18n="Worlds/Lorebooks">Worlds/Lorebooks</span> |
| 3743 | <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/" class="notes-link" target="_blank"> | 3746 | <a href="https://docs.sillytavern.app/usage/worldinfo/" class="notes-link" target="_blank"> |
| 3744 | <span class="fa-solid fa-circle-question note-link-span"></span> | 3747 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 3745 | </a> | 3748 | </a> |
| 3746 | </h3> | 3749 | </h3> |
| @@ -4267,7 +4270,7 @@ | |||
| 4267 | <audio id="audio_message_sound" src="sounds/message.mp3" hidden></audio> | 4270 | <audio id="audio_message_sound" src="sounds/message.mp3" hidden></audio> |
| 4268 | <span> | 4271 | <span> |
| 4269 | <small data-i18n="Message Sound">Message Sound</small> | 4272 | <small data-i18n="Message Sound">Message Sound</small> |
| 4270 | <a href="https://docs.sillytavern.app/usage/core-concepts/uicustomization/#message-sound" class="notes-link" target="_blank"> | 4273 | <a href="https://docs.sillytavern.app/usage/user_settings/uicustomization/#message-sound" class="notes-link" target="_blank"> |
| 4271 | <span class="fa-solid fa-circle-question note-link-span"></span> | 4274 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 4272 | </a> | 4275 | </a> |
| 4273 | </span> | 4276 | </span> |
| @@ -4484,7 +4487,7 @@ | |||
| 4484 | </div> | 4487 | </div> |
| 4485 | <div nane="AutoContiueBlock" class="inline-drawer wide100p flexFlowColumn"> | 4488 | <div nane="AutoContiueBlock" class="inline-drawer wide100p flexFlowColumn"> |
| 4486 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically 'continue' a response if the model stopped before reaching a certain amount of tokens."> | 4489 | <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically 'continue' a response if the model stopped before reaching a certain amount of tokens."> |
| 4487 | <b><span data-i18n="Auto-swipe">Auto-Continue</span></b> | 4490 | <b><span data-i18n="Auto-Continue">Auto-Continue</span></b> |
| 4488 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | 4491 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> |
| 4489 | </div> | 4492 | </div> |
| 4490 | <div class="inline-drawer-content"> | 4493 | <div class="inline-drawer-content"> |
| @@ -5799,7 +5802,7 @@ | |||
| 5799 | <div class="flex-container justifySpaceBetween"> | 5802 | <div class="flex-container justifySpaceBetween"> |
| 5800 | <small for="group"> | 5803 | <small for="group"> |
| 5801 | <span data-i18n="Inclusion Group">Inclusion Group</span> | 5804 | <span data-i18n="Inclusion Group">Inclusion Group</span> |
| 5802 | <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered. Supports multiple comma-separated groups. Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group"> | 5805 | <a href="https://docs.sillytavern.app/usage/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered. Supports multiple comma-separated groups. Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group"> |
| 5803 | <span class="fa-solid fa-circle-question note-link-span"></span> | 5806 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 5804 | </a> | 5807 | </a> |
| 5805 | </small> | 5808 | </small> |
| @@ -1,13 +1,13 @@ | |||
| 1 | { | 1 | { |
| 2 | "Favorite": "가장 좋아하는", | 2 | "Favorite": "가장 좋아하는", |
| 3 | "Tag": "꼬리표", | 3 | "Tag": "태그", |
| 4 | "Duplicate": "복제하다", | 4 | "Duplicate": "복제하기", |
| 5 | "Persona": "페르소나", | 5 | "Persona": "페르소나", |
| 6 | "Delete": "삭제", | 6 | "Delete": "삭제", |
| 7 | "AI Response Configuration": "AI 응답 구성", | 7 | "AI Response Configuration": "AI 응답 구성", |
| 8 | "AI Configuration panel will stay open": "AI 구성 패널이 열린 상태로 유지됩니다", | 8 | "AI Configuration panel will stay open": "AI 구성 패널이 열린 상태로 유지됩니다", |
| 9 | "clickslidertips": "수동으로 값을 입력하려면 클릭하세요.", | 9 | "clickslidertips": "수동으로 값을 입력하려면 클릭하세요.", |
| 10 | "MAD LAB MODE ON": "매드랩 모드 켜짐", | 10 | "MAD LAB MODE ON": "미치광이 연구실 모드 켜짐", |
| 11 | "Documentation on sampling parameters": "샘플링 매개 변수에 대한 문서", | 11 | "Documentation on sampling parameters": "샘플링 매개 변수에 대한 문서", |
| 12 | "kobldpresets": "코볼드 사전 설정", | 12 | "kobldpresets": "코볼드 사전 설정", |
| 13 | "guikoboldaisettings": "KoboldAI 인터페이스 설정", | 13 | "guikoboldaisettings": "KoboldAI 인터페이스 설정", |
| @@ -24,26 +24,26 @@ | |||
| 24 | "AI Module": "AI 모듈", | 24 | "AI Module": "AI 모듈", |
| 25 | "Changes the style of the generated text.": "생성된 텍스트의 스타일을 변경합니다.", | 25 | "Changes the style of the generated text.": "생성된 텍스트의 스타일을 변경합니다.", |
| 26 | "No Module": "모듈 없음", | 26 | "No Module": "모듈 없음", |
| 27 | "Instruct": "지시하다", | 27 | "Instruct": "지시", |
| 28 | "Prose Augmenter": "산문 증강기", | 28 | "Prose Augmenter": "산문 증강기", |
| 29 | "Text Adventure": "텍스트 어드벤처", | 29 | "Text Adventure": "텍스트 어드벤처", |
| 30 | "response legth(tokens)": "응답 길이 (토큰)", | 30 | "response legth(tokens)": "응답 길이 (토큰)", |
| 31 | "Streaming": "스트리밍", | 31 | "Streaming": "스트리밍", |
| 32 | "Streaming_desc": "생성되는대로 응답을 조금씩 표시하십시오", | 32 | "Streaming_desc": "생성되는대로 응답을 조금씩 표시하세요", |
| 33 | "context size(tokens)": "컨텍스트 크기 (토큰)", | 33 | "context size(tokens)": "컨텍스트 크기 (토큰)", |
| 34 | "unlocked": "잠금 해제됨", | 34 | "unlocked": "잠금 해제됨", |
| 35 | "Only enable this if your model supports context sizes greater than 8192 tokens": "모델이 8192 토큰보다 큰 컨텍스트 크기를 지원하는 경우에만 활성화하십시오", | 35 | "Only enable this if your model supports context sizes greater than 8192 tokens": "모델이 8192 토큰보다 큰 컨텍스트 크기를 지원하는 경우에만 활성화하세요", |
| 36 | "Max prompt cost:": "최대 프롬프트 비용:", | 36 | "Max prompt cost:": "최대 프롬프트 비용:", |
| 37 | "Display the response bit by bit as it is generated.": "생성되는 대답을 조금씩 표시합니다.", | 37 | "Display the response bit by bit as it is generated.": "생성되는 대답을 조금씩 표시합니다.", |
| 38 | "When this is off, responses will be displayed all at once when they are complete.": "이 기능이 꺼져 있으면 대답은 완료되면 한 번에 모두 표시됩니다.", | 38 | "When this is off, responses will be displayed all at once when they are complete.": "이 기능이 꺼져 있으면 대답은 완료되면 한 번에 모두 표시됩니다.", |
| 39 | "Temperature": "온도", | 39 | "Temperature": "온도", |
| 40 | "rep.pen": "반복 패널티", | 40 | "rep.pen": "반복 페널티", |
| 41 | "Rep. Pen. Range.": "반복 벌칙 범위", | 41 | "Rep. Pen. Range.": "반복 페널티 범위", |
| 42 | "Rep. Pen. Slope": "대표적 패널티 기울기", | 42 | "Rep. Pen. Slope": "대표적 페널티 기울기", |
| 43 | "Rep. Pen. Freq.": "반복 벌칙 빈도", | 43 | "Rep. Pen. Freq.": "반복 페널티 빈도", |
| 44 | "Rep. Pen. Presence": "반복 벌칙 존재", | 44 | "Rep. Pen. Presence": "반복 페널티 존재", |
| 45 | "TFS": "TFS", | 45 | "TFS": "TFS", |
| 46 | "Phrase Repetition Penalty": "구절 반복 패널티", | 46 | "Phrase Repetition Penalty": "구절 반복 페널티", |
| 47 | "Off": "끄기", | 47 | "Off": "끄기", |
| 48 | "Very light": "매우 가벼운", | 48 | "Very light": "매우 가벼운", |
| 49 | "Light": "가벼운", | 49 | "Light": "가벼운", |
| @@ -51,17 +51,17 @@ | |||
| 51 | "Aggressive": "공격적", | 51 | "Aggressive": "공격적", |
| 52 | "Very aggressive": "매우 공격적", | 52 | "Very aggressive": "매우 공격적", |
| 53 | "Unlocked Context Size": "잠금 해제된 컨텍스트 크기", | 53 | "Unlocked Context Size": "잠금 해제된 컨텍스트 크기", |
| 54 | "Unrestricted maximum value for the context slider": "컨텍스트 슬라이더의 제한 없는 최대값", | 54 | "Unrestricted maximum value for the context slider": "컨텍스트 슬라이더에 대한 제한 없는 최대값", |
| 55 | "Context Size (tokens)": "컨텍스트 크기 (토큰)", | 55 | "Context Size (tokens)": "컨텍스트 크기 (토큰)", |
| 56 | "Max Response Length (tokens)": "최대 응답 길이 (토큰)", | 56 | "Max Response Length (tokens)": "최대 응답 길이 (토큰)", |
| 57 | "Multiple swipes per generation": "세대당 다중 스와이프", | 57 | "Multiple swipes per generation": "세대당 다중 스와이프", |
| 58 | "Enable OpenAI completion streaming": "OpenAI 완성 스트리밍 활성화", | 58 | "Enable OpenAI completion streaming": "OpenAI 완성 스트리밍 활성화", |
| 59 | "Frequency Penalty": "빈도 패널티", | 59 | "Frequency Penalty": "빈도 페널티", |
| 60 | "Presence Penalty": "존재 패널티", | 60 | "Presence Penalty": "존재 페널티", |
| 61 | "Count Penalty": "카운트 페널티", | 61 | "Count Penalty": "카운트 페널티", |
| 62 | "Top K": "상위 K", | 62 | "Top K": "상위 K", |
| 63 | "Top P": "상위 P", | 63 | "Top P": "상위 P", |
| 64 | "Repetition Penalty": "반복 벌칙", | 64 | "Repetition Penalty": "반복 페널티", |
| 65 | "Min P": "최소 P", | 65 | "Min P": "최소 P", |
| 66 | "Top A": "상위 A", | 66 | "Top A": "상위 A", |
| 67 | "Quick Prompts Edit": "빠른 프롬프트 편집", | 67 | "Quick Prompts Edit": "빠른 프롬프트 편집", |
| @@ -69,12 +69,12 @@ | |||
| 69 | "NSFW": "NSFW", | 69 | "NSFW": "NSFW", |
| 70 | "Jailbreak": "탈옥", | 70 | "Jailbreak": "탈옥", |
| 71 | "Utility Prompts": "유틸리티 프롬프트", | 71 | "Utility Prompts": "유틸리티 프롬프트", |
| 72 | "Impersonation prompt": "피소하는 프롬프트", | 72 | "Impersonation prompt": "사칭 프롬프트", |
| 73 | "Restore default prompt": "기본 프롬프트 복원", | 73 | "Restore default prompt": "기본 프롬프트 복원", |
| 74 | "Prompt that is used for Impersonation function": "피소 기능에 사용되는 프롬프트", | 74 | "Prompt that is used for Impersonation function": "사칭 기능에 사용되는 프롬프트", |
| 75 | "World Info Format Template": "세계 정보 형식 템플릿", | 75 | "World Info Format Template": "월드 인포 형식 템플릿", |
| 76 | "Restore default format": "기본 형식 복원", | 76 | "Restore default format": "기본 형식 복원", |
| 77 | "Wraps activated World Info entries before inserting into the prompt.": "프롬프트에 삽입하기 전에 활성화된 세계 정보 항목을 래핑합니다.", | 77 | "Wraps activated World Info entries before inserting into the prompt.": "프롬프트에 삽입하기 전에 활성화된 월드 인포 항목을 래핑합니다.", |
| 78 | "scenario_format_template_part_1": "사용", | 78 | "scenario_format_template_part_1": "사용", |
| 79 | "scenario_format_template_part_2": "내용이 삽입된 위치를 표시합니다.", | 79 | "scenario_format_template_part_2": "내용이 삽입된 위치를 표시합니다.", |
| 80 | "Scenario Format Template": "시나리오 형식 템플릿", | 80 | "Scenario Format Template": "시나리오 형식 템플릿", |
| @@ -94,7 +94,7 @@ | |||
| 94 | "Replace empty message": "빈 메시지 대체", | 94 | "Replace empty message": "빈 메시지 대체", |
| 95 | "Send this text instead of nothing when the text box is empty.": "텍스트 상자가 비어 있을 때 이 텍스트를 아무것도 없이 보내세요.", | 95 | "Send this text instead of nothing when the text box is empty.": "텍스트 상자가 비어 있을 때 이 텍스트를 아무것도 없이 보내세요.", |
| 96 | "Seed": "시드", | 96 | "Seed": "시드", |
| 97 | "Set to get deterministic results. Use -1 for random seed.": "결정적인 결과를 얻으려면 설정하세요. 무작위 시드에는 -1을 사용합니다.", | 97 | "Set to get deterministic results. Use -1 for random seed.": "결정적인 결과를 얻으려면 설정하세요. 무작위 시드를 위해서는 -1 값을 사용합니다.", |
| 98 | "Temperature controls the randomness in token selection": "온도는 토큰 선택에서의 무작위성을 제어합니다.", | 98 | "Temperature controls the randomness in token selection": "온도는 토큰 선택에서의 무작위성을 제어합니다.", |
| 99 | "Top_K_desc": "Top K는 선택할 수 있는 최대 상위 토큰 양을 설정합니다.", | 99 | "Top_K_desc": "Top K는 선택할 수 있는 최대 상위 토큰 양을 설정합니다.", |
| 100 | "Top_P_desc": "Top P (일명 핵심 샘플링)", | 100 | "Top_P_desc": "Top P (일명 핵심 샘플링)", |
| @@ -103,60 +103,60 @@ | |||
| 103 | "Min_P_desc": "Min P는 기본 최소 확률을 설정합니다.", | 103 | "Min_P_desc": "Min P는 기본 최소 확률을 설정합니다.", |
| 104 | "Top_A_desc": "Top A는 가장 높은 토큰 확률의 제곱에 기반하여 토큰 선택에 대한 임계값을 설정합니다.", | 104 | "Top_A_desc": "Top A는 가장 높은 토큰 확률의 제곱에 기반하여 토큰 선택에 대한 임계값을 설정합니다.", |
| 105 | "Tail_Free_Sampling_desc": "꼬리 제거 샘플링 (TFS)", | 105 | "Tail_Free_Sampling_desc": "꼬리 제거 샘플링 (TFS)", |
| 106 | "rep.pen range": "반복 패널티 범위", | 106 | "rep.pen range": "반복 페널티 범위", |
| 107 | "Mirostat": "미로스타트", | 107 | "Mirostat": "Mirostat", |
| 108 | "Mode": "방법", | 108 | "Mode": "모드", |
| 109 | "Mirostat_Mode_desc": "값이 0이면 Mirostat가 완전히 비활성화됩니다. 1은 Mirostat 1.0용이고 2는 Mirostat 2.0용입니다.", | 109 | "Mirostat_Mode_desc": "값이 0이면 Mirostat가 완전히 비활성화됩니다. 1은 Mirostat 1.0용이고 2는 Mirostat 2.0용입니다.", |
| 110 | "Tau": "타우", | 110 | "Tau": "Tau", |
| 111 | "Mirostat_Tau_desc": "Mirostat 출력의 가변성을 제어합니다.", | 111 | "Mirostat_Tau_desc": "Mirostat 출력의 가변성을 제어합니다.", |
| 112 | "Eta": "에타", | 112 | "Eta": "Eta", |
| 113 | "Mirostat_Eta_desc": "Mirostat의 학습률을 제어합니다.", | 113 | "Mirostat_Eta_desc": "Mirostat의 학습률을 제어합니다.", |
| 114 | "Ban EOS Token": "EOS 토큰 금지", | 114 | "Ban EOS Token": "EOS 토큰 금지", |
| 115 | "Ban_EOS_Token_desc": "KoboldCpp가 포함된 EOS(End-of-Sequence) 토큰(및 KoboldAI가 포함된 다른 토큰도 가능)을 금지합니다.\r스토리 작성에 적합하지만 채팅 및 교육 모드에는 사용하면 안 됩니다.", | 115 | "Ban_EOS_Token_desc": "KoboldCpp가 포함된 EOS(End-of-Sequence) 토큰(및 KoboldAI가 포함된 다른 토큰도 가능)을 금지합니다.\r스토리 작성에 적합하지만 채팅 및 교육 모드에는 사용하면 안 됩니다.", |
| 116 | "GBNF Grammar": "GBNF 문법", | 116 | "GBNF Grammar": "GBNF 문법", |
| 117 | "Type in the desired custom grammar": "원하는 사용자 정의 문법을 입력하세요.", | 117 | "Type in the desired custom grammar": "원하는 사용자 정의 문법을 입력하세요.", |
| 118 | "Samplers Order": "샘플러 순서", | 118 | "Samplers Order": "샘플러 순서", |
| 119 | "Samplers will be applied in a top-down order. Use with caution.": "샘플러는 위에서 아래로 적용됩니다. 주의하여 사용하십시오.", | 119 | "Samplers will be applied in a top-down order. Use with caution.": "샘플러는 위에서 아래로 적용됩니다. 주의하여 사용하세요.", |
| 120 | "Tail Free Sampling": "꼬리가 자유로운 샘플링", | 120 | "Tail Free Sampling": "Tail Free 샘플링", |
| 121 | "Load koboldcpp order": "코볼드 CPP 순서로 로드", | 121 | "Load koboldcpp order": "kobold CPP 순서로 로드", |
| 122 | "Preamble": "전문", | 122 | "Preamble": "서두", |
| 123 | "Use style tags to modify the writing style of the output.": "스타일 태그를 사용하여 출력의 쓰기 스타일을 수정하십시오.", | 123 | "Use style tags to modify the writing style of the output.": "스타일 태그를 사용하여 출력의 쓰기 스타일을 수정하세요.", |
| 124 | "Banned Tokens": "금지된 토큰", | 124 | "Banned Tokens": "금지된 토큰", |
| 125 | "Sequences you don't want to appear in the output. One per line.": "출력에 나타나지 않길 원하는 시퀀스입니다. 한 줄에 하나씩.", | 125 | "Sequences you don't want to appear in the output. One per line.": "출력에 나타나지 않길 원하는 시퀀스입니다. 한 줄에 하나씩.", |
| 126 | "Logit Bias": "로그 비애", | 126 | "Logit Bias": "Logit 편향", |
| 127 | "Add": "추가", | 127 | "Add": "추가", |
| 128 | "Helps to ban or reenforce the usage of certain words": "특정 단어의 사용을 금지하거나 강화하는데 도움이 됩니다.", | 128 | "Helps to ban or reenforce the usage of certain words": "특정 단어의 사용을 금지하거나 강화하는데 도움이 됩니다.", |
| 129 | "CFG Scale": "CFG 스케일", | 129 | "CFG Scale": "CFG 스케일", |
| 130 | "Negative Prompt": "부정적인 프롬프트", | 130 | "Negative Prompt": "부정적 프롬프트", |
| 131 | "Add text here that would make the AI generate things you don't want in your outputs.": "AI가 출력에서 원하지 않는 것을 생성하도록하는 텍스트를 여기에 추가하십시오.", | 131 | "Add text here that would make the AI generate things you don't want in your outputs.": "AI가 출력에서 원하지 않는 것을 생성하도록하는 텍스트를 여기에 추가하세요.", |
| 132 | "Used if CFG Scale is unset globally, per chat or character": "CFG 스케일이 전역적으로 설정되지 않은 경우 사용됩니다. 채팅 당 또는 캐릭터 당", | 132 | "Used if CFG Scale is unset globally, per chat or character": "CFG 스케일이 전역적으로 설정되지 않은 경우, 각 채팅 또는 각 캐릭터마다 사용됩니다.", |
| 133 | "Mirostat Tau": "미로스탯 타우", | 133 | "Mirostat Tau": "Mirostat Tau", |
| 134 | "Mirostat LR": "미로스타트 LR", | 134 | "Mirostat LR": "Mirostat LR", |
| 135 | "Min Length": "최소 길이", | 135 | "Min Length": "최소 길이", |
| 136 | "Top K Sampling": "상위 K 샘플링", | 136 | "Top K Sampling": "상위 K 샘플링", |
| 137 | "Nucleus Sampling": "핵 샘플링", | 137 | "Nucleus Sampling": "Nucleus 샘플링", |
| 138 | "Top A Sampling": "상위 A 샘플링", | 138 | "Top A Sampling": "상위 A 샘플링", |
| 139 | "CFG": "CFG", | 139 | "CFG": "CFG", |
| 140 | "Neutralize Samplers": "샘플러 중화", | 140 | "Neutralize Samplers": "샘플러 중화", |
| 141 | "Set all samplers to their neutral/disabled state.": "모든 샘플러를 중립/비활성 상태로 설정하십시오.", | 141 | "Set all samplers to their neutral/disabled state.": "모든 샘플러를 중립/비활성 상태로 설정하세요.", |
| 142 | "Sampler Select": "샘플러 선택", | 142 | "Sampler Select": "샘플러 선택", |
| 143 | "Customize displayed samplers or add custom samplers.": "표시된 샘플러를 사용자 정의하거나 사용자 정의 샘플러를 추가하세요.", | 143 | "Customize displayed samplers or add custom samplers.": "표시된 샘플러를 사용자 정의하거나 사용자 정의 샘플러를 추가하세요.", |
| 144 | "Epsilon Cutoff": "이프실론 자르기", | 144 | "Epsilon Cutoff": "Epsilon 자르기", |
| 145 | "Epsilon cutoff sets a probability floor below which tokens are excluded from being sampled": "Epsilon 절단은 토큰이 샘플링에서 제외되는 확률 하한선을 설정합니다.", | 145 | "Epsilon cutoff sets a probability floor below which tokens are excluded from being sampled": "Epsilon 절단은 토큰이 샘플링에서 제외되는 확률 하한선을 설정합니다.", |
| 146 | "Eta Cutoff": "에타 자르기", | 146 | "Eta Cutoff": "Eta 자르기", |
| 147 | "Eta_Cutoff_desc": "에타 절단은 특별한 에타 샘플링 기술의 주요 매개 변수입니다. 1e-4 단위로; 합리적인 값은 3입니다. 비활성화하려면 0으로 설정하십시오. 자세한 내용은 Hewitt et al. (2022)의 Truncation Sampling as Language Model Desmoothing 논문을 참조하십시오.", | 147 | "Eta_Cutoff_desc": "Eta 절단은 특별한 Eta 샘플링 기술의 주요 매개 변수입니다. 1e-4 단위로; 합리적인 값은 3입니다. 비활성화하려면 0으로 설정하세요. 자세한 내용은 Hewitt et al. (2022)의 Truncation Sampling as Language Model Desmoothing 논문을 참조하세요.", |
| 148 | "rep.pen decay": "대표 펜 부패", | 148 | "rep.pen decay": "반복 페널티 붕괴", |
| 149 | "Encoder Rep. Pen.": "인코더 반복 패널티", | 149 | "Encoder Rep. Pen.": "인코더 반복 페널티", |
| 150 | "No Repeat Ngram Size": "반복 없는 N그램 크기", | 150 | "No Repeat Ngram Size": "반복 없는 Ngram 크기", |
| 151 | "Skew": "비스듬한", | 151 | "Skew": "비스듬한", |
| 152 | "Max Tokens Second": "최대 토큰 초", | 152 | "Max Tokens Second": "초당 최대 토큰", |
| 153 | "Smooth Sampling": "부드러운 샘플링", | 153 | "Smooth Sampling": "부드러운 샘플링", |
| 154 | "Smooth_Sampling_desc": "2차/3차 변환을 사용하여 분포를 조정할 수 있습니다. 평활화 요소 값이 낮을수록 더 창의적이 됩니다. 일반적으로 0.2-0.3 사이가 가장 적합합니다(곡선 = 1로 가정). 평활화 곡선 값이 높을수록 곡선이 더 가파르게 변하고 확률이 낮은 선택을 더욱 적극적으로 처벌하게 됩니다. 1.0 곡선은 Smoothing Factor만 사용하는 것과 같습니다.", | 154 | "Smooth_Sampling_desc": "2차/3차 변환을 사용하여 분포를 조정할 수 있습니다. 평활화 요소 값이 낮을수록 더 창의적이 됩니다. 일반적으로 0.2-0.3 사이가 가장 적합합니다(곡선 = 1로 가정). 평활화 곡선 값이 높을수록 곡선이 더 가파르게 변하고 확률이 낮은 선택을 더욱 적극적으로 처벌하게 됩니다. 1.0 곡선은 Smoothing Factor만 사용하는 것과 같습니다.", |
| 155 | "Smoothing Factor": "평활화 요소", | 155 | "Smoothing Factor": "평활화 요소", |
| 156 | "Smoothing Curve": "평활화 곡선", | 156 | "Smoothing Curve": "평활화 곡선", |
| 157 | "DRY_Repetition_Penalty_desc": "DRY는 입력의 끝을 이전에 입력에서 발생한 시퀀스로 확장하는 토큰에 페널티를 적용합니다. 비활성화하려면 승수를 0으로 설정하세요.", | 157 | "DRY_Repetition_Penalty_desc": "DRY는 입력의 끝을 이전에 입력에서 발생한 시퀀스로 확장하는 토큰에 페널티를 적용합니다. 비활성화하려면 승수를 0으로 설정하세요.", |
| 158 | "DRY Repetition Penalty": "DRY 반복 페널티", | 158 | "DRY Repetition Penalty": "DRY 반복 페널티", |
| 159 | "DRY_Multiplier_desc": "DRY를 활성화하려면 값 > 0으로 설정하십시오. 가장 짧은 페널티를 받는 시퀀스에 대한 페널티의 크기를 제어합니다.", | 159 | "DRY_Multiplier_desc": "DRY를 활성화하려면 값 > 0으로 설정하세요. 가장 짧은 페널티를 받는 시퀀스에 대한 페널티의 크기를 제어합니다.", |
| 160 | "Multiplier": "승수", | 160 | "Multiplier": "승수", |
| 161 | "DRY_Base_desc": "시퀀스 길이가 증가함에 따라 페널티가 증가하는 속도를 제어합니다.", | 161 | "DRY_Base_desc": "시퀀스 길이가 증가함에 따라 페널티가 증가하는 속도를 제어합니다.", |
| 162 | "Base": "베이스", | 162 | "Base": "베이스", |
| @@ -172,23 +172,23 @@ | |||
| 172 | "Maximum Temp": "최대 온도", | 172 | "Maximum Temp": "최대 온도", |
| 173 | "Exponent": "지수", | 173 | "Exponent": "지수", |
| 174 | "Mirostat (mode=1 is only for llama.cpp)": "Mirostat (mode=1은 llama.cpp 전용입니다)", | 174 | "Mirostat (mode=1 is only for llama.cpp)": "Mirostat (mode=1은 llama.cpp 전용입니다)", |
| 175 | "Mirostat_desc": "미로스타트는 출력 헷갈림의 온도계입니다", | 175 | "Mirostat_desc": "Mirostat은 언어 모델의 출력 텍스트의 복잡도(perplexity)를 직접 제어하여 더 자연스러운 텍스트를 생성하도록 하는 적응형 샘플링 알고리즘입니다", |
| 176 | "Mirostat Mode": "미로스탯 모드", | 176 | "Mirostat Mode": "Mirostat 모드", |
| 177 | "Variability parameter for Mirostat outputs": "미로스탯 출력의 변동성 매개변수", | 177 | "Variability parameter for Mirostat outputs": "Mirostat 출력의 변동성 매개변수", |
| 178 | "Mirostat Eta": "미로스탯 에타", | 178 | "Mirostat Eta": "Mirostat Eta", |
| 179 | "Learning rate of Mirostat": "미로스탯의 학습률", | 179 | "Learning rate of Mirostat": "Mirostat 학습률", |
| 180 | "Beam search": "빔 검색", | 180 | "Beam search": "빔 검색", |
| 181 | "Helpful tip coming soon.": "유용한 팁을 곧 알려드리겠습니다.", | 181 | "Helpful tip coming soon.": "유용한 팁을 곧 알려드리겠습니다.", |
| 182 | "Number of Beams": "빔의 수", | 182 | "Number of Beams": "빔의 수", |
| 183 | "Length Penalty": "길이 패널티", | 183 | "Length Penalty": "길이 페널티", |
| 184 | "Early Stopping": "조기 중지", | 184 | "Early Stopping": "조기 중지", |
| 185 | "Contrastive search": "대조적 검색", | 185 | "Contrastive search": "대조적 검색", |
| 186 | "Penalty Alpha": "패널티 알파", | 186 | "Penalty Alpha": "페널티 알파", |
| 187 | "Strength of the Contrastive Search regularization term. Set to 0 to disable CS": "대조적 검색 정규화 항의 강도입니다. CS를 비활성화하려면 0으로 설정하세요.", | 187 | "Strength of the Contrastive Search regularization term. Set to 0 to disable CS": "대조적 검색 정규화 항의 강도입니다. CS를 비활성화하려면 0으로 설정하세요.", |
| 188 | "Do Sample": "샘플", | 188 | "Do Sample": "샘플", |
| 189 | "Add BOS Token": "BOS 토큰 추가", | 189 | "Add BOS Token": "BOS 토큰 추가", |
| 190 | "Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative": "프롬프트의 시작 부분에 bos_token을 추가하십시오. 이를 비활성화하면 응답이 더 창의적으로 될 수 있습니다.", | 190 | "Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative": "프롬프트의 시작 부분에 bos_token을 추가하세요. 이를 비활성화하면 응답이 더 창의적으로 될 수 있습니다.", |
| 191 | "Ban the eos_token. This forces the model to never end the generation prematurely": "eos_token을 금지하십시오. 이는 모델이 생성을 이르게 종료하지 않도록 합니다", | 191 | "Ban the eos_token. This forces the model to never end the generation prematurely": "eos_token을 금지하세요. 이는 모델이 생성을 이르게 종료하지 않도록 합니다", |
| 192 | "Ignore EOS Token": "EOS 토큰 무시", | 192 | "Ignore EOS Token": "EOS 토큰 무시", |
| 193 | "Ignore the EOS Token even if it generates.": "EOS 토큰이 생성되더라도 무시하세요.", | 193 | "Ignore the EOS Token even if it generates.": "EOS 토큰이 생성되더라도 무시하세요.", |
| 194 | "Skip Special Tokens": "특수 토큰 건너뛰기", | 194 | "Skip Special Tokens": "특수 토큰 건너뛰기", |
| @@ -210,25 +210,27 @@ | |||
| 210 | "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.": "llama.cpp만 가능합니다. 샘플러의 순서를 결정합니다. Mirostat 모드가 0이 아닌 경우 샘플러 순서는 무시됩니다.", | 210 | "llama.cpp only. Determines the order of samplers. If Mirostat mode is not 0, sampler order is ignored.": "llama.cpp만 가능합니다. 샘플러의 순서를 결정합니다. Mirostat 모드가 0이 아닌 경우 샘플러 순서는 무시됩니다.", |
| 211 | "Sampler Priority": "샘플러 우선 순위", | 211 | "Sampler Priority": "샘플러 우선 순위", |
| 212 | "Ooba only. Determines the order of samplers.": "Ooba 전용. 샘플러의 순서를 결정합니다.", | 212 | "Ooba only. Determines the order of samplers.": "Ooba 전용. 샘플러의 순서를 결정합니다.", |
| 213 | "Character Names Behavior": "캐릭터 이름 행동", | 213 | "Character Names Behavior": "캐릭터 이름 동작", |
| 214 | "[title]character_names_none": "캐릭터 이름 접두사를 추가하지 않습니다. 그룹 채팅에서는 좋지 않을 수 있으므로, 이 설정을 선택할 때는 주의해야 합니다.", | ||
| 214 | "Helps the model to associate messages with characters.": "모델이 메시지를 캐릭터와 연관시키는 데 도움이 됩니다.", | 215 | "Helps the model to associate messages with characters.": "모델이 메시지를 캐릭터와 연관시키는 데 도움이 됩니다.", |
| 215 | "None": "없음", | 216 | "None": "없음", |
| 216 | "character_names_default": "그룹 및 과거 페르소나는 제외됩니다. 그렇지 않으면 프롬프트에 이름을 제공해야 합니다.", | 217 | "None (not injected)": "없음 (삽입되지 않음)", |
| 218 | "character_names_default": "그룹과 과거 페르소나에 대해 접두사를 추가합니다. 그 외의 경우에는 프롬프트에 이름을 직접 제공해야 합니다.", | ||
| 217 | "Don't add character names.": "캐릭터 이름을 추가하지 마세요.", | 219 | "Don't add character names.": "캐릭터 이름을 추가하지 마세요.", |
| 218 | "Completion": "완료 객체", | 220 | "Completion": "완료 객체", |
| 219 | "character_names_completion": "제한 사항이 적용됩니다. 라틴 영숫자 및 밑줄만 사용할 수 있습니다. 모든 소스, 특히 Claude, MistralAI, Google에서 작동하지 않습니다.", | 221 | "character_names_completion": "제한 사항이 적용됩니다. 라틴 알파벳, 숫자, 밑줄만 사용 가능합니다. 모든 소스, 특히 Claude, MistralAI, Google에서 작동하지 않습니다.", |
| 220 | "Add character names to completion objects.": "완성 개체에 캐릭터 이름을 추가합니다.", | 222 | "Add character names to completion objects.": "완성 객체에 캐릭터 이름을 추가합니다.", |
| 221 | "Message Content": "메시지 내용", | 223 | "Message Content": "메시지 내용", |
| 222 | "Prepend character names to message contents.": "메시지 내용 앞에 문자 이름을 추가합니다.", | 224 | "Prepend character names to message contents.": "메시지 내용 앞에 캐릭터의 이름을 추가합니다.", |
| 223 | "Continue Postfix": "접미사 계속하기", | 225 | "Continue Postfix": "계속하기 접미사", |
| 224 | "The next chunk of the continued message will be appended using this as a separator.": "계속되는 메시지의 다음 청크는 이를 구분 기호로 사용하여 추가됩니다.", | 226 | "The next chunk of the continued message will be appended using this as a separator.": "계속되는 메시지의 다음 청크는 이를 구분 기호로 사용하여 추가됩니다.", |
| 225 | "Space": "공간", | 227 | "Space": "한 칸 띄우기", |
| 226 | "Newline": "개행", | 228 | "Newline": "새로운 줄", |
| 227 | "Double Newline": "이중 개행", | 229 | "Double Newline": "이중 줄", |
| 228 | "Wrap user messages in quotes before sending": "전송 전에 사용자 메시지를 따옴표로 둘러싸기", | 230 | "Wrap user messages in quotes before sending": "전송 전에 사용자 메시지를 따옴표로 둘러싸기", |
| 229 | "Wrap in Quotes": "따옴표 안에 넣기", | 231 | "Wrap in Quotes": "따옴표로 메시지 감싸기", |
| 230 | "Wrap entire user message in quotes before sending.": "전체 사용자 메시지를 보내기 전에 따옴표로 묶으십시오.", | 232 | "Wrap entire user message in quotes before sending.": "사용자 메시지 전체를 보내기 전에 따옴표로 감싸집니다.", |
| 231 | "Leave off if you use quotes manually for speech.": "말하기 위해 수동으로 따옴표를 사용하는 경우 무시하십시오.", | 233 | "Leave off if you use quotes manually for speech.": "말하기 위해 수동으로 따옴표를 사용하는 경우 체크하지 마세요.", |
| 232 | "Continue prefill": "사전 작성 계속", | 234 | "Continue prefill": "사전 작성 계속", |
| 233 | "Continue sends the last message as assistant role instead of system message with instruction.": "계속하면 지시와 함께 시스템 메시지 대신 마지막 메시지를 어시스턴트 역할로 보냅니다.", | 235 | "Continue sends the last message as assistant role instead of system message with instruction.": "계속하면 지시와 함께 시스템 메시지 대신 마지막 메시지를 어시스턴트 역할로 보냅니다.", |
| 234 | "Squash system messages": "시스템 메시지 압축", | 236 | "Squash system messages": "시스템 메시지 압축", |
| @@ -239,7 +241,7 @@ | |||
| 239 | "image_inlining_hint_2": "메시지에 대한 조치 또는", | 241 | "image_inlining_hint_2": "메시지에 대한 조치 또는", |
| 240 | "image_inlining_hint_3": "채팅에 이미지 파일을 첨부하는 메뉴입니다.", | 242 | "image_inlining_hint_3": "채팅에 이미지 파일을 첨부하는 메뉴입니다.", |
| 241 | "Inline Image Quality": "인라인 이미지 품질", | 243 | "Inline Image Quality": "인라인 이미지 품질", |
| 242 | "openai_inline_image_quality_auto": "자동차", | 244 | "openai_inline_image_quality_auto": "자동", |
| 243 | "openai_inline_image_quality_low": "낮은", | 245 | "openai_inline_image_quality_low": "낮은", |
| 244 | "openai_inline_image_quality_high": "높은", | 246 | "openai_inline_image_quality_high": "높은", |
| 245 | "Use AI21 Tokenizer": "AI21 토크나이저 사용", | 247 | "Use AI21 Tokenizer": "AI21 토크나이저 사용", |
| @@ -250,35 +252,35 @@ | |||
| 250 | "(Gemini 1.5 Pro/Flash only)": "(Gemini 1.5 Pro/Flash 전용)", | 252 | "(Gemini 1.5 Pro/Flash only)": "(Gemini 1.5 Pro/Flash 전용)", |
| 251 | "Merges_all_system_messages_desc_1": "비시스템 역할이 있는 첫 번째 메시지까지 모든 시스템 메시지를 병합하여", | 253 | "Merges_all_system_messages_desc_1": "비시스템 역할이 있는 첫 번째 메시지까지 모든 시스템 메시지를 병합하여", |
| 252 | "Merges_all_system_messages_desc_2": "필드.", | 254 | "Merges_all_system_messages_desc_2": "필드.", |
| 253 | "Assistant Prefill": "어시스턴트 사전 작성", | 255 | "Assistant Prefill": "어시스턴트 프리필", |
| 254 | "Start Claude's answer with...": "클로드의 답변 시작하기...", | 256 | "Start Claude's answer with...": "클로드의 답변 시작하기...", |
| 255 | "Assistant Impersonation Prefill": "보조자 가장 미리 채우기", | 257 | "Assistant Impersonation Prefill": "어시스턴트 사칭 프리필", |
| 256 | "Use system prompt (Claude 2.1+ only)": "시스템 프롬프트 사용 (클로드 2.1+ 전용)", | 258 | "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.": "지원되는 모델에 대한 시스템 프롬프트를 보냅니다. 비활성화된 경우 사용자 메시지가 프롬프트의 처음에 추가됩니다.", | 259 | "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "지원되는 모델에 대한 시스템 프롬프트를 보냅니다. 비활성화된 경우 사용자 메시지가 프롬프트의 처음에 추가됩니다.", |
| 258 | "User first message": "사용자 첫 번째 메시지", | 260 | "User first message": "사용자 첫 번째 메시지", |
| 259 | "Restore User first message": "사용자 우선 메시지 복원", | 261 | "Restore User first message": "사용자의 첫 번째 메시지 복원", |
| 260 | "Human message": "인간의 메시지, 지시 등\n비어 있으면 아무것도 추가하지 않습니다. 즉, '사용자' 역할이 있는 새 프롬프트가 필요합니다.", | 262 | "Human message": "인간 메시지, 지시 등\n비어 있으면 아무것도 추가하지 않습니다. 즉, '사용자' 역할이 있는 새 프롬프트가 필요합니다.", |
| 261 | "New preset": "새 프리셋", | 263 | "New preset": "새 프리셋", |
| 262 | "Delete preset": "프리셋 삭제", | 264 | "Delete preset": "프리셋 삭제", |
| 263 | "View / Edit bias preset": "바이어스 프리셋 보기/편집", | 265 | "View / Edit bias preset": "바이어스 프리셋 보기/편집", |
| 264 | "Add bias entry": "바이어스 항목 추가", | 266 | "Add bias entry": "바이어스 항목 추가", |
| 265 | "Most tokens have a leading space.": "대부분의 토큰에는 선행 공백이 있습니다.", | 267 | "Most tokens have a leading space.": "대부분의 토큰에는 선행 공백이 있습니다.", |
| 266 | "API Connections": "API 연결", | 268 | "API Connections": "API 연결", |
| 267 | "Text Completion": "텍스트 완성", | 269 | "Text Completion": "Text Completion", |
| 268 | "Chat Completion": "채팅 완료", | 270 | "Chat Completion": "Chat Completion", |
| 269 | "NovelAI": "NovelAI", | 271 | "NovelAI": "NovelAI", |
| 270 | "KoboldAI Horde": "KoboldAI 호드", | 272 | "KoboldAI Horde": "KoboldAI Horde", |
| 271 | "KoboldAI": "KoboldAI", | 273 | "KoboldAI": "KoboldAI", |
| 272 | "Avoid sending sensitive information to the Horde.": "민감한 정보를 호드에 보내지 마십시오.", | 274 | "Avoid sending sensitive information to the Horde.": "민감한 정보를 Horde에 보내지 않도록 합니다.", |
| 273 | "Review the Privacy statement": "개인 정보 보호 정책 검토", | 275 | "Review the Privacy statement": "개인 정보 보호 정책 검토", |
| 274 | "Register a Horde account for faster queue times": "더 빠른 대기 시간을 위해 호드 계정을 등록하십시오.", | 276 | "Register a Horde account for faster queue times": "대기 시간 감축을 원한다면 Horde 계정을 등록하세요.", |
| 275 | "Learn how to contribute your idle GPU cycles to the Horde": "여유로운 GPU 주기를 호드에 기여하는 방법 배우기", | 277 | "Learn how to contribute your idle GPU cycles to the Horde": "여유로운 GPU 주기를 Horde에 기여하는 방법 배우기", |
| 276 | "Adjust context size to worker capabilities": "컨텍스트 크기를 작업자 기능에 맞게 조정하십시오.", | 278 | "Adjust context size to worker capabilities": "컨텍스트 크기를 작업자 기능에 맞게 조정합니다.", |
| 277 | "Adjust response length to worker capabilities": "응답 길이를 작업자 기능에 맞게 조정하십시오.", | 279 | "Adjust response length to worker capabilities": "응답 길이를 작업자 기능에 맞게 조정합니다.", |
| 278 | "Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "승인된 작업자만을 대기열에 넣어 나쁜 응답을 처리할 수 있습니다. 응답 시간이 느려질 수 있습니다.", | 280 | "Can help with bad responses by queueing only the approved workers. May slowdown the response time.": "승인된 작업자만을 대기열에 넣어 나쁜 응답을 처리할 수 있습니다. 응답 시간이 느려질 수 있습니다.", |
| 279 | "Trusted workers only": "신뢰할 수 있는 작업자만", | 281 | "Trusted workers only": "신뢰할 수 있는 작업자만 허용", |
| 280 | "API key": "API 키", | 282 | "API key": "API 키", |
| 281 | "Get it here:": "여기서 얻으세요:", | 283 | "Get it here:": "여기에서 얻으세요:", |
| 282 | "Register": "등록", | 284 | "Register": "등록", |
| 283 | "View my Kudos": "내 Kudos 보기", | 285 | "View my Kudos": "내 Kudos 보기", |
| 284 | "Enter": "입력", | 286 | "Enter": "입력", |
| @@ -287,7 +289,7 @@ | |||
| 287 | "For privacy reasons, your API key will be hidden after you reload the page.": "개인 정보 보호를 위해 페이지를 다시로드한 후에는 API 키가 숨겨집니다.", | 289 | "For privacy reasons, your API key will be hidden after you reload the page.": "개인 정보 보호를 위해 페이지를 다시로드한 후에는 API 키가 숨겨집니다.", |
| 288 | "Models": "모델", | 290 | "Models": "모델", |
| 289 | "Refresh models": "모델 새로 고침", | 291 | "Refresh models": "모델 새로 고침", |
| 290 | "-- Horde models not loaded --": "-- 호드 모델 로드되지 않음 --", | 292 | "-- Horde models not loaded --": "-- Horde 모델 로드되지 않음 --", |
| 291 | "Not connected...": "연결되지 않음...", | 293 | "Not connected...": "연결되지 않음...", |
| 292 | "API url": "API URL", | 294 | "API url": "API URL", |
| 293 | "Example: http://127.0.0.1:5000/api ": "예시: http://127.0.0.1:5000/api", | 295 | "Example: http://127.0.0.1:5000/api ": "예시: http://127.0.0.1:5000/api", |
| @@ -295,9 +297,9 @@ | |||
| 295 | "Cancel": "취소", | 297 | "Cancel": "취소", |
| 296 | "Novel API key": "NovelAPI 키", | 298 | "Novel API key": "NovelAPI 키", |
| 297 | "Get your NovelAI API Key": "NovelAI API 키 가져오기", | 299 | "Get your NovelAI API Key": "NovelAI API 키 가져오기", |
| 298 | "Enter it in the box below": "아래 상자에 입력하세요", | 300 | "Enter it in the box below": "아래 칸에 복사한 API 키를 입력하세요.", |
| 299 | "Novel AI Model": "Novel AI 모델", | 301 | "Novel AI Model": "Novel AI 모델", |
| 300 | "No connection...": "연결 없음...", | 302 | "No connection...": "연결 되지 않음...", |
| 301 | "API Type": "API 유형", | 303 | "API Type": "API 유형", |
| 302 | "Default (completions compatible)": "기본값 [OpenAI /완성 호환: oobabooga, LM Studio 등]", | 304 | "Default (completions compatible)": "기본값 [OpenAI /완성 호환: oobabooga, LM Studio 등]", |
| 303 | "TogetherAI API Key": "TogetherAI API 키", | 305 | "TogetherAI API Key": "TogetherAI API 키", |
| @@ -310,10 +312,10 @@ | |||
| 310 | "Model Providers": "모델 제공자", | 312 | "Model Providers": "모델 제공자", |
| 311 | "InfermaticAI API Key": "InfermaticAI API 키", | 313 | "InfermaticAI API Key": "InfermaticAI API 키", |
| 312 | "InfermaticAI Model": "InfermaticAI 모델", | 314 | "InfermaticAI Model": "InfermaticAI 모델", |
| 313 | "DreamGen API key": "드림젠 API 키", | 315 | "DreamGen API key": "DreamGen API 키", |
| 314 | "DreamGen Model": "드림젠 모델", | 316 | "DreamGen Model": "DreamGen 모델", |
| 315 | "Mancer API key": "Mancer API 키", | 317 | "Mancer API key": "Mancer API 키", |
| 316 | "Mancer Model": "맨서 모델", | 318 | "Mancer Model": "Mancer 모델", |
| 317 | "Make sure you run it with": "실행하는지 확인하세요", | 319 | "Make sure you run it with": "실행하는지 확인하세요", |
| 318 | "flag": "깃발", | 320 | "flag": "깃발", |
| 319 | "API key (optional)": "API 키 (선택 사항)", | 321 | "API key (optional)": "API 키 (선택 사항)", |
| @@ -325,8 +327,8 @@ | |||
| 325 | "Example: 127.0.0.1:8000": "예: http://127.0.0.1:8000", | 327 | "Example: 127.0.0.1:8000": "예: http://127.0.0.1:8000", |
| 326 | "vLLM Model": "vLLM 모델", | 328 | "vLLM Model": "vLLM 모델", |
| 327 | "PygmalionAI/aphrodite-engine": "PygmalionAI/aphrodite-engine (OpenAI API의 래퍼 모드)", | 329 | "PygmalionAI/aphrodite-engine": "PygmalionAI/aphrodite-engine (OpenAI API의 래퍼 모드)", |
| 328 | "Aphrodite API key": "아프로디테 API 키", | 330 | "Aphrodite API key": "Aphrodite API 키", |
| 329 | "Aphrodite Model": "아프로디테 모델", | 331 | "Aphrodite Model": "Aphrodite 모델", |
| 330 | "ggerganov/llama.cpp": "ggerganov/llama.cpp (출력 서버)", | 332 | "ggerganov/llama.cpp": "ggerganov/llama.cpp (출력 서버)", |
| 331 | "Example: 127.0.0.1:8080": "예: 127.0.0.1:8080", | 333 | "Example: 127.0.0.1:8080": "예: 127.0.0.1:8080", |
| 332 | "Example: 127.0.0.1:11434": "예: 127.0.0.1:11434", | 334 | "Example: 127.0.0.1:11434": "예: 127.0.0.1:11434", |
| @@ -335,21 +337,23 @@ | |||
| 335 | "Tabby API key": "Tabby API 키", | 337 | "Tabby API key": "Tabby API 키", |
| 336 | "koboldcpp API key (optional)": "koboldcpp API 키(선택사항)", | 338 | "koboldcpp API key (optional)": "koboldcpp API 키(선택사항)", |
| 337 | "Example: 127.0.0.1:5001": "예: 127.0.0.1:5001", | 339 | "Example: 127.0.0.1:5001": "예: 127.0.0.1:5001", |
| 338 | "Authorize": "승인하다", | 340 | "Authorize": "승인하기", |
| 339 | "Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "OAuth 플로우를 사용하여 OpenRouter API 토큰을 가져옵니다. openrouter.ai로 리디렉션됩니다.", | 341 | "Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai": "OAuth 플로우를 사용하여 OpenRouter API 토큰을 가져옵니다. openrouter.ai로 리디렉션됩니다.", |
| 342 | "Legacy API (pre-OAI, no streaming)": "레거시 API (OAI 이전, 스트리밍 없음)", | ||
| 340 | "Bypass status check": "상태 확인 우회", | 343 | "Bypass status check": "상태 확인 우회", |
| 341 | "Chat Completion Source": "채팅 완성 소스", | 344 | "Chat Completion Source": "채팅 완성 근원", |
| 342 | "Reverse Proxy": "역방향 프록시", | 345 | "Reverse Proxy": "역방향 프록시", |
| 343 | "Proxy Presets": "프록시 사전 설정", | 346 | "Proxy Presets": "프록시 사전 설정", |
| 344 | "Saved addresses and passwords.": "저장된 주소와 비밀번호.", | 347 | "Saved addresses and passwords.": "저장된 주소와 비밀번호.", |
| 345 | "Save Proxy": "프록시 저장", | 348 | "Save Proxy": "프록시 저장", |
| 346 | "Delete Proxy": "프록시 삭제", | 349 | "Delete Proxy": "프록시 삭제", |
| 347 | "Proxy Name": "프록시 이름", | 350 | "Proxy Name": "프록시 이름", |
| 351 | "Allow reverse proxy": "역방향 프록시 허용", | ||
| 348 | "This will show up as your saved preset.": "이는 저장된 사전 설정으로 표시됩니다.", | 352 | "This will show up as your saved preset.": "이는 저장된 사전 설정으로 표시됩니다.", |
| 349 | "Proxy Server URL": "프록시 서버 URL", | 353 | "Proxy Server URL": "프록시 서버 URL", |
| 350 | "Alternative server URL (leave empty to use the default value).": "대체 서버 URL (기본값 사용을 원할 경우 비워 둡니다).", | 354 | "Alternative server URL (leave empty to use the default value).": "대체 서버 URL (기본값 사용을 원할 경우 비워 둡니다).", |
| 351 | "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "이 상자에 어떤 것이든 입력하기 전에 실제 OAI API 키를 API 패널에서 제거하세요.", | 355 | "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "이 입력란에 어떤 것이든 입력하기 전에 반드시 실제 OAI API 키를 API 패널에서 제거하세요.", |
| 352 | "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "비공식 OpenAI 프록시를 사용하는 동안 발생하는 문제에 대한 지원을 제공할 수 없습니다.", | 356 | "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "개발진은 비공식 OpenAI 프록시를 사용하는 동안 발생하는 문제에 대한 지원을 제공할 수 없습니다.", |
| 353 | "Doesn't work? Try adding": "작동하지 않나요? 추가해 보세요", | 357 | "Doesn't work? Try adding": "작동하지 않나요? 추가해 보세요", |
| 354 | "at the end!": "마지막에!", | 358 | "at the end!": "마지막에!", |
| 355 | "Proxy Password": "프록시 비밀번호", | 359 | "Proxy Password": "프록시 비밀번호", |
| @@ -357,25 +361,30 @@ | |||
| 357 | "Peek a password": "비밀번호를 엿보세요", | 361 | "Peek a password": "비밀번호를 엿보세요", |
| 358 | "OpenAI API key": "OpenAI API 키", | 362 | "OpenAI API key": "OpenAI API 키", |
| 359 | "View API Usage Metrics": "API 사용 지표 보기", | 363 | "View API Usage Metrics": "API 사용 지표 보기", |
| 360 | "Follow": "따르다", | 364 | "Follow": "OpenAI API 키를 얻으려면", |
| 361 | "these directions": "이 지시 사항", | 365 | "these directions": "이 지시 사항", |
| 362 | "to get your OpenAI API key.": "OpenAI API 키를 얻으려면.", | 366 | "to get your OpenAI API key.": "을 따르세요.", |
| 363 | "Use Proxy password field instead. This input will be ignored.": "대신 \"프록시 비밀번호\" 필드를 사용하세요. 이 입력은 무시됩니다.", | 367 | "Use Proxy password field instead. This input will be ignored.": "대신 \"프록시 비밀번호\" 필드를 사용하세요. 이 입력은 무시됩니다.", |
| 364 | "OpenAI Model": "OpenAI 모델", | 368 | "OpenAI Model": "OpenAI 모델", |
| 365 | "Bypass API status check": "API 상태 확인 우회", | 369 | "Bypass API status check": "API 상태 확인 우회", |
| 366 | "Show External models (provided by API)": "외부 모델 표시 (API 제공)", | 370 | "Show External models (provided by API)": "외부 모델 표시 (API 제공)", |
| 367 | "Get your key from": "다음에서 키를 받으세요", | 371 | "Get your key from": "다음에서 키를 받으세요", |
| 368 | "Anthropic's developer console": "Anthropic의 개발자 콘솔", | 372 | "Anthropic's developer console": "Anthropic의 개발자 콘솔", |
| 373 | "Slack and Poe cookies will not work here, do not bother trying.": "Slack과 Poe 쿠키는 여기서 작동하지 않습니다. 시도하지 마세요.", | ||
| 369 | "Claude Model": "Claude 모델", | 374 | "Claude Model": "Claude 모델", |
| 370 | "Window AI Model": "창 AI 모델", | 375 | "Window AI Model": "Window AI 모델", |
| 371 | "Model Order": "OpenRouter 모델 정렬", | 376 | "Model Order": "OpenRouter 모델 정렬", |
| 372 | "Alphabetically": "알파벳순", | 377 | "Alphabetically": "알파벳순", |
| 373 | "Price": "가격(가장 저렴)", | 378 | "Price": "가격(가장 저렴)", |
| 374 | "Context Size": "컨텍스트 크기", | 379 | "Context Size": "컨텍스트 크기", |
| 375 | "Group by vendors": "공급업체별 그룹화", | 380 | "Group by vendors": "공급업체별 그룹화", |
| 376 | "Group by vendors Description": "OpenAI 모델을 한 그룹에 넣고, Anthropic 모델을 다른 그룹에 두는 등 정렬을 통해 결합할 수 있습니다.", | 381 | "Group by vendors Description": "OpenAI 모델을 한 그룹에 넣고, Anthropic 모델을 다른 그룹에 두는 등 정렬을 통해 결합할 수 있습니다.", |
| 377 | "Allow fallback routes": "대체 경로 허용", | 382 | "Allow fallback routes": "fallback 허용", |
| 378 | "Allow fallback routes Description": "선택한 모델이 요청을 처리할 수 없는 경우 대체 모델이 자동으로 선택됩니다.", | 383 | "Allow fallback routes Description": "선택한 모델이 요청을 처리할 수 없는 경우 대체 모델이 자동으로 선택됩니다.", |
| 384 | "openrouter_force_instruct": "이 옵션은 오래되었으며 향후 제거될 예정입니다. 지시 형식을 사용하려면 대신 Text Completion API에서 OpenRouter로 전환하세요.", | ||
| 385 | "LEGACY": "유산", | ||
| 386 | "Force Instruct Mode formatting": "강제 지시 모드 형식", | ||
| 387 | "Force_Instruct_Mode_formatting_Description": "Instruct Mode와 이 모드가 모두 활성화된 경우 프롬프트는 SillyTavern에 의해 현재 형식을 사용하여 형식화됩니다.\n 고급 형식 설정(시스템 프롬프트 지시 제외) 비활성화된 경우 프롬프트는 OpenRouter에 의해 형식화됩니다.", | ||
| 379 | "Scale API Key": "Scale API 키", | 388 | "Scale API Key": "Scale API 키", |
| 380 | "Clear your cookie": "쿠키 지우기", | 389 | "Clear your cookie": "쿠키 지우기", |
| 381 | "Alt Method": "대체 방법", | 390 | "Alt Method": "대체 방법", |
| @@ -385,29 +394,30 @@ | |||
| 385 | "Google Model": "구글 모델", | 394 | "Google Model": "구글 모델", |
| 386 | "MistralAI API Key": "MistralAI API 키", | 395 | "MistralAI API Key": "MistralAI API 키", |
| 387 | "MistralAI Model": "MistralAI 모델", | 396 | "MistralAI Model": "MistralAI 모델", |
| 388 | "Groq API Key": "그로크 API 키", | 397 | "Groq API Key": "Groq API 키", |
| 389 | "Groq Model": "그로크 모델", | 398 | "Groq Model": "Groq 모델", |
| 390 | "Perplexity API Key": "Perplexity API 키", | 399 | "Perplexity API Key": "Perplexity API 키", |
| 391 | "Perplexity Model": "혼란 모델", | 400 | "Perplexity Model": "Perplexity 모델", |
| 392 | "Cohere API Key": "Cohere API 키", | 401 | "Cohere API Key": "Cohere API 키", |
| 393 | "Cohere Model": "Cohere 모델", | 402 | "Cohere Model": "Cohere 모델", |
| 394 | "Custom Endpoint (Base URL)": "사용자 정의 엔드포인트(기본 URL)", | 403 | "Custom Endpoint (Base URL)": "사용자 정의 엔드포인트(기본 URL)", |
| 395 | "Custom API Key": "커스텀 API 키", | 404 | "Custom API Key": "커스텀 API 키", |
| 396 | "Available Models": "사용 가능한 모델", | 405 | "Available Models": "사용 가능한 모델", |
| 397 | "Prompt Post-Processing": "신속한 후처리", | 406 | "Prompt Post-Processing": "신속한 후처리", |
| 407 | "[title]API Connections;[no_connection_text]api_no_connection": "연결이 되지 않았습니다...", | ||
| 398 | "Applies additional processing to the prompt before sending it to the API.": "API로 보내기 전에 프롬프트에 추가 처리를 적용합니다.", | 408 | "Applies additional processing to the prompt before sending it to the API.": "API로 보내기 전에 프롬프트에 추가 처리를 적용합니다.", |
| 399 | "Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "짧은 테스트 메시지를 보내어 API 연결을 확인합니다. 이에 대해 크레딧이 지급될 것임을 인식하십시오!", | 409 | "Verifies your API connection by sending a short test message. Be aware that you'll be credited for it!": "짧은 테스트 메시지를 보내어 API 연결을 확인합니다. 이에 대해 유료 크레딧이 지불될 수 있음을 인식하세요!", |
| 400 | "Test Message": "테스트 메시지", | 410 | "Test Message": "테스트 메시지", |
| 401 | "Auto-connect to Last Server": "마지막 서버에 자동으로 연결", | 411 | "Auto-connect to Last Server": "마지막 서버에 자동으로 연결", |
| 402 | "Missing key": "❌ 키 누락", | 412 | "Missing key": "❌ 현재 저장된 키가 존재하지 않습니다.", |
| 403 | "Key saved": "✔️ 키 저장됨", | 413 | "Key saved": "✔️ 키 저장됨.", |
| 404 | "View hidden API keys": "숨겨진 API 키 보기", | 414 | "View hidden API keys": "숨겨진 API 키 보기", |
| 405 | "AI Response Formatting": "AI 응답 형식 지정", | 415 | "AI Response Formatting": "AI 응답 형식 지정", |
| 406 | "Advanced Formatting": "고급 서식", | 416 | "Advanced Formatting": "고급 서식", |
| 407 | "Context Template": "컨텍스트 템플릿", | 417 | "Context Template": "컨텍스트 템플릿", |
| 408 | "Auto-select this preset for Instruct Mode": "지시 모드에 대해 이 프리셋 자동 선택", | 418 | "Auto-select this preset for Instruct Mode": "지시 모드에 대해 이 프리셋 자동 선택", |
| 409 | "Story String": "이야기 문자열", | 419 | "Story String": "이야기 문자열", |
| 410 | "Example Separator": "예제 구분자", | 420 | "Example Separator": "예시 대화 구분자", |
| 411 | "Chat Start": "채팅 시작", | 421 | "Chat Start": "채팅 시작", |
| 412 | "Add Chat Start and Example Separator to a list of stopping strings.": "중지 문자열 목록에 채팅 시작 및 예제 구분 기호를 추가합니다.", | 422 | "Add Chat Start and Example Separator to a list of stopping strings.": "중지 문자열 목록에 채팅 시작 및 예제 구분 기호를 추가합니다.", |
| 413 | "Use as Stop Strings": "중지 문자열로 사용", | 423 | "Use as Stop Strings": "중지 문자열로 사용", |
| @@ -415,10 +425,10 @@ | |||
| 415 | "Allow Jailbreak": "탈옥 허용", | 425 | "Allow Jailbreak": "탈옥 허용", |
| 416 | "Context Order": "컨텍스트 순서", | 426 | "Context Order": "컨텍스트 순서", |
| 417 | "Summary": "요약", | 427 | "Summary": "요약", |
| 418 | "Author's Note": "작성자 메모", | 428 | "Author's Note": "작가 노트", |
| 419 | "Example Dialogues": "예시 대화", | 429 | "Example Dialogues": "예시 대화", |
| 420 | "Hint": "힌트:", | 430 | "Hint": "힌트:", |
| 421 | "In-Chat Position not affected": "요약 및 작성자 메모 주문은 In-Chat 위치가 설정되지 않은 경우에만 영향을 받습니다.", | 431 | "In-Chat Position not affected": "요약 및 작가 노트 삽입 순서는 In-Chat 위치가 설정되지 않은 경우에만 영향을 받습니다.", |
| 422 | "Instruct Mode": "지시 모드", | 432 | "Instruct Mode": "지시 모드", |
| 423 | "Enabled": "활성화됨", | 433 | "Enabled": "활성화됨", |
| 424 | "instruct_bind_to_context": "활성화되면 선택한 지시 템플릿 이름이나 기본 설정에 따라 컨텍스트 템플릿이 자동으로 선택됩니다.", | 434 | "instruct_bind_to_context": "활성화되면 선택한 지시 템플릿 이름이나 기본 설정에 따라 컨텍스트 템플릿이 자동으로 선택됩니다.", |
| @@ -426,7 +436,7 @@ | |||
| 426 | "Presets": "프리셋", | 436 | "Presets": "프리셋", |
| 427 | "Auto-select this preset on API connection": "API 연결 시 이 프리셋 자동 선택", | 437 | "Auto-select this preset on API connection": "API 연결 시 이 프리셋 자동 선택", |
| 428 | "Activation Regex": "활성화 정규식", | 438 | "Activation Regex": "활성화 정규식", |
| 429 | "Wrap Sequences with Newline": "새 줄로 시퀀스 래핑", | 439 | "Wrap Sequences with Newline": "새 줄로 시퀀스 감싸기", |
| 430 | "Replace Macro in Sequences": "시퀀스에서 매크로 대체", | 440 | "Replace Macro in Sequences": "시퀀스에서 매크로 대체", |
| 431 | "Skip Example Dialogues Formatting": "예제 대화 형식 건너뛰기", | 441 | "Skip Example Dialogues Formatting": "예제 대화 형식 건너뛰기", |
| 432 | "Include Names": "이름 포함", | 442 | "Include Names": "이름 포함", |
| @@ -454,9 +464,9 @@ | |||
| 454 | "If enabled, System Sequences will be the same as User Sequences.": "이 기능을 활성화하면, 시스템 시퀀스가 사용자 시퀀스와 동일해집니다.", | 464 | "If enabled, System Sequences will be the same as User Sequences.": "이 기능을 활성화하면, 시스템 시퀀스가 사용자 시퀀스와 동일해집니다.", |
| 455 | "System same as User": "사용자와 동일한 시스템", | 465 | "System same as User": "사용자와 동일한 시스템", |
| 456 | "Misc. Sequences": "기타 시퀀스", | 466 | "Misc. Sequences": "기타 시퀀스", |
| 457 | "Inserted before the first Assistant's message.": "첫 번째 보조자의 메시지 앞에 삽입됩니다.", | 467 | "Inserted before the first Assistant's message.": "어시스턴트의 첫 번째 메시지 앞에 삽입됩니다.", |
| 458 | "First Assistant Prefix": "첫 번째 어시스턴트 접두어", | 468 | "First Assistant Prefix": "첫 번째 어시스턴트 접두어", |
| 459 | "instruct_last_output_sequence": "마지막 보조자의 메시지 앞에 삽입되거나 AI 응답을 생성할 때 마지막 프롬프트 줄로 삽입됩니다(중립/시스템 역할 제외).", | 469 | "instruct_last_output_sequence": "마지막 어시스턴트 메시지 앞에 삽입되거나 AI 응답을 생성할 때 마지막 프롬프트 줄로 삽입됩니다(중립/시스템 역할 제외).", |
| 460 | "Last Assistant Prefix": "마지막 어시스턴트 접두사", | 470 | "Last Assistant Prefix": "마지막 어시스턴트 접두사", |
| 461 | "Will be inserted as a last prompt line when using system/neutral generation.": "시스템/중립 생성을 사용할 때 마지막 프롬프트 라인으로 삽입됩니다.", | 471 | "Will be inserted as a last prompt line when using system/neutral generation.": "시스템/중립 생성을 사용할 때 마지막 프롬프트 라인으로 삽입됩니다.", |
| 462 | "System Instruction Prefix": "시스템 명령어 접두사", | 472 | "System Instruction Prefix": "시스템 명령어 접두사", |
| @@ -483,15 +493,15 @@ | |||
| 483 | "Custom Stopping Strings": "사용자 정의 중지 문자열", | 493 | "Custom Stopping Strings": "사용자 정의 중지 문자열", |
| 484 | "JSON serialized array of strings": "문자열의 JSON 직렬화된 배열", | 494 | "JSON serialized array of strings": "문자열의 JSON 직렬화된 배열", |
| 485 | "Replace Macro in Custom Stopping Strings": "사용자 정의 중단 문자열에서 매크로 교체", | 495 | "Replace Macro in Custom Stopping Strings": "사용자 정의 중단 문자열에서 매크로 교체", |
| 486 | "Auto-Continue": "자동 계속", | 496 | "Auto-Continue": "자동 계속하기", |
| 487 | "Allow for Chat Completion APIs": "채팅 완성 API 허용", | 497 | "Allow for Chat Completion APIs": "채팅 완성 API 허용", |
| 488 | "Target length (tokens)": "대상 길이 (토큰)", | 498 | "Target length (tokens)": "대상 길이 (토큰)", |
| 489 | "World Info": "세계 정보", | 499 | "World Info": "월드 인포", |
| 490 | "Locked = World Editor will stay open": "잠금 = 월드 편집기가 열린 상태로 유지됩니다", | 500 | "Locked = World Editor will stay open": "잠금 = 월드 편집기가 열린 상태로 유지됩니다", |
| 491 | "Worlds/Lorebooks": "세계/로어북", | 501 | "Worlds/Lorebooks": "월드 인포/로어북", |
| 492 | "Active World(s) for all chats": "모든 채팅에 대한 활성 세계(들)", | 502 | "Active World(s) for all chats": "모든 채팅에 대한 활성화된 월드 인포(들)", |
| 493 | "-- World Info not found --": "-- 세계 정보를 찾을 수 없음 --", | 503 | "-- World Info not found --": "-- 월드 인포를 찾을 수 없음 --", |
| 494 | "Global World Info/Lorebook activation settings": "글로벌 세계 정보/전설집 활성화 설정", | 504 | "Global World Info/Lorebook activation settings": "글로벌 월드 인포/로어북 활성화 설정", |
| 495 | "Click to expand": "펼치려면 클릭하세요.", | 505 | "Click to expand": "펼치려면 클릭하세요.", |
| 496 | "Scan Depth": "스캔 깊이", | 506 | "Scan Depth": "스캔 깊이", |
| 497 | "Context %": "컨텍스트 %", | 507 | "Context %": "컨텍스트 %", |
| @@ -513,22 +523,22 @@ | |||
| 513 | "Match Whole Words": "전체 단어 일치", | 523 | "Match Whole Words": "전체 단어 일치", |
| 514 | "Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "포함 그룹 필터링을 위해 키 일치 수가 가장 많은 항목만 선택됩니다.", | 524 | "Only the entries with the most number of key matches will be selected for Inclusion Group filtering": "포함 그룹 필터링을 위해 키 일치 수가 가장 많은 항목만 선택됩니다.", |
| 515 | "Use Group Scoring": "그룹 점수 사용", | 525 | "Use Group Scoring": "그룹 점수 사용", |
| 516 | "Alert if your world info is greater than the allocated budget.": "귀하의 세계 정보가 할당된 예산보다 큰 경우 경고합니다.", | 526 | "Alert if your world info is greater than the allocated budget.": "귀하의 월드 인포가 할당된 예산보다 큰 경우 경고합니다.", |
| 517 | "Alert On Overflow": "오버플로우 알림", | 527 | "Alert On Overflow": "오버플로우 알림", |
| 518 | "New": "새로운", | 528 | "New": "새 월드인포", |
| 519 | "or": "또는", | 529 | "or": "또는", |
| 520 | "--- Pick to Edit ---": "--- 편집할 항목 선택 ---", | 530 | "--- Pick to Edit ---": "--- 편집할 항목 선택 ---", |
| 521 | "Rename World Info": "월드 정보 이름 바꾸기", | 531 | "Rename World Info": "월드 인포 이름 바꾸기", |
| 522 | "Open all Entries": "모든 항목 열기", | 532 | "Open all Entries": "모든 항목 열기", |
| 523 | "Close all Entries": "모든 항목 닫기", | 533 | "Close all Entries": "모든 항목 닫기", |
| 524 | "New Entry": "새 항목", | 534 | "New Entry": "새 항목", |
| 525 | "Fill empty Memo/Titles with Keywords": "비어 있는 메모/제목을 키워드로 채우기", | 535 | "Fill empty Memo/Titles with Keywords": "비어 있는 메모/제목을 키워드로 채우기", |
| 526 | "Import World Info": "월드 정보 가져오기", | 536 | "Import World Info": "월드 인포 가져오기", |
| 527 | "Export World Info": "월드 정보 내보내기", | 537 | "Export World Info": "월드 인포 내보내기", |
| 528 | "Duplicate World Info": "월드 정보 복제", | 538 | "Duplicate World Info": "월드 인포 복제", |
| 529 | "Delete World Info": "월드 정보 삭제", | 539 | "Delete World Info": "월드 인포 삭제", |
| 530 | "Search...": "검색...", | 540 | "Search...": "검색...", |
| 531 | "Search": "찾다", | 541 | "Search": "찾기", |
| 532 | "Priority": "우선 순위", | 542 | "Priority": "우선 순위", |
| 533 | "Custom": "사용자 정의", | 543 | "Custom": "사용자 정의", |
| 534 | "Title A-Z": "제목 A-Z", | 544 | "Title A-Z": "제목 A-Z", |
| @@ -537,12 +547,12 @@ | |||
| 537 | "Tokens ↘": "토큰 ↘", | 547 | "Tokens ↘": "토큰 ↘", |
| 538 | "Depth ↗": "깊이 ↗", | 548 | "Depth ↗": "깊이 ↗", |
| 539 | "Depth ↘": "깊이 ↘", | 549 | "Depth ↘": "깊이 ↘", |
| 540 | "Order ↗": "주문 ↗", | 550 | "Order ↗": "순서 ↗", |
| 541 | "Order ↘": "주문 ↘", | 551 | "Order ↘": "순서 ↘", |
| 542 | "UID ↗": "UID ↗", | 552 | "UID ↗": "UID ↗", |
| 543 | "UID ↘": "UID ↘", | 553 | "UID ↘": "UID ↘", |
| 544 | "Trigger% ↗": "트리거% ↗", | 554 | "Trigger% ↗": "발동 확률% ↗", |
| 545 | "Trigger% ↘": "트리거% ↘", | 555 | "Trigger% ↘": "발동 확률% ↘", |
| 546 | "Refresh": "새로 고침", | 556 | "Refresh": "새로 고침", |
| 547 | "User Settings": "사용자 설정", | 557 | "User Settings": "사용자 설정", |
| 548 | "Simple": "간단한", | 558 | "Simple": "간단한", |
| @@ -558,7 +568,7 @@ | |||
| 558 | "Delete a theme": "테마 삭제", | 568 | "Delete a theme": "테마 삭제", |
| 559 | "Update a theme file": "테마 파일 업데이트", | 569 | "Update a theme file": "테마 파일 업데이트", |
| 560 | "Save as a new theme": "새 테마로 저장", | 570 | "Save as a new theme": "새 테마로 저장", |
| 561 | "Avatar Style": "아바타 스타일", | 571 | "Avatar Style": "캐릭터 프로필 스타일", |
| 562 | "Circle": "원", | 572 | "Circle": "원", |
| 563 | "Square": "정사각형", | 573 | "Square": "정사각형", |
| 564 | "Rectangle": "사각형", | 574 | "Rectangle": "사각형", |
| @@ -578,7 +588,7 @@ | |||
| 578 | "UI Border": "UI 테두리", | 588 | "UI Border": "UI 테두리", |
| 579 | "User Message Blur Tint": "사용자 메시지 흐림 틴트", | 589 | "User Message Blur Tint": "사용자 메시지 흐림 틴트", |
| 580 | "AI Message Blur Tint": "AI 메시지 흐림 틴트", | 590 | "AI Message Blur Tint": "AI 메시지 흐림 틴트", |
| 581 | "Chat Width": "채팅 폭", | 591 | "Chat Width": "채팅창 폭", |
| 582 | "Width of the main chat window in % of screen width": "화면 너비의 %로 표시되는 기본 채팅창 너비", | 592 | "Width of the main chat window in % of screen width": "화면 너비의 %로 표시되는 기본 채팅창 너비", |
| 583 | "Font Scale": "글꼴 크기", | 593 | "Font Scale": "글꼴 크기", |
| 584 | "Font size": "글꼴 크기", | 594 | "Font size": "글꼴 크기", |
| @@ -594,50 +604,53 @@ | |||
| 594 | "No Text Shadows": "텍스트 그림자 없음", | 604 | "No Text Shadows": "텍스트 그림자 없음", |
| 595 | "Reduce chat height, and put a static sprite behind the chat window": "채팅 높이를 줄이고, 채팅 창 뒤에 정적 스프라이트를 넣습니다", | 605 | "Reduce chat height, and put a static sprite behind the chat window": "채팅 높이를 줄이고, 채팅 창 뒤에 정적 스프라이트를 넣습니다", |
| 596 | "Waifu Mode": "와이프 모드", | 606 | "Waifu Mode": "와이프 모드", |
| 597 | "Always show the full list of the Message Actions context items for chat messages, instead of hiding them behind '...'": "채팅 메시지의 메시지 액션 컨텍스트 항목의 전체 목록을 항상 표시하십시오. 대신 '...' 뒤에 숨기지 않습니다.", | 607 | "Always show the full list of the Message Actions context items for chat messages, instead of hiding them behind '...'": "채팅 메시지의 메시지 액션 컨텍스트 항목의 전체 목록을 항상 표시하세요. 대신 '...' 뒤에 숨기지 않습니다.", |
| 598 | "Auto-Expand Message Actions": "메시지 액션 자동 확장", | 608 | "Auto-Expand Message Actions": "메시지 액션 자동 확장", |
| 599 | "Alternative UI for numeric sampling parameters with fewer steps": "단계가 적은 숫자 샘플링 매개변수에 대한 대체 UI", | 609 | "Alternative UI for numeric sampling parameters with fewer steps": "단계가 적은 숫자 샘플링 매개변수에 대한 대체 UI", |
| 600 | "Zen Sliders": "젠 슬라이더", | 610 | "Zen Sliders": "젠 슬라이더", |
| 601 | "Entirely unrestrict all numeric sampling parameters": "모든 숫자 샘플링 매개변수를 완전히 제한하지 않음", | 611 | "Entirely unrestrict all numeric sampling parameters": "모든 숫자 샘플링 매개변수를 완전히 제한하지 않음", |
| 602 | "Mad Lab Mode": "미치광이 랩 모드", | 612 | "Mad Lab Mode": "미치광이 연구실 모드", |
| 603 | "Time the AI's message generation, and show the duration in the chat log": "AI의 메시지 생성 시간을 측정하고, 채팅 로그에 지속 시간을 표시합니다", | 613 | "Time the AI's message generation, and show the duration in the chat log": "AI의 메시지 생성 시간을 측정하고, 채팅 로그에 지속 시간을 표시합니다", |
| 604 | "Message Timer": "메시지 타이머", | 614 | "Message Timer": "메시지 도착 시간 측정", |
| 605 | "Show a timestamp for each message in the chat log": "채팅 로그의 각 메시지에 타임스탬프 표시", | 615 | "Show a timestamp for each message in the chat log": "채팅 로그의 각 메시지에 타임스탬프 표시", |
| 606 | "Chat Timestamps": "채팅 타임스탬프", | 616 | "Chat Timestamps": "채팅 타임스탬프", |
| 607 | "Show an icon for the API that generated the message": "메시지를 생성한 API에 대한 아이콘 표시", | 617 | "Show an icon for the API that generated the message": "메시지를 생성한 API에 대한 아이콘 표시", |
| 608 | "Model Icon": "모델 아이콘", | 618 | "Model Icon": "모델 아이콘 표시", |
| 609 | "Show sequential message numbers in the chat log": "채팅 로그에 순차적인 메시지 번호 표시", | 619 | "Show sequential message numbers in the chat log": "채팅 로그에 순차적인 메시지 번호 표시", |
| 610 | "Message IDs": "메시지 ID", | 620 | "Message IDs": "메시지 ID", |
| 611 | "Hide avatars in chat messages.": "채팅 메시지에서 아바타 숨김.", | 621 | "Hide avatars in chat messages.": "채팅 메시지에서 아바타 숨김.", |
| 612 | "Hide Chat Avatars": "채팅 아바타 숨기기", | 622 | "Hide Chat Avatars": "캐릭터 프로필 숨기기", |
| 613 | "Show the number of tokens in each message in the chat log": "채팅 로그의 각 메시지에 토큰 수 표시", | 623 | "Show the number of tokens in each message in the chat log": "채팅 로그의 각 메시지에 토큰 수 표시", |
| 614 | "Show Message Token Count": "메시지 토큰 개수 표시", | 624 | "Show Message Token Count": "메시지 토큰 개수 표시", |
| 615 | "Single-row message input area. Mobile only, no effect on PC": "한 줄짜리 메시지 입력 영역. 모바일 전용, PC에는 영향 없음", | 625 | "Single-row message input area. Mobile only, no effect on PC": "한 줄짜리 메시지 입력 영역. 모바일 전용, PC에는 영향 없음", |
| 616 | "Compact Input Area (Mobile)": "컴팩트한 입력 영역 (모바일)", | 626 | "Compact Input Area (Mobile)": "조그마한 입력 영역 (모바일)", |
| 627 | "Swipe # for All Messages": "모든 스와이프 메시지에 대해 번호 매기기", | ||
| 628 | "[title]Display swipe numbers for all messages, not just the last.": "마지막 메시지만이 아니라 모든 메시지에 대한 스와이프 번호를 표시합니다.", | ||
| 617 | "In the Character Management panel, show quick selection buttons for favorited characters": "캐릭터 관리 패널에서 즐겨찾는 캐릭터에 대한 빠른 선택 버튼을 표시합니다", | 629 | "In the Character Management panel, show quick selection buttons for favorited characters": "캐릭터 관리 패널에서 즐겨찾는 캐릭터에 대한 빠른 선택 버튼을 표시합니다", |
| 618 | "Characters Hotswap": "캐릭터 핫스왑", | 630 | "Characters Hotswap": "캐릭터 핫스왑", |
| 619 | "Enable magnification for zoomed avatar display.": "마우스 오버 시 아바타가 커지도록 설정하세요.", | 631 | "Enable magnification for zoomed avatar display.": "마우스 포인터를 아바타 위에 올려두면 아바타가 확대 됩니다.", |
| 620 | "Avatar Hover Magnification": "아바타 마우스오버 시 확대", | 632 | "Avatar Hover Magnification": "마우스를 올리면 아바타 확대", |
| 621 | "Enables a magnification effect on hover when you display the zoomed avatar after clicking an avatar's image in chat.": "채팅에서 아바타 이미지를 클릭한 후 확대된 아바타를 표시할 때 마우스 오버 시 확대 효과를 활성화합니다.", | 633 | "Enables a magnification effect on hover when you display the zoomed avatar after clicking an avatar's image in chat.": "채팅에서 아바타 이미지를 클릭한 후 확대된 아바타를 표시할 때 마우스 오버 시 확대 효과를 활성화합니다.", |
| 622 | "Show tagged character folders in the character list": "캐릭터 목록에서 태그가 지정된 캐릭터 폴더 표시", | 634 | "Show tagged character folders in the character list": "캐릭터 목록에서 태그가 지정된 캐릭터 폴더 표시", |
| 623 | "Tags as Folders": "태그를 폴더로", | 635 | "Tags as Folders": "태그를 폴더로 설정", |
| 624 | "Tags_as_Folders_desc": "최근 변경 사항: 태그는 태그 관리 메뉴에서 폴더로 표시되어야 폴더로 표시됩니다. 여기를 클릭해 불러오세요.", | 636 | "Tags_as_Folders_desc": "최근 변경 사항: 태그는 태그 관리 메뉴에서 폴더로 표시되어야 폴더로 표시됩니다. 여기를 클릭해 불러오세요.", |
| 637 | "Background Image": "채팅 배경 이미지", | ||
| 625 | "Character Handling": "캐릭터 처리", | 638 | "Character Handling": "캐릭터 처리", |
| 626 | "If set in the advanced character definitions, this field will be displayed in the characters list.": "고급 캐릭터 정의에서 설정된 경우 이 필드가 캐릭터 목록에 표시됩니다.", | 639 | "If set in the advanced character definitions, this field will be displayed in the characters list.": "고급 캐릭터 정의에서 설정된 경우 이 필드가 캐릭터 목록에 표시됩니다.", |
| 627 | "Char List Subheader": "문자 목록 하위 제목", | 640 | "Char List Subheader": "캐릭터 목록 하위 제목", |
| 628 | "Character Version": "캐릭터 버전", | 641 | "Character Version": "캐릭터 버전", |
| 629 | "Created by": "작성자", | 642 | "Created by": "제작자", |
| 630 | "Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "퍼지 매칭을 사용하고 이름 하위 문자열뿐만 아니라 모든 데이터 필드로 목록에서 캐릭터를 검색합니다", | 643 | "Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "퍼지 매칭을 사용하고 이름 하위 문자열뿐만 아니라 모든 데이터 필드로 목록에서 캐릭터를 검색합니다", |
| 631 | "Advanced Character Search": "고급 캐릭터 검색", | 644 | "Advanced Character Search": "고급 캐릭터 검색", |
| 632 | "If checked and the character card contains a prompt override (System Prompt), use that instead": "선택되어 있고 캐릭터 카드에 프롬프트 재정의 (시스템 프롬프트)가 포함 된 경우, 대신 사용하십시오", | 645 | "If checked and the character card contains a prompt override (System Prompt), use that instead": "선택되어 있고 캐릭터 카드에 프롬프트(시스템 프롬프트) 재정의가 포함 된 경우, 그것을 대신 사용합니다", |
| 633 | "Prefer Character Card Prompt": "캐릭터 카드 프롬프트 선호", | 646 | "Prefer Character Card Prompt": "캐릭터 카드 프롬프트 선호", |
| 634 | "If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "선택되어 있고 캐릭터 카드에 탈옥 재정의 (게시 내역 지침)가 포함 된 경우, 대신 사용하십시오", | 647 | "If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "선택되어 있고 캐릭터 카드에 (Post-History 지시)탈옥 재정의가 포함 된 경우, 그것을 대신 사용합니다.", |
| 635 | "Prefer Character Card Jailbreak": "캐릭터 카드 탈옥 선호", | 648 | "Prefer Character Card Jailbreak": "캐릭터 카드 탈옥 선호", |
| 636 | "Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "가져온 캐릭터 이미지를 자르거나 크기를 조정하지 마세요. 꺼져 있으면 512x768로 자르거나 크기를 조정합니다.", | 649 | "Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "가져온 캐릭터 이미지를 자르거나 크기를 조정하지 마세요. 꺼져 있으면 512x768로 자르거나 크기를 조정합니다.", |
| 637 | "Never resize avatars": "아바타 크기 변경하지 않음", | 650 | "Never resize avatars": "아바타 크기 변경하지 않음", |
| 638 | "Show actual file names on the disk, in the characters list display only": "실제 파일 이름을 디스크에 표시하며 캐릭터 목록 디스플레이에만", | 651 | "Show actual file names on the disk, in the characters list display only": "실제 파일 이름을 디스크에 표시하며 캐릭터 목록 디스플레이에만", |
| 639 | "Show avatar filenames": "아바타 파일 이름 표시", | 652 | "Show avatar filenames": "아바타 파일 이름 표시", |
| 640 | "Prompt to import embedded card tags on character import. Otherwise embedded tags are ignored": "캐릭터 가져오기시 내장된 카드 태그를 가져 오도록 요청하십시오. 그렇지 않으면 내장된 태그가 무시됩니다", | 653 | "Prompt to import embedded card tags on character import. Otherwise embedded tags are ignored": "캐릭터 가져오기시 내장된 카드 태그를 가져 오도록 요청하세요. 그렇지 않으면 내장된 태그가 무시됩니다", |
| 641 | "Import Card Tags": "카드 태그 가져오기", | 654 | "Import Card Tags": "카드 태그 가져오기", |
| 642 | "Hide character definitions from the editor panel behind a spoiler button": "스포일러 버튼 뒤에 편집기 패널에서 캐릭터 정의를 숨깁니다", | 655 | "Hide character definitions from the editor panel behind a spoiler button": "스포일러 버튼 뒤에 편집기 패널에서 캐릭터 정의를 숨깁니다", |
| 643 | "Spoiler Free Mode": "스포일러 무료 모드", | 656 | "Spoiler Free Mode": "스포일러 무료 모드", |
| @@ -655,7 +668,7 @@ | |||
| 655 | "Background Sound Only": "배경 소리만", | 668 | "Background Sound Only": "배경 소리만", |
| 656 | "Reduce the formatting requirements on API URLs": "API URL의 서식 요구 사항 감소", | 669 | "Reduce the formatting requirements on API URLs": "API URL의 서식 요구 사항 감소", |
| 657 | "Relaxed API URLS": "완화된 API URLS", | 670 | "Relaxed API URLS": "완화된 API URLS", |
| 658 | "Ask to import the World Info/Lorebook for every new character with embedded lorebook. If unchecked, a brief message will be shown instead": "내장된 로어북이있는 모든 새 캐릭터에 대해 세계 정보/로어북을 가져 오도록 요청하십시오. 선택 해제하면 대신 간단한 메시지가 표시됩니다", | 671 | "Ask to import the World Info/Lorebook for every new character with embedded lorebook. If unchecked, a brief message will be shown instead": "내장된 로어북이있는 모든 새 캐릭터에 대해 월드 인포/로어북을 가져 오도록 요청하세요. 선택 해제하면 대신 간단한 메시지가 표시됩니다", |
| 659 | "Lorebook Import Dialog": "로어북 가져오기 대화 상자", | 672 | "Lorebook Import Dialog": "로어북 가져오기 대화 상자", |
| 660 | "Restore unsaved user input on page refresh": "페이지 새로 고침시 저장되지 않은 사용자 입력 복원", | 673 | "Restore unsaved user input on page refresh": "페이지 새로 고침시 저장되지 않은 사용자 입력 복원", |
| 661 | "Restore User Input": "사용자 입력 복원", | 674 | "Restore User Input": "사용자 입력 복원", |
| @@ -675,8 +688,8 @@ | |||
| 675 | "Streaming FPS": "스트리밍 FPS", | 688 | "Streaming FPS": "스트리밍 FPS", |
| 676 | "Update speed of streamed text.": "스트리밍된 텍스트의 속도를 업데이트합니다.", | 689 | "Update speed of streamed text.": "스트리밍된 텍스트의 속도를 업데이트합니다.", |
| 677 | "Example Messages Behavior": "예제 메시지 동작", | 690 | "Example Messages Behavior": "예제 메시지 동작", |
| 678 | "Gradual push-out": "점진적 밀어내기", | 691 | "Gradual push-out": "토큰 초과 시 점진적 밀어내기", |
| 679 | "Always include examples": "항상 예제 포함", | 692 | "Always include examples": "항상 컨텍스트에 예제 포함", |
| 680 | "Never include examples": "절대로 예제 포함 안 함", | 693 | "Never include examples": "절대로 예제 포함 안 함", |
| 681 | "Send on Enter": "Enter로 전송", | 694 | "Send on Enter": "Enter로 전송", |
| 682 | "Disabled": "비활성화됨", | 695 | "Disabled": "비활성화됨", |
| @@ -693,7 +706,9 @@ | |||
| 693 | "Save edits to messages without confirmation as you type": "입력하는 동안 확인없이 메시지에 대한 편집 사항 저장", | 706 | "Save edits to messages without confirmation as you type": "입력하는 동안 확인없이 메시지에 대한 편집 사항 저장", |
| 694 | "Auto-save Message Edits": "메시지 편집 자동 저장", | 707 | "Auto-save Message Edits": "메시지 편집 자동 저장", |
| 695 | "Confirm message deletion": "메시지 삭제 확인", | 708 | "Confirm message deletion": "메시지 삭제 확인", |
| 696 | "Auto-fix Markdown": "Markdown 자동 수정", | 709 | "Auto-fix Markdown": "마크다운 자동 수정", |
| 710 | "Render LaTeX and AsciiMath equation notation in chat messages. Powered by KaTeX": "채팅 메시지에서 LaTeX 및 AsciiMath 방정식 표기법을 렌더링합니다. KaTeX 제공", | ||
| 711 | "Render Formulas": "수식 렌더링", | ||
| 697 | "Disallow embedded media from other domains in chat messages": "채팅 메시지에 다른 도메인의 삽입된 미디어를 허용하지 않습니다.", | 712 | "Disallow embedded media from other domains in chat messages": "채팅 메시지에 다른 도메인의 삽입된 미디어를 허용하지 않습니다.", |
| 698 | "Forbid External Media": "외부 미디어 금지", | 713 | "Forbid External Media": "외부 미디어 금지", |
| 699 | "Allow {{char}}: in bot messages": "봇 메시지에서 {{char}}: 허용", | 714 | "Allow {{char}}: in bot messages": "봇 메시지에서 {{char}}: 허용", |
| @@ -732,8 +747,8 @@ | |||
| 732 | "entire chat width": "전체 채팅 폭", | 747 | "entire chat width": "전체 채팅 폭", |
| 733 | "full window width": "전체 창 너비", | 748 | "full window width": "전체 창 너비", |
| 734 | "STscript Settings": "STscript 설정", | 749 | "STscript Settings": "STscript 설정", |
| 735 | "Sets default flags for the STscript parser.": "STscript 파서 기본 플래그 설정", | 750 | "Sets default flags for the STscript parser.": "STscript Parser 기본 플래그 설정", |
| 736 | "Parser Flags": "파서 플래그 설정", | 751 | "Parser Flags": "Parser 플래그 설정", |
| 737 | "Switch to stricter escaping, allowing all delimiting characters to be escaped with a backslash, and backslashes to be escaped as well.": "모든 구분자를 백슬래시로 이스케이핑하고, 백슬래시 자체도 이스케이프할 수 있도록 엄격한 방식으로 전환합니다.", | 752 | "Switch to stricter escaping, allowing all delimiting characters to be escaped with a backslash, and backslashes to be escaped as well.": "모든 구분자를 백슬래시로 이스케이핑하고, 백슬래시 자체도 이스케이프할 수 있도록 엄격한 방식으로 전환합니다.", |
| 738 | "STRICT_ESCAPING": "STRICT_ESCAPING", | 753 | "STRICT_ESCAPING": "STRICT_ESCAPING", |
| 739 | "Replace all {{getvar::}} and {{getglobalvar::}} macros with scoped variables to avoid double macro substitution.": "이중 매크로 대체를 방지하려면 모든 {{getvar::}} 및 {{getglobalvar::}} 매크로를 범위 변수로 바꾸세요.", | 754 | "Replace all {{getvar::}} and {{getglobalvar::}} macros with scoped variables to avoid double macro substitution.": "이중 매크로 대체를 방지하려면 모든 {{getvar::}} 및 {{getglobalvar::}} 매크로를 범위 변수로 바꾸세요.", |
| @@ -751,7 +766,7 @@ | |||
| 751 | "Manage extensions": "확장 프로그램 관리", | 766 | "Manage extensions": "확장 프로그램 관리", |
| 752 | "Import Extension From Git Repo": "Git 리포지토리에서 확장 프로그램 가져오기", | 767 | "Import Extension From Git Repo": "Git 리포지토리에서 확장 프로그램 가져오기", |
| 753 | "Install extension": "확장 프로그램 설치", | 768 | "Install extension": "확장 프로그램 설치", |
| 754 | "Extras API:": "추가 API:", | 769 | "Extras API:": "외부 API:", |
| 755 | "Auto-connect": "자동 연결", | 770 | "Auto-connect": "자동 연결", |
| 756 | "Extras API URL": "엑스트라 API URL", | 771 | "Extras API URL": "엑스트라 API URL", |
| 757 | "Extras API key (optional)": "Extras API 키 (선택 사항)", | 772 | "Extras API key (optional)": "Extras API 키 (선택 사항)", |
| @@ -769,20 +784,21 @@ | |||
| 769 | "No persona description": "[설명 없음]", | 784 | "No persona description": "[설명 없음]", |
| 770 | "Name": "이름", | 785 | "Name": "이름", |
| 771 | "Enter your name": "이름을 입력하세요", | 786 | "Enter your name": "이름을 입력하세요", |
| 772 | "Click to set a new User Name": "새 사용자 이름 설정을 클릭하세요", | 787 | "Click to set a new User Name": "새 사용자 이름 설정을 저장합니다.", |
| 773 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "선택한 페르소나를 현재 채팅에 잠그려면 클릭하세요. 잠금을 제거하려면 다시 클릭하세요.", | 788 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "선택한 페르소나를 현재 채팅에 잠그려면 클릭하세요. 잠금을 제거하려면 다시 클릭하세요.", |
| 774 | "Click to set user name for all messages": "모든 메시지에 사용자 이름을 설정하려면 클릭하세요", | 789 | "Click to set user name for all messages": "모든 메시지를 현재 선택된 사용자 이름으로 설정하려면 클릭하세요", |
| 775 | "Persona Description": "페르소나 설명", | 790 | "Persona Description": "페르소나 설명", |
| 776 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "예: [{{user}}는 28세의 루마니아 고양이 소녀입니다.]", | 791 | "Example: [{{user}} is a 28-year-old Romanian cat girl.]": "예: [{{user}}는 28세의 루마니아 고양이 소녀입니다.]", |
| 777 | "Tokens persona description": "토큰 페르소나 설명", | 792 | "Tokens persona description": "페르소나 설명 토큰", |
| 778 | "Position:": "위치:", | 793 | "Position:": "위치:", |
| 794 | "None (disabled)": "없음 (비활성화됨)", | ||
| 779 | "In Story String / Prompt Manager": "이야기 문자열 / 프롬프트 관리자", | 795 | "In Story String / Prompt Manager": "이야기 문자열 / 프롬프트 관리자", |
| 780 | "Top of Author's Note": "작성자의 주석 상단", | 796 | "Top of Author's Note": "작가 노트 상단", |
| 781 | "Bottom of Author's Note": "작성자의 주석 하단", | 797 | "Bottom of Author's Note": "작가 노트 하단", |
| 782 | "In-chat @ Depth": "채팅 내 @ Depth", | 798 | "In-chat @ Depth": "채팅 내 @ Depth", |
| 783 | "Depth:": "깊이:", | 799 | "Depth:": "깊이:", |
| 784 | "Role:": "역할:", | 800 | "Role:": "역할:", |
| 785 | "System": "체계", | 801 | "System": "시스템", |
| 786 | "User": "사용자", | 802 | "User": "사용자", |
| 787 | "Assistant": "어시스턴트", | 803 | "Assistant": "어시스턴트", |
| 788 | "Show notifications on switching personas": "페르소나 전환시 알림 표시", | 804 | "Show notifications on switching personas": "페르소나 전환시 알림 표시", |
| @@ -803,15 +819,15 @@ | |||
| 803 | "Click to select a new avatar for this character": "이 캐릭터의 새 아바타를 선택하려면 클릭하세요", | 819 | "Click to select a new avatar for this character": "이 캐릭터의 새 아바타를 선택하려면 클릭하세요", |
| 804 | "Add to Favorites": "즐겨찾기에 추가", | 820 | "Add to Favorites": "즐겨찾기에 추가", |
| 805 | "Advanced Definition": "고급 정의", | 821 | "Advanced Definition": "고급 정의", |
| 806 | "Character Lore": "캐릭터 이야기", | 822 | "Character Lore": "캐릭터 로어북", |
| 807 | "Chat Lore": "채팅 이야기", | 823 | "Chat Lore": "채팅 로어북", |
| 808 | "Export and Download": "내보내기 및 다운로드", | 824 | "Export and Download": "내보내기 및 다운로드", |
| 809 | "Duplicate Character": "캐릭터 복제", | 825 | "Duplicate Character": "캐릭터 복제", |
| 810 | "Create Character": "캐릭터 생성", | 826 | "Create Character": "캐릭터 생성", |
| 811 | "Delete Character": "캐릭터 삭제", | 827 | "Delete Character": "캐릭터 삭제", |
| 812 | "More...": "더...", | 828 | "More...": "추가 설정들...", |
| 813 | "Link to World Info": "월드 정보에 연결", | 829 | "Link to World Info": "월드 인포에 연결", |
| 814 | "Import Card Lore": "카드 로어 가져오기", | 830 | "Import Card Lore": "카드 로어북 가져오기", |
| 815 | "Scenario Override": "시나리오 재정의", | 831 | "Scenario Override": "시나리오 재정의", |
| 816 | "Convert to Persona": "페르소나로 변환", | 832 | "Convert to Persona": "페르소나로 변환", |
| 817 | "Rename": "이름 변경", | 833 | "Rename": "이름 변경", |
| @@ -820,22 +836,22 @@ | |||
| 820 | "Import Tags": "태그 가져오기", | 836 | "Import Tags": "태그 가져오기", |
| 821 | "Search / Create Tags": "검색 / 태그 생성", | 837 | "Search / Create Tags": "검색 / 태그 생성", |
| 822 | "View all tags": "모든 태그 보기", | 838 | "View all tags": "모든 태그 보기", |
| 823 | "Creator's Notes": "제작자의 노트", | 839 | "Creator's Notes": "제작자의 메모", |
| 824 | "Show / Hide Description and First Message": "설명 및 첫 번째 메시지 표시/숨기기", | 840 | "Show / Hide Description and First Message": "설명 및 첫 번째 메시지 표시/숨기기", |
| 825 | "Character Description": "캐릭터 설명", | 841 | "Character Description": "캐릭터 설명", |
| 826 | "Click to allow/forbid the use of external media for this character.": "이 캐릭터에 대한 외부 미디어 사용을 허용/금지하려면 클릭하세요.", | 842 | "Click to allow/forbid the use of external media for this character.": "이 캐릭터에 대한 외부 미디어 사용을 허용/금지하려면 클릭하세요.", |
| 827 | "Ext. Media": "내선 미디어", | 843 | "Ext. Media": "외부 미디어", |
| 828 | "Describe your character's physical and mental traits here.": "여기에 캐릭터의 신체적, 정신적 특성을 설명하세요.", | 844 | "Describe your character's physical and mental traits here.": "여기에 캐릭터의 신체적, 정신적 특성을 설명하세요.", |
| 829 | "First message": "첫 번째 메시지", | 845 | "First message": "첫 번째 메시지", |
| 830 | "Click to set additional greeting messages": "추가 인사말 메시지를 설정하려면 클릭하세요", | 846 | "Click to set additional greeting messages": "첫 번째 메시지를 추가로 설정하려면 클릭하세요.", |
| 831 | "Alt. Greetings": "대체. 인사말", | 847 | "Alt. Greetings": "대체. 첫 메시지", |
| 832 | "This will be the first message from the character that starts every chat.": "이것은 모든 채팅을 시작하는 캐릭터의 첫 번째 메시지가 됩니다.", | 848 | "This will be the first message from the character that starts every chat.": "이것은 모든 채팅을 시작할 때 캐릭터의 첫 번째 메시지가 됩니다.", |
| 833 | "Group Controls": "그룹 제어", | 849 | "Group Controls": "그룹 제어", |
| 834 | "Chat Name (Optional)": "채팅 이름 (선택 사항)", | 850 | "Chat Name (Optional)": "채팅 이름 (선택 사항)", |
| 835 | "Click to select a new avatar for this group": "이 그룹의 새 아바타를 선택하려면 클릭하세요", | 851 | "Click to select a new avatar for this group": "이 그룹의 새 아바타를 선택하려면 클릭하세요", |
| 836 | "Group reply strategy": "그룹 응답 전략", | 852 | "Group reply strategy": "그룹 응답 전략", |
| 837 | "Natural order": "자연 순서", | 853 | "Natural order": "자연스러운 순서", |
| 838 | "List order": "목록 순서", | 854 | "List order": "목록에 배정된 순서", |
| 839 | "Group generation handling mode": "그룹 생성 처리 모드", | 855 | "Group generation handling mode": "그룹 생성 처리 모드", |
| 840 | "Swap character cards": "캐릭터 카드 바꾸기", | 856 | "Swap character cards": "캐릭터 카드 바꾸기", |
| 841 | "Join character cards (exclude muted)": "캐릭터 카드 가입 (뮤트 제외)", | 857 | "Join character cards (exclude muted)": "캐릭터 카드 가입 (뮤트 제외)", |
| @@ -861,8 +877,8 @@ | |||
| 861 | "Characters sorting order": "캐릭터 정렬 순서", | 877 | "Characters sorting order": "캐릭터 정렬 순서", |
| 862 | "A-Z": "A-Z", | 878 | "A-Z": "A-Z", |
| 863 | "Z-A": "Z-A", | 879 | "Z-A": "Z-A", |
| 864 | "Newest": "최신", | 880 | "Newest": "최신순", |
| 865 | "Oldest": "가장 오래된", | 881 | "Oldest": "가장 오래된 순", |
| 866 | "Favorites": "즐겨찾기", | 882 | "Favorites": "즐겨찾기", |
| 867 | "Recent": "최근", | 883 | "Recent": "최근", |
| 868 | "Most chats": "대화가 가장 많은", | 884 | "Most chats": "대화가 가장 많은", |
| @@ -874,19 +890,19 @@ | |||
| 874 | "Bulk_edit_characters": "대량 캐릭터 편집", | 890 | "Bulk_edit_characters": "대량 캐릭터 편집", |
| 875 | "Bulk select all characters": "모든 문자 일괄 선택", | 891 | "Bulk select all characters": "모든 문자 일괄 선택", |
| 876 | "Bulk delete characters": "대량 캐릭터 삭제", | 892 | "Bulk delete characters": "대량 캐릭터 삭제", |
| 877 | "popup-button-save": "구하다", | 893 | "popup-button-save": "저장하기", |
| 878 | "popup-button-yes": "예", | 894 | "popup-button-yes": "네", |
| 879 | "popup-button-no": "아니요", | 895 | "popup-button-no": "아니요", |
| 880 | "popup-button-cancel": "취소", | 896 | "popup-button-cancel": "취소", |
| 881 | "popup-button-import": "수입", | 897 | "popup-button-import": "불러오기", |
| 882 | "Advanced Defininitions": "고급 정의", | 898 | "Advanced Defininitions": "고급 정의", |
| 883 | "Prompt Overrides": "프롬프트 무시", | 899 | "Prompt Overrides": "프롬프트 무시", |
| 884 | "(For Chat Completion and Instruct Mode)": "(채팅 완료 및 지시 모드의 경우)", | 900 | "(For Chat Completion and Instruct Mode)": "(채팅 완료 및 지시 모드의 경우)", |
| 885 | "Insert {{original}} into either box to include the respective default prompt from system settings.": "{{original}}를 해당 상자에 넣어 시스템 설정의 기본 프롬프트를 포함합니다.", | 901 | "Insert {{original}} into either box to include the respective default prompt from system settings.": "{{original}}를 해당 상자에 넣어 시스템 설정의 기본 프롬프트를 포함합니다.", |
| 886 | "Main Prompt": "주 프롬프트", | 902 | "Main Prompt": "주요 프롬프트", |
| 887 | "Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "여기에 있는 모든 내용은 이 캐릭터에 사용된 기본 주 프롬프트를 대체합니다. (v2 사양: system_prompt)", | 903 | "Any contents here will replace the default Main Prompt used for this character. (v2 spec: system_prompt)": "여기에 있는 모든 내용은 이 캐릭터에 사용된 기본 메인 프롬프트를 대체합니다. (v2 사양: system_prompt)", |
| 888 | "Any contents here will replace the default Jailbreak Prompt used for this character. (v2 spec: post_history_instructions)": "여기에 있는 모든 내용은 이 캐릭터에 사용된 기본 탈옥 프롬프트를 대체합니다. (v2 사양: post_history_instructions)", | 904 | "Any contents here will replace the default Jailbreak Prompt used for this character. (v2 spec: post_history_instructions)": "여기에 있는 모든 내용은 이 캐릭터에 사용된 기본 탈옥 프롬프트를 대체합니다. (v2 사양: post_history_instructions)", |
| 889 | "Creator's Metadata (Not sent with the AI prompt)": "만든이 메타데이터 (AI 프롬프트와 함께 전송되지 않음)", | 905 | "Creator's Metadata (Not sent with the AI prompt)": "제작자의 메타데이터 (AI 프롬프트와 함께 전송되지 않음)", |
| 890 | "Creator's Metadata": "제작자의 메타데이터", | 906 | "Creator's Metadata": "제작자의 메타데이터", |
| 891 | "(Not sent with the AI Prompt)": "(AI 프롬프트와 함께 전송되지 않음)", | 907 | "(Not sent with the AI Prompt)": "(AI 프롬프트와 함께 전송되지 않음)", |
| 892 | "Everything here is optional": "여기 있는 모든 것은 선택 사항입니다", | 908 | "Everything here is optional": "여기 있는 모든 것은 선택 사항입니다", |
| @@ -904,11 +920,11 @@ | |||
| 904 | "@ Depth": "@ 깊이", | 920 | "@ Depth": "@ 깊이", |
| 905 | "Role": "역할", | 921 | "Role": "역할", |
| 906 | "Talkativeness": "수다스러움", | 922 | "Talkativeness": "수다스러움", |
| 907 | "How often the character speaks in group chats!": "캐릭터가 그룹 채팅에서 얼마나 자주 말하는지!", | 923 | "How often the character speaks in group chats!": "캐릭터가 그룹 채팅에서 얼마나 자주 말할지 설정해보세요!", |
| 908 | "How often the character speaks in": "캐릭터가 말하는 빈도", | 924 | "How often the character speaks in": "캐릭터가 말하는 빈도", |
| 909 | "group chats!": "그룹 채팅!", | 925 | "group chats!": "그룹 채팅!", |
| 910 | "Shy": "수줍음", | 926 | "Shy": "수줍음", |
| 911 | "Normal": "보통", | 927 | "Normal": "평범함", |
| 912 | "Chatty": "수다쟁이", | 928 | "Chatty": "수다쟁이", |
| 913 | "Examples of dialogue": "대화 예시", | 929 | "Examples of dialogue": "대화 예시", |
| 914 | "Important to set the character's writing style.": "캐릭터의 글쓰기 스타일을 설정하는 것이 중요합니다.", | 930 | "Important to set the character's writing style.": "캐릭터의 글쓰기 스타일을 설정하는 것이 중요합니다.", |
| @@ -918,16 +934,16 @@ | |||
| 918 | "Import Chat": "채팅 가져오기", | 934 | "Import Chat": "채팅 가져오기", |
| 919 | "Copy to system backgrounds": "시스템 배경에 복사", | 935 | "Copy to system backgrounds": "시스템 배경에 복사", |
| 920 | "Rename background": "배경 이름 바꾸기", | 936 | "Rename background": "배경 이름 바꾸기", |
| 921 | "Lock": "잠그다", | 937 | "Lock": "잠금", |
| 922 | "Unlock": "터놓다", | 938 | "Unlock": "잠금 해제", |
| 923 | "Delete background": "배경 삭제", | 939 | "Delete background": "배경 삭제", |
| 924 | "Chat Scenario Override": "채팅 시나리오 재정의", | 940 | "Chat Scenario Override": "채팅 시나리오 재정의", |
| 925 | "Remove": "제거", | 941 | "Remove": "제거", |
| 926 | "Type here...": "여기에 입력하세요...", | 942 | "Type here...": "여기에 입력하세요...", |
| 927 | "Chat Lorebook": "채팅 설화집", | 943 | "Chat Lorebook": "채팅 로어북", |
| 928 | "Chat Lorebook for": "채팅 설화집", | 944 | "Chat Lorebook for": "채팅 로어북", |
| 929 | "chat_world_template_txt": "선택한 세계 정보가 이 채팅에 연결됩니다. AI 답글을 생성할 때,\n 글로벌 및 캐릭터 지식북의 항목과 결합됩니다.", | 945 | "chat_world_template_txt": "선택한 월드 인포가 이 채팅에 연결됩니다. AI 응답을 생성할 때,\n 글로벌 및 캐릭터 로어북의 항목과 결합됩니다.", |
| 930 | "Select a World Info file for": "다음을 위해 세계 정보 파일 선택:", | 946 | "Select a World Info file for": "다음을 위해 월드 인포 파일 선택:", |
| 931 | "Primary Lorebook": "기본 로어북", | 947 | "Primary Lorebook": "기본 로어북", |
| 932 | "A selected World Info will be bound to this character as its own Lorebook.": "선택한 월드 정보가 이 캐릭터에게 자체 로어북으로 바인딩됩니다.", | 948 | "A selected World Info will be bound to this character as its own Lorebook.": "선택한 월드 정보가 이 캐릭터에게 자체 로어북으로 바인딩됩니다.", |
| 933 | "When generating an AI reply, it will be combined with the entries from a global World Info selector.": "AI 응답을 생성할 때 전역 월드 정보 선택기의 항목과 결합됩니다.", | 949 | "When generating an AI reply, it will be combined with the entries from a global World Info selector.": "AI 응답을 생성할 때 전역 월드 정보 선택기의 항목과 결합됩니다.", |
| @@ -942,34 +958,34 @@ | |||
| 942 | "Use tag as folder": "폴더로 태그 지정", | 958 | "Use tag as folder": "폴더로 태그 지정", |
| 943 | "Delete tag": "태그 삭제", | 959 | "Delete tag": "태그 삭제", |
| 944 | "Entry Title/Memo": "항목 제목/메모", | 960 | "Entry Title/Memo": "항목 제목/메모", |
| 945 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI 입국 상태:\r🔵 상수\r🟢 보통\r🔗 벡터화됨\r❌ 장애인", | 961 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized❌ Disabled": "WI 입국 상태:\r🔵 상시\r🟢 조건 만족시\r🔗 벡터화됨\r❌ 비활성화", |
| 946 | "WI_Entry_Status_Constant": "끊임없는", | 962 | "WI_Entry_Status_Constant": "상시 활성화", |
| 947 | "WI_Entry_Status_Normal": "정상", | 963 | "WI_Entry_Status_Normal": "정상", |
| 948 | "WI_Entry_Status_Vectorized": "벡터화됨", | 964 | "WI_Entry_Status_Vectorized": "벡터화됨", |
| 949 | "WI_Entry_Status_Disabled": "장애가 있는", | 965 | "WI_Entry_Status_Disabled": "비활성화됨", |
| 950 | "T_Position": "↑Char: 캐릭터 정의 전\n↓Char: 캐릭터 정의 후\n↑AN: 저자 주석 전\n↓AN: 저자 주석 후\n@D: 깊이에", | 966 | "T_Position": "↑Char: 캐릭터 정의 전\n↓Char: 캐릭터 정의 후\n↑AN: 작가 노트 전\n↓AN: 작가노트 후\n@D: 깊이", |
| 951 | "Before Char Defs": "캐릭터 정의 전", | 967 | "Before Char Defs": "캐릭터 정의 전", |
| 952 | "After Char Defs": "캐릭터 정의 후", | 968 | "After Char Defs": "캐릭터 정의 후", |
| 953 | "Before EM": "↑EM", | 969 | "Before EM": "↑EM", |
| 954 | "After EM": "↓EM", | 970 | "After EM": "↓EM", |
| 955 | "Before AN": "저자 주석 전", | 971 | "Before AN": "작가 노트 전", |
| 956 | "After AN": "저자 주석 후", | 972 | "After AN": "작가 노트 후", |
| 957 | "at Depth System": "@D ⚙️", | 973 | "at Depth System": "@D ⚙️", |
| 958 | "at Depth User": "@D 👤", | 974 | "at Depth User": "@D 👤", |
| 959 | "at Depth AI": "@디 🤖", | 975 | "at Depth AI": "@D 🤖", |
| 960 | "Depth": "깊이", | 976 | "Depth": "깊이", |
| 961 | "Order:": "주문:", | 977 | "Order:": "순서:", |
| 962 | "Order": "주문:", | 978 | "Order": "순서:", |
| 963 | "Trigger %:": "방아쇠 %:", | 979 | "Trigger %:": "발동 확률 %:", |
| 964 | "Probability": "개연성", | 980 | "Probability": "개연성", |
| 965 | "Duplicate world info entry": "중복된 세계 정보 항목", | 981 | "Duplicate world info entry": "중복된 월드 인포 항목", |
| 966 | "Delete world info entry": "세계 정보 항목 삭제", | 982 | "Delete world info entry": "월드 인포 항목 삭제", |
| 967 | "Comma separated (required)": "쉼표로 구분 (필수)", | 983 | "Comma separated (required)": "쉼표로 구분 (필수)", |
| 968 | "Primary Keywords": "기본 키워드", | 984 | "Primary Keywords": "기본 키워드", |
| 969 | "Keywords or Regexes": "키워드 또는 정규식", | 985 | "Keywords or Regexes": "키워드 또는 정규식", |
| 970 | "Comma separated list": "쉼표로 구분된 목록", | 986 | "Comma separated list": "쉼표로 구분된 목록", |
| 971 | "Switch to plaintext mode": "일반 텍스트 모드로 전환", | 987 | "Switch to plaintext mode": "일반 텍스트 모드로 전환", |
| 972 | "Logic": "로직", | 988 | "Logic": "논리 구조", |
| 973 | "AND ANY": "AND ANY", | 989 | "AND ANY": "AND ANY", |
| 974 | "AND ALL": "AND ALL", | 990 | "AND ALL": "AND ALL", |
| 975 | "NOT ALL": "NOT ALL", | 991 | "NOT ALL": "NOT ALL", |
| @@ -982,6 +998,7 @@ | |||
| 982 | "Case-Sensitive": "대소문자 구분", | 998 | "Case-Sensitive": "대소문자 구분", |
| 983 | "Yes": "예", | 999 | "Yes": "예", |
| 984 | "No": "아니오", | 1000 | "No": "아니오", |
| 1001 | "Quick Reply": "빠른 답장", | ||
| 985 | "Can be used to automatically activate Quick Replies": "빠른 답장을 자동으로 활성화하는 데 사용할 수 있습니다.", | 1002 | "Can be used to automatically activate Quick Replies": "빠른 답장을 자동으로 활성화하는 데 사용할 수 있습니다.", |
| 986 | "Automation ID": "자동화 ID", | 1003 | "Automation ID": "자동화 ID", |
| 987 | "( None )": "( 없음 )", | 1004 | "( None )": "( 없음 )", |
| @@ -994,7 +1011,7 @@ | |||
| 994 | "Character Exclusion": "캐릭터 제외", | 1011 | "Character Exclusion": "캐릭터 제외", |
| 995 | "-- Characters not found --": "-- 캐릭터를 찾을 수 없음 --", | 1012 | "-- Characters not found --": "-- 캐릭터를 찾을 수 없음 --", |
| 996 | "Inclusion Group": "포함 그룹", | 1013 | "Inclusion Group": "포함 그룹", |
| 997 | "Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group": "포함 그룹은 여러 항목이 트리거되는 경우 그룹에서 한 번에 하나의 항목만 활성화되도록 합니다.\r쉼표로 구분된 여러 그룹을 지원합니다.\r\r문서: 세계 정보 - 포함 그룹", | 1014 | "Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group": "포함 그룹은 여러 항목이 트리거되는 경우 그룹에서 한 번에 하나의 항목만 활성화되도록 합니다.\r쉼표로 구분된 여러 그룹을 지원합니다.\r\r문서: 월드 인포 - 포함 그룹", |
| 998 | "Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.": "이 항목 우선순위 지정: 선택하면 모든 선택 항목 중에서 이 항목의 우선순위가 지정됩니다.\r여러 항목의 우선순위가 높은 경우 '순서'가 가장 높은 항목이 선택됩니다.", | 1015 | "Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen.": "이 항목 우선순위 지정: 선택하면 모든 선택 항목 중에서 이 항목의 우선순위가 지정됩니다.\r여러 항목의 우선순위가 높은 경우 '순서'가 가장 높은 항목이 선택됩니다.", |
| 999 | "Only one entry with the same label will be activated": "동일한 라벨을 가진 항목은 하나만 활성화됩니다", | 1016 | "Only one entry with the same label will be activated": "동일한 라벨을 가진 항목은 하나만 활성화됩니다", |
| 1000 | "A relative likelihood of entry activation within the group": "그룹 내 항목 활성화의 상대적 가능성", | 1017 | "A relative likelihood of entry activation within the group": "그룹 내 항목 활성화의 상대적 가능성", |
| @@ -1004,27 +1021,28 @@ | |||
| 1004 | "Add Memo": "메모 추가", | 1021 | "Add Memo": "메모 추가", |
| 1005 | "Text or token ids": "텍스트 또는 [토큰 ID]", | 1022 | "Text or token ids": "텍스트 또는 [토큰 ID]", |
| 1006 | "close": "닫다", | 1023 | "close": "닫다", |
| 1007 | "prompt_manager_edit": "편집하다", | 1024 | "prompt_manager_edit": "프롬프트 편집", |
| 1008 | "prompt_manager_name": "이름", | 1025 | "prompt_manager_name": "이름", |
| 1009 | "A name for this prompt.": "이 프롬프트의 이름입니다.", | 1026 | "A name for this prompt.": "이 프롬프트의 이름입니다.", |
| 1010 | "To whom this message will be attributed.": "이 메시지는 누구에게 귀속됩니까?", | 1027 | "To whom this message will be attributed.": "해당 프롬프트에 부여할 역할은 무엇인가요?", |
| 1011 | "AI Assistant": "AI 어시스턴트", | 1028 | "AI Assistant": "AI 어시스턴트", |
| 1012 | "prompt_manager_position": "위치", | 1029 | "prompt_manager_position": "위치", |
| 1013 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "주입 위치. 다른 프롬프트 옆(상대적) 또는 채팅 내(절대적).", | 1030 | "Injection position. Next to other prompts (relative) or in-chat (absolute).": "주입 위치. 다른 프롬프트 옆(상대적) 또는 채팅 내(절대적).", |
| 1014 | "prompt_manager_relative": "상대적인", | 1031 | "prompt_manager_relative": "상대적인", |
| 1032 | "prompt_manager_in_chat": "깊이에 따라", | ||
| 1015 | "prompt_manager_depth": "깊이", | 1033 | "prompt_manager_depth": "깊이", |
| 1016 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "주입 깊이. 0 = 마지막 메시지 뒤, 1 = 마지막 메시지 앞 등", | 1034 | "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "주입 깊이. 0 = 마지막 메시지 뒤, 1 = 마지막 메시지 앞 등", |
| 1017 | "Prompt": "프롬프트", | 1035 | "Prompt": "프롬프트", |
| 1018 | "The prompt to be sent.": "보낼 프롬프트입니다.", | 1036 | "The prompt to be sent.": "보내질 프롬프트 내용을 작성하는 부분입니다.", |
| 1019 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "이 프롬프트는 재정의가 선호되는 경우에도 캐릭터 카드로 재정의될 수 없습니다.", | 1037 | "This prompt cannot be overridden by character cards, even if overrides are preferred.": "이 프롬프트는 고급 정의에서 재정의가 선호되는 경우에도 재정의될 수 없습니다.", |
| 1020 | "prompt_manager_forbid_overrides": "재정의 금지", | 1038 | "prompt_manager_forbid_overrides": "재정의 금지", |
| 1021 | "reset": "초기화", | 1039 | "reset": "초기화", |
| 1022 | "save": "구하다", | 1040 | "save": "저장", |
| 1023 | "This message is invisible for the AI": "이 메시지는 AI에게 보이지 않습니다", | 1041 | "This message is invisible for the AI": "이 메시지는 AI에게 보이지 않습니다", |
| 1024 | "Message Actions": "메시지 작업", | 1042 | "Message Actions": "메시지 작업", |
| 1025 | "Translate message": "메시지 번역", | 1043 | "Translate message": "메시지 번역", |
| 1026 | "Generate Image": "이미지 생성", | 1044 | "Generate Image": "이미지 생성", |
| 1027 | "Narrate": "이야기하기", | 1045 | "Narrate": "나레이션 하기", |
| 1028 | "Exclude message from prompts": "프롬프트에서 메시지 제외", | 1046 | "Exclude message from prompts": "프롬프트에서 메시지 제외", |
| 1029 | "Include message in prompts": "프롬프트에 메시지 포함", | 1047 | "Include message in prompts": "프롬프트에 메시지 포함", |
| 1030 | "Embed file or image": "파일 또는 이미지 삽입", | 1048 | "Embed file or image": "파일 또는 이미지 삽입", |
| @@ -1040,26 +1058,26 @@ | |||
| 1040 | "Move message down": "메시지를 아래로 이동", | 1058 | "Move message down": "메시지를 아래로 이동", |
| 1041 | "Enlarge": "확대", | 1059 | "Enlarge": "확대", |
| 1042 | "Welcome to SillyTavern!": "SillyTavern에 오신 것을 환영합니다!", | 1060 | "Welcome to SillyTavern!": "SillyTavern에 오신 것을 환영합니다!", |
| 1043 | "welcome_message_part_1": "읽기", | 1061 | "welcome_message_part_1": "자세한 설명 읽기:", |
| 1044 | "welcome_message_part_2": "공식 문서", | 1062 | "welcome_message_part_2": "공식 문서", |
| 1045 | "welcome_message_part_3": null, | 1063 | "welcome_message_part_3": null, |
| 1046 | "welcome_message_part_4": "유형", | 1064 | "welcome_message_part_4": "유형", |
| 1047 | "welcome_message_part_5": "명령과 매크로에 대한 채팅.", | 1065 | "welcome_message_part_5": "명령과 매크로에 대한 채팅.", |
| 1048 | "welcome_message_part_6": "참여하세요", | 1066 | "welcome_message_part_6": "공식", |
| 1049 | "Discord server": "디스코드 서버", | 1067 | "Discord server": "디스코드 서버", |
| 1050 | "welcome_message_part_7": "정보 및 공지사항을 확인하세요.", | 1068 | "welcome_message_part_7": "에서 정보 및 공지사항을 확인하세요.", |
| 1051 | "SillyTavern is aimed at advanced users.": "SillyTavern은 고급 사용자를 대상으로 합니다.", | 1069 | "SillyTavern is aimed at advanced users.": "SillyTavern은 고급 사용자를 대상으로 합니다.", |
| 1052 | "If you're new to this, enable the simplified UI mode below.": "처음 사용하는 경우 아래의 단순화된 UI 모드를 활성화하세요.", | 1070 | "If you're new to this, enable the simplified UI mode below.": "처음 사용하는 경우 아래의 단순화된 UI 모드를 활성화하세요.", |
| 1053 | "Change it later in the 'User Settings' panel.": "나중에 '사용자 설정' 패널에서 변경하세요.", | 1071 | "Change it later in the 'User Settings' panel.": "나중에 '사용자 설정' 패널에서 변경하세요.", |
| 1054 | "Enable simple UI mode": "단순 UI 모드 활성화", | 1072 | "Enable simple UI mode": "단순 UI 모드 활성화", |
| 1055 | "Looking for AI characters?": "AI 캐릭터를 찾고 계십니까?", | 1073 | "Looking for AI characters?": "AI 캐릭터를 찾고 계십니까?", |
| 1056 | "onboarding_import": "수입", | 1074 | "onboarding_import": "가져오기", |
| 1057 | "from supported sources or view": "지원되는 소스 또는 보기에서", | 1075 | "from supported sources or view": "지원되는 소스 또는 보기에서", |
| 1058 | "Sample characters": "샘플 캐릭터", | 1076 | "Sample characters": "샘플 캐릭터", |
| 1059 | "Your Persona": "당신의 페르소나", | 1077 | "Your Persona": "당신의 페르소나", |
| 1060 | "Before you get started, you must select a persona name.": "시작하기 전에 페르소나 이름을 선택해야 합니다.", | 1078 | "Before you get started, you must select a persona name.": "시작하기 전에 페르소나 이름을 선택해야 합니다.", |
| 1061 | "welcome_message_part_8": "이는 언제든지 다음을 통해 변경될 수 있습니다.", | 1079 | "welcome_message_part_8": "이는 언제든지 변경될 수 있습니다. 변경을 원한다면", |
| 1062 | "welcome_message_part_9": "상.", | 1080 | "welcome_message_part_9": "아이콘을 누르세요.", |
| 1063 | "Persona Name:": "페르소나 이름:", | 1081 | "Persona Name:": "페르소나 이름:", |
| 1064 | "Temporarily disable automatic replies from this character": "이 캐릭터의 자동 응답 일시적으로 비활성화", | 1082 | "Temporarily disable automatic replies from this character": "이 캐릭터의 자동 응답 일시적으로 비활성화", |
| 1065 | "Enable automatic replies from this character": "이 캐릭터의 자동 응답 활성화", | 1083 | "Enable automatic replies from this character": "이 캐릭터의 자동 응답 활성화", |
| @@ -1081,7 +1099,7 @@ | |||
| 1081 | "Remove the file": "파일을 제거하세요", | 1099 | "Remove the file": "파일을 제거하세요", |
| 1082 | "Unique to this chat": "이 채팅에만 고유함", | 1100 | "Unique to this chat": "이 채팅에만 고유함", |
| 1083 | "Checkpoints inherit the Note from their parent, and can be changed individually after that.": "체크포인트는 상위 항목으로부터 메모를 상속받으며 이후 개별적으로 변경될 수 있습니다.", | 1101 | "Checkpoints inherit the Note from their parent, and can be changed individually after that.": "체크포인트는 상위 항목으로부터 메모를 상속받으며 이후 개별적으로 변경될 수 있습니다.", |
| 1084 | "Include in World Info Scanning": "세계 정보 스캔에 포함", | 1102 | "Include in World Info Scanning": "월드인포를 스캔 대상에 포함", |
| 1085 | "Before Main Prompt / Story String": "메인 프롬프트 전/스토리 문자열", | 1103 | "Before Main Prompt / Story String": "메인 프롬프트 전/스토리 문자열", |
| 1086 | "After Main Prompt / Story String": "메인 프롬프트 이후 / 스토리 문자열", | 1104 | "After Main Prompt / Story String": "메인 프롬프트 이후 / 스토리 문자열", |
| 1087 | "as": "~처럼", | 1105 | "as": "~처럼", |
| @@ -1090,11 +1108,11 @@ | |||
| 1090 | "User inputs until next insertion:": "다음 삽입까지 사용자 입력:", | 1108 | "User inputs until next insertion:": "다음 삽입까지 사용자 입력:", |
| 1091 | "Character Author's Note (Private)": "캐릭터 작가의 메모 (비공개)", | 1109 | "Character Author's Note (Private)": "캐릭터 작가의 메모 (비공개)", |
| 1092 | "Won't be shared with the character card on export.": "내보내기 시 캐릭터 카드와 공유되지 않습니다.", | 1110 | "Won't be shared with the character card on export.": "내보내기 시 캐릭터 카드와 공유되지 않습니다.", |
| 1093 | "Will be automatically added as the author's note for this character. Will be used in groups, but can't be modified when a group chat is open.": "해당 캐릭터에 대한 작가의 메모로 자동 추가됩니다. 그룹으로 사용되지만\n 그룹 채팅이 열려 있으면 수정할 수 없습니다.", | 1111 | "Will be automatically added as the author's note for this character. Will be used in groups, but can't be modified when a group chat is open.": "해당 캐릭터에 대한 작가 노트로 자동 추가됩니다. 그룹으로 사용되지만\n 그룹 채팅이 열려 있으면 수정할 수 없습니다.", |
| 1094 | "Use character author's note": "캐릭터 작성자의 메모 사용", | 1112 | "Use character author's note": "캐릭터 작가 노트 사용", |
| 1095 | "Replace Author's Note": "작성자의 메모 바꾸기", | 1113 | "Replace Author's Note": "작가 노트 자리를 대체하기", |
| 1096 | "Default Author's Note": "기본 작성자의 메모", | 1114 | "Default Author's Note": "기본 작가 노트", |
| 1097 | "Will be automatically added as the Author's Note for all new chats.": "모든 새 채팅에 대한 작성자 메모로 자동으로 추가됩니다.", | 1115 | "Will be automatically added as the Author's Note for all new chats.": "모든 새 채팅에 대한 작가 노트로 자동으로 추가됩니다.", |
| 1098 | "Chat CFG": "채팅CFG", | 1116 | "Chat CFG": "채팅CFG", |
| 1099 | "1 = disabled": "1 = 비활성화됨", | 1117 | "1 = disabled": "1 = 비활성화됨", |
| 1100 | "write short replies, write replies using past tense": "짧은 답장 쓰기, 과거 시제를 사용하여 답장 쓰기", | 1118 | "write short replies, write replies using past tense": "짧은 답장 쓰기, 과거 시제를 사용하여 답장 쓰기", |
| @@ -1104,7 +1122,7 @@ | |||
| 1104 | "Will be automatically added as the CFG for this character.": "해당 캐릭터의 CFG로 자동 추가됩니다.", | 1122 | "Will be automatically added as the CFG for this character.": "해당 캐릭터의 CFG로 자동 추가됩니다.", |
| 1105 | "Global CFG": "글로벌 CFG", | 1123 | "Global CFG": "글로벌 CFG", |
| 1106 | "Will be used as the default CFG options for every chat unless overridden.": "재정의되지 않는 한 모든 채팅에 대해 기본 CFG 옵션으로 사용됩니다.", | 1124 | "Will be used as the default CFG options for every chat unless overridden.": "재정의되지 않는 한 모든 채팅에 대해 기본 CFG 옵션으로 사용됩니다.", |
| 1107 | "CFG Prompt Cascading": "CFG 프롬프트 카스케이딩", | 1125 | "CFG Prompt Cascading": "CFG 프롬프트 세분화", |
| 1108 | "Combine positive/negative prompts from other boxes.": "다른 상자의 긍정적/부정적 프롬프트를 결합합니다.", | 1126 | "Combine positive/negative prompts from other boxes.": "다른 상자의 긍정적/부정적 프롬프트를 결합합니다.", |
| 1109 | "For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.": "예를 들어, 채팅, 글로벌, 문자 상자를 체크하면 모든 부정 프롬프트가 쉼표로 구분된 문자열로 결합됩니다.", | 1127 | "For example, ticking the chat, global, and character boxes combine all negative prompts into a comma-separated string.": "예를 들어, 채팅, 글로벌, 문자 상자를 체크하면 모든 부정 프롬프트가 쉼표로 구분된 문자열로 결합됩니다.", |
| 1110 | "Always Include": "항상 포함", | 1128 | "Always Include": "항상 포함", |
| @@ -1127,14 +1145,14 @@ | |||
| 1127 | "Toggle Panels": "토글 패널", | 1145 | "Toggle Panels": "토글 패널", |
| 1128 | "Back to parent chat": "부모 채팅으로 돌아가기", | 1146 | "Back to parent chat": "부모 채팅으로 돌아가기", |
| 1129 | "Save checkpoint": "체크포인트 저장", | 1147 | "Save checkpoint": "체크포인트 저장", |
| 1130 | "Convert to group": "그룹으로 변환", | 1148 | "Convert to group": "그룹 채팅으로 변환", |
| 1131 | "Start new chat": "새로운 채팅 시작", | 1149 | "Start new chat": "새로운 채팅 시작", |
| 1132 | "Manage chat files": "채팅 파일 관리", | 1150 | "Manage chat files": "채팅 파일 관리", |
| 1133 | "Delete messages": "메시지 삭제", | 1151 | "Delete messages": "메시지 삭제", |
| 1134 | "Regenerate": "재생성", | 1152 | "Regenerate": "재생성", |
| 1135 | "Ask AI to write your message for you": "AI에게 메시지를 대신 작성하도록 요청", | 1153 | "Ask AI to write your message for you": "AI에게 메시지를 대신 작성하도록 요청", |
| 1136 | "Impersonate": "대신 말하기", | 1154 | "Impersonate": "사칭", |
| 1137 | "Continue": "계속", | 1155 | "Continue": "계속 생성하기", |
| 1138 | "Bind user name to that avatar": "그 아바타에 사용자 이름 바인딩", | 1156 | "Bind user name to that avatar": "그 아바타에 사용자 이름 바인딩", |
| 1139 | "Change persona image": "페르소나 이미지 변경", | 1157 | "Change persona image": "페르소나 이미지 변경", |
| 1140 | "Select this as default persona for the new chats.": "새 채팅의 기본 페르소나로 선택합니다.", | 1158 | "Select this as default persona for the new chats.": "새 채팅의 기본 페르소나로 선택합니다.", |
| @@ -1142,8 +1160,8 @@ | |||
| 1142 | "These characters are the winners of character design contests and have outstandable quality.": "캐릭터 디자인 공모전에서 당선된 캐릭터로, 뛰어난 퀄리티를 자랑하는 캐릭터입니다.", | 1160 | "These characters are the winners of character design contests and have outstandable quality.": "캐릭터 디자인 공모전에서 당선된 캐릭터로, 뛰어난 퀄리티를 자랑하는 캐릭터입니다.", |
| 1143 | "Contest Winners": "콘테스트 우승자", | 1161 | "Contest Winners": "콘테스트 우승자", |
| 1144 | "These characters are the finalists of character design contests and have remarkable quality.": "이 캐릭터들은 캐릭터 디자인 공모전의 최종 후보로, 뛰어난 퀄리티를 자랑합니다.", | 1162 | "These characters are the finalists of character design contests and have remarkable quality.": "이 캐릭터들은 캐릭터 디자인 공모전의 최종 후보로, 뛰어난 퀄리티를 자랑합니다.", |
| 1145 | "Featured Characters": "주요 캐릭터", | 1163 | "Featured Characters": "독립된 캐릭터", |
| 1146 | "Attach a File": "파일을 첨부", | 1164 | "Attach a File": "파일 첨부하기", |
| 1147 | "Open Data Bank": "오픈데이터뱅크", | 1165 | "Open Data Bank": "오픈데이터뱅크", |
| 1148 | "Enter a URL or the ID of a Fandom wiki page to scrape:": "스크랩할 Fandom 위키 페이지의 URL이나 ID를 입력하세요:", | 1166 | "Enter a URL or the ID of a Fandom wiki page to scrape:": "스크랩할 Fandom 위키 페이지의 URL이나 ID를 입력하세요:", |
| 1149 | "Examples:": "예:", | 1167 | "Examples:": "예:", |
| @@ -1176,16 +1194,14 @@ | |||
| 1176 | "Don't include the page name!": "페이지 이름을 포함하지 마세요!", | 1194 | "Don't include the page name!": "페이지 이름을 포함하지 마세요!", |
| 1177 | "Enter web URLs to scrape (one per line):": "스크랩할 웹 URL을 입력하세요(한 줄에 하나씩):", | 1195 | "Enter web URLs to scrape (one per line):": "스크랩할 웹 URL을 입력하세요(한 줄에 하나씩):", |
| 1178 | "Enter a video URL to download its transcript.": "스크립트를 다운로드하려면 동영상 URL 또는 ID를 입력하세요.", | 1196 | "Enter a video URL to download its transcript.": "스크립트를 다운로드하려면 동영상 URL 또는 ID를 입력하세요.", |
| 1179 | "Expression API": "현지의\n엑스트라\n법학대학원", | 1197 | "Expression API": "표현\n엑스트라\nAPI", |
| 1180 | "ext_sum_with": "요약:", | ||
| 1181 | "ext_sum_main_api": "메인 API", | ||
| 1182 | "ext_sum_current_summary": "현재 요약:", | 1198 | "ext_sum_current_summary": "현재 요약:", |
| 1183 | "ext_sum_restore_previous": "이전 복원", | 1199 | "ext_sum_restore_previous": "이전 복원", |
| 1184 | "ext_sum_memory_placeholder": "여기에 요약이 생성됩니다...", | 1200 | "ext_sum_memory_placeholder": "여기에 요약이 생성됩니다...", |
| 1185 | "Trigger a summary update right now.": "지금 요약하세요", | 1201 | "Trigger a summary update right now.": "지금 요약하세요", |
| 1186 | "ext_sum_force_text": "지금 요약하세요", | 1202 | "ext_sum_force_text": "지금 요약하세요", |
| 1187 | "Disable automatic summary updates. While paused, the summary remains as-is. You can still force an update by pressing the Summarize now button (which is only available with the Main API).": "자동 요약 업데이트를 비활성화합니다. 일시 중지된 동안 요약은 그대로 유지됩니다. 지금 요약 버튼(기본 API에서만 사용 가능)을 눌러 강제로 업데이트할 수 있습니다.", | 1203 | "Disable automatic summary updates. While paused, the summary remains as-is. You can still force an update by pressing the Summarize now button (which is only available with the Main API).": "자동 요약 업데이트를 비활성화합니다. 일시 중지된 동안 요약은 그대로 유지됩니다. 지금 요약 버튼(기본 API에서만 사용 가능)을 눌러 강제로 업데이트할 수 있습니다.", |
| 1188 | "ext_sum_pause": "정지시키다", | 1204 | "ext_sum_pause": "요약 정지시키기", |
| 1189 | "Omit World Info and Author's Note from text to be summarized. Only has an effect when using the Main API. The Extras API always omits WI/AN.": "요약할 텍스트에서 World Info 및 Author's Note를 생략합니다. Main API를 사용할 때만 효과가 있습니다. Extras API는 항상 WI/AN을 생략합니다.", | 1205 | "Omit World Info and Author's Note from text to be summarized. Only has an effect when using the Main API. The Extras API always omits WI/AN.": "요약할 텍스트에서 World Info 및 Author's Note를 생략합니다. Main API를 사용할 때만 효과가 있습니다. Extras API는 항상 WI/AN을 생략합니다.", |
| 1190 | "ext_sum_no_wi_an": "WI/AN 없음", | 1206 | "ext_sum_no_wi_an": "WI/AN 없음", |
| 1191 | "ext_sum_settings_tip": "요약 프롬프트, 삽입 위치 등을 편집합니다.", | 1207 | "ext_sum_settings_tip": "요약 프롬프트, 삽입 위치 등을 편집합니다.", |
| @@ -1193,7 +1209,7 @@ | |||
| 1193 | "ext_sum_prompt_builder": "프롬프트 빌더", | 1209 | "ext_sum_prompt_builder": "프롬프트 빌더", |
| 1194 | "ext_sum_prompt_builder_1_desc": "확장 프로그램은 아직 요약되지 않은 메시지를 사용하여 자체 프롬프트를 작성합니다. 요약이 생성될 때까지 채팅을 차단합니다.", | 1210 | "ext_sum_prompt_builder_1_desc": "확장 프로그램은 아직 요약되지 않은 메시지를 사용하여 자체 프롬프트를 작성합니다. 요약이 생성될 때까지 채팅을 차단합니다.", |
| 1195 | "ext_sum_prompt_builder_1": "원시, 차단", | 1211 | "ext_sum_prompt_builder_1": "원시, 차단", |
| 1196 | "ext_sum_prompt_builder_2_desc": "확장 프로그램은 아직 요약되지 않은 메시지를 사용하여 자체 프롬프트를 작성합니다. 요약이 생성되는 동안 채팅을 차단하지 않습니다. 모든 백엔드가 이 모드를 지원하는 것은 아닙니다.", | 1212 | "ext_sum_prompt_builder_2_desc": "확장 프로그램은 아직 요약되지 않은 메시지를 사용하여 자체 프롬프트를 작성합니다. 요약이 생성되는 동안 채팅을 차단하지 않습니다. 하지만 모든 백엔드가 이 모드를 지원하는 것은 아닙니다.", |
| 1197 | "ext_sum_prompt_builder_2": "원시, 비차단", | 1213 | "ext_sum_prompt_builder_2": "원시, 비차단", |
| 1198 | "ext_sum_prompt_builder_3_desc": "확장은 일반 기본 프롬프트 빌더를 사용하고 요약 요청을 마지막 시스템 메시지로 추가합니다.", | 1214 | "ext_sum_prompt_builder_3_desc": "확장은 일반 기본 프롬프트 빌더를 사용하고 요약 요청을 마지막 시스템 메시지로 추가합니다.", |
| 1199 | "ext_sum_prompt_builder_3": "클래식, 차단", | 1215 | "ext_sum_prompt_builder_3": "클래식, 차단", |
| @@ -1224,13 +1240,13 @@ | |||
| 1224 | "ext_regex_title": "정규식", | 1240 | "ext_regex_title": "정규식", |
| 1225 | "ext_regex_new_global_script": "+ 글로벌", | 1241 | "ext_regex_new_global_script": "+ 글로벌", |
| 1226 | "ext_regex_new_scoped_script": "+ 범위 지정", | 1242 | "ext_regex_new_scoped_script": "+ 범위 지정", |
| 1227 | "ext_regex_import_script": "수입", | 1243 | "ext_regex_import_script": "불러오기", |
| 1228 | "ext_regex_global_scripts": "글로벌 스크립트", | 1244 | "ext_regex_global_scripts": "글로벌 스크립트", |
| 1229 | "ext_regex_global_scripts_desc": "모든 캐릭터에 사용 가능합니다. 로컬 설정에 저장되었습니다.", | 1245 | "ext_regex_global_scripts_desc": "모든 캐릭터에 사용 가능합니다. 로컬 설정에 저장되었습니다.", |
| 1230 | "ext_regex_scoped_scripts": "범위가 지정된 스크립트", | 1246 | "ext_regex_scoped_scripts": "범위가 지정된 스크립트", |
| 1231 | "ext_regex_scoped_scripts_desc": "해당 캐릭터에만 사용 가능합니다. 카드 데이터에 저장됩니다.", | 1247 | "ext_regex_scoped_scripts_desc": "해당 캐릭터에만 사용 가능합니다. 카드 데이터에 저장됩니다.", |
| 1232 | "Regex Editor": "정규식 편집기", | 1248 | "Regex Editor": "정규식 편집기", |
| 1233 | "Test Mode": "시험 모드", | 1249 | "Test Mode": "테스트 모드", |
| 1234 | "ext_regex_desc": "Regex는 정규식을 사용하여 문자열을 찾거나 바꾸는 도구입니다. 자세한 내용을 보려면 ?를 클릭하세요. 제목 옆에.", | 1250 | "ext_regex_desc": "Regex는 정규식을 사용하여 문자열을 찾거나 바꾸는 도구입니다. 자세한 내용을 보려면 ?를 클릭하세요. 제목 옆에.", |
| 1235 | "Input": "입력", | 1251 | "Input": "입력", |
| 1236 | "ext_regex_test_input_placeholder": "여기에 입력하세요...", | 1252 | "ext_regex_test_input_placeholder": "여기에 입력하세요...", |
| @@ -1277,20 +1293,21 @@ | |||
| 1277 | "sd_refine_mode": "프롬프트를 생성 API로 보내기 전에 수동으로 편집할 수 있도록 허용", | 1293 | "sd_refine_mode": "프롬프트를 생성 API로 보내기 전에 수동으로 편집할 수 있도록 허용", |
| 1278 | "sd_refine_mode_txt": "생성 전에 프롬프트 편집", | 1294 | "sd_refine_mode_txt": "생성 전에 프롬프트 편집", |
| 1279 | "sd_interactive_mode": "'고양이 사진 보내주세요'와 같은 메시지를 보낼 때 자동으로 이미지를 생성합니다.", | 1295 | "sd_interactive_mode": "'고양이 사진 보내주세요'와 같은 메시지를 보낼 때 자동으로 이미지를 생성합니다.", |
| 1280 | "sd_interactive_mode_txt": "대화형 모드", | 1296 | "sd_interactive_mode_txt": "대화에 따른 자동 이미지 생성 모드", |
| 1281 | "sd_multimodal_captioning": "다중 모달 캡션을 사용하여 아바타를 기반으로 사용자 및 캐릭터 초상화에 대한 프롬프트를 생성합니다.", | 1297 | "sd_multimodal_captioning": "다중 모달 캡션을 사용하여 아바타를 기반으로 사용자 및 캐릭터 초상화에 대한 프롬프트를 생성합니다.", |
| 1282 | "sd_multimodal_captioning_txt": "인물 사진에 다중 모드 캡션 사용", | 1298 | "sd_multimodal_captioning_txt": "인물 사진에 다중 모드 캡션 사용", |
| 1283 | "sd_expand": "텍스트 생성 모델을 사용하여 프롬프트 자동 확장", | 1299 | "sd_expand": "텍스트 생성 모델을 사용하여 프롬프트 자동 확장", |
| 1284 | "sd_expand_txt": "자동 강화 프롬프트", | 1300 | "sd_expand_txt": "자동 강화 프롬프트", |
| 1285 | "sd_snap": "강제 종횡비(인물 사진, 배경)를 사용하여 가장 가까운 알려진 해상도로 스냅 생성을 요청하는 동시에 절대 픽셀 수를 유지하려고 합니다(SDXL에 권장).", | 1301 | "sd_snap": "강제 종횡비(인물 사진, 배경)를 사용하여 가장 가까운 알려진 해상도로 스냅 생성을 요청하는 동시에 절대 픽셀 수를 유지하려고 합니다(SDXL에 권장).", |
| 1286 | "sd_snap_txt": "스냅 자동 조정 해상도", | 1302 | "sd_snap_txt": "스냅 자동 조정 해상도", |
| 1287 | "Source": "원천", | 1303 | "Source": "근원", |
| 1304 | "Horde": "Horde", | ||
| 1288 | "sd_auto_url": "예: {{auto_url}}", | 1305 | "sd_auto_url": "예: {{auto_url}}", |
| 1289 | "Authentication (optional)": "인증(선택사항)", | 1306 | "Authentication (optional)": "인증(선택사항)", |
| 1290 | "Example: username:password": "예: 사용자 이름:비밀번호", | 1307 | "Example: username:password": "예: 사용자 이름:비밀번호", |
| 1291 | "Important:": "중요한:", | 1308 | "Important:": "중요한:", |
| 1292 | "sd_auto_auth_warning_1": "SD 웹 UI를 실행하세요", | 1309 | "sd_auto_auth_warning_1": "SD 웹 UI를 실행하세요", |
| 1293 | "sd_auto_auth_warning_2": "깃발! SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.", | 1310 | "sd_auto_auth_warning_2": "Flag! SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.", |
| 1294 | "sd_drawthings_url": "예: {{drawthings_url}}", | 1311 | "sd_drawthings_url": "예: {{drawthings_url}}", |
| 1295 | "sd_drawthings_auth_txt": "UI에서 HTTP API 스위치가 활성화된 상태에서 DrawThings 앱을 실행하세요! SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.", | 1312 | "sd_drawthings_auth_txt": "UI에서 HTTP API 스위치가 활성화된 상태에서 DrawThings 앱을 실행하세요! SillyTavern 호스트 시스템에서 서버에 액세스할 수 있어야 합니다.", |
| 1296 | "sd_vlad_url": "예: {{vlad_url}}", | 1313 | "sd_vlad_url": "예: {{vlad_url}}", |
| @@ -1308,26 +1325,28 @@ | |||
| 1308 | "Standard": "기준", | 1325 | "Standard": "기준", |
| 1309 | "HD": "HD(고화질)", | 1326 | "HD": "HD(고화질)", |
| 1310 | "sd_comfy_url": "예: {{comfy_url}}", | 1327 | "sd_comfy_url": "예: {{comfy_url}}", |
| 1311 | "Open workflow editor": "워크플로 편집기 열기", | 1328 | "Open workflow editor": "워크플로우로 편집기 열기", |
| 1312 | "Create new workflow": "새 워크플로 만들기", | 1329 | "Create new workflow": "새 워크플로우 만들기", |
| 1313 | "Delete workflow": "워크플로 삭제", | 1330 | "Delete workflow": "워크플로우 삭제", |
| 1314 | "Enhance": "향상시키다", | 1331 | "Enhance": "향상시키다", |
| 1315 | "Refine": "구체화", | 1332 | "Refine": "구체화", |
| 1316 | "Decrisper": "더 명확하게", | 1333 | "Decrisper": "더 명확하게", |
| 1317 | "Sampling steps": "샘플링 단계 ()", | 1334 | "Sampling steps": "샘플링 단계 ()", |
| 1318 | "Width": "너비 ()", | 1335 | "Width": "너비 ()", |
| 1319 | "Height": "키 ()", | 1336 | "Height": "높이 ()", |
| 1320 | "Resolution": "해결", | 1337 | "Resolution": "해상도", |
| 1321 | "Model": "모델", | 1338 | "Model": "모델", |
| 1339 | "Ask every time": "매번 물어보기", | ||
| 1322 | "Sampling method": "샘플링 방법", | 1340 | "Sampling method": "샘플링 방법", |
| 1341 | "Message Template": "메시지 템플릿", | ||
| 1323 | "Karras (not all samplers supported)": "Karras(일부 샘플러는 지원되지 않음)", | 1342 | "Karras (not all samplers supported)": "Karras(일부 샘플러는 지원되지 않음)", |
| 1324 | "SMEA versions of samplers are modified to perform better at high resolution.": "샘플러의 SMEA 버전은 고해상도에서 더 나은 성능을 발휘하도록 수정되었습니다.", | 1343 | "SMEA versions of samplers are modified to perform better at high resolution.": "샘플러의 SMEA 버전은 고해상도에서 더 나은 성능을 발휘하도록 수정되었습니다.", |
| 1325 | "SMEA": "SMEA", | 1344 | "SMEA": "SMEA", |
| 1326 | "DYN variants of SMEA samplers often lead to more varied output, but may fail at very high resolutions.": "SMEA 샘플러의 DYN 변형은 종종 더 다양한 출력으로 이어지지만 매우 높은 해상도에서는 실패할 수 있습니다.", | 1345 | "DYN variants of SMEA samplers often lead to more varied output, but may fail at very high resolutions.": "SMEA 샘플러의 DYN 변형은 종종 더 다양한 출력으로 이어지지만 매우 높은 해상도에서는 실패할 수 있습니다.", |
| 1327 | "DYN": "DYN", | 1346 | "DYN": "DYN", |
| 1328 | "Scheduler": "스케줄러", | 1347 | "Scheduler": "스케줄러", |
| 1329 | "Restore Faces": "얼굴 복원", | 1348 | "Restore Faces": "얼굴 디테일 복원", |
| 1330 | "Hires. Fix": "고용합니다. 고치다", | 1349 | "Hires. Fix": "고해상도 업스케일", |
| 1331 | "Upscaler": "업스케일러", | 1350 | "Upscaler": "업스케일러", |
| 1332 | "Upscale by": "고급화", | 1351 | "Upscale by": "고급화", |
| 1333 | "Denoising strength": "노이즈 제거 강도", | 1352 | "Denoising strength": "노이즈 제거 강도", |
| @@ -1371,7 +1390,7 @@ | |||
| 1371 | "Import Characters": "캐릭터 가져오기", | 1390 | "Import Characters": "캐릭터 가져오기", |
| 1372 | "Enter the URL of the content to import": "가져올 콘텐츠의 URL을 입력하세요.", | 1391 | "Enter the URL of the content to import": "가져올 콘텐츠의 URL을 입력하세요.", |
| 1373 | "Supported sources:": "지원되는 소스:", | 1392 | "Supported sources:": "지원되는 소스:", |
| 1374 | "char_import_1": "처브 캐릭터 (다이렉트 링크 또는 ID)", | 1393 | "char_import_1": "Chub 캐릭터 (다이렉트 링크 또는 ID)", |
| 1375 | "char_import_example": "예:", | 1394 | "char_import_example": "예:", |
| 1376 | "char_import_2": "Chub Lorebook(직접 링크 또는 ID)", | 1395 | "char_import_2": "Chub Lorebook(직접 링크 또는 ID)", |
| 1377 | "char_import_3": "JanitorAI 캐릭터(직접 링크 또는 UUID)", | 1396 | "char_import_3": "JanitorAI 캐릭터(직접 링크 또는 UUID)", |
| @@ -1402,7 +1421,7 @@ | |||
| 1402 | "Make a Snapshot": "스냅샷 만들기", | 1421 | "Make a Snapshot": "스냅샷 만들기", |
| 1403 | "Restore this snapshot": "이 스냅샷 복원", | 1422 | "Restore this snapshot": "이 스냅샷 복원", |
| 1404 | "Hi,": "안녕,", | 1423 | "Hi,": "안녕,", |
| 1405 | "To enable multi-account features, restart the SillyTavern server with": "다중 계정 기능을 활성화하려면 SillyTavern 서버를 다시 시작하십시오.", | 1424 | "To enable multi-account features, restart the SillyTavern server with": "다중 계정 기능을 활성화하려면 SillyTavern 서버를 다시 시작하세요.", |
| 1406 | "set to true in the config.yaml file.": "config.yaml 파일에서 true로 설정됩니다.", | 1425 | "set to true in the config.yaml file.": "config.yaml 파일에서 true로 설정됩니다.", |
| 1407 | "Account Info": "계정 정보", | 1426 | "Account Info": "계정 정보", |
| 1408 | "To change your user avatar, use the buttons below or select a default persona in the Persona Management menu.": "사용자 아바타를 변경하려면 아래 버튼을 사용하거나 페르소나 관리 메뉴에서 기본 페르소나를 선택하세요.", | 1427 | "To change your user avatar, use the buttons below or select a default persona in the Persona Management menu.": "사용자 아바타를 변경하려면 아래 버튼을 사용하거나 페르소나 관리 메뉴에서 기본 페르소나를 선택하세요.", |
| @@ -1418,26 +1437,190 @@ | |||
| 1418 | "Download Backup": "백업 다운로드", | 1437 | "Download Backup": "백업 다운로드", |
| 1419 | "Danger Zone": "위험지대", | 1438 | "Danger Zone": "위험지대", |
| 1420 | "Reset your settings to factory defaults.": "설정을 공장 기본값으로 재설정하세요.", | 1439 | "Reset your settings to factory defaults.": "설정을 공장 기본값으로 재설정하세요.", |
| 1421 | "Reset Settings": "설정 재설정", | 1440 | "Reset Settings": "설정 초기화", |
| 1422 | "Wipe all user data and reset your account to factory settings.": "모든 사용자 데이터를 지우고 계정을 공장 설정으로 재설정하세요.", | 1441 | "Wipe all user data and reset your account to factory settings.": "모든 사용자 데이터를 지우고 계정을 공장 설정으로 재설정하세요.", |
| 1423 | "Reset Everything": "모든 것을 재설정", | 1442 | "Reset Everything": "모든 것을 재설정", |
| 1424 | "Reset Code:": "재설정 코드:", | 1443 | "Reset Code:": "재설정 코드:", |
| 1425 | "Want to update?": "업데이트 하시겠습니까?", | 1444 | "Want to update?": "업데이트 하시겠습니까?", |
| 1426 | "How to start chatting?": "채팅을 시작하는 방법은?", | 1445 | "How to start chatting?": "어떻게 채팅을 시작할 수 있나요?", |
| 1427 | "Click _space": "딸깍 하는 소리", | 1446 | "Click _space": "해당 아이콘을 클릭하세요.", |
| 1428 | "and select a": "그리고 선택하십시오", | 1447 | "and connect to an": "그리고 API를 해당 탭에서 연결하세요.", |
| 1448 | "and select a": "그리고 선택하세요.", | ||
| 1429 | "Chat API": "채팅 API", | 1449 | "Chat API": "채팅 API", |
| 1430 | "and pick a character.": "그리고 캐릭터를 선택하세요.", | 1450 | "and pick a character.": "그리고 원하는 캐릭터를 선택하세요.", |
| 1431 | "You can browse a list of bundled characters in the": "번들 캐릭터 목록을 검색할 수 있습니다.", | 1451 | "You can browse a list of bundled characters in the": "번들 캐릭터 목록을 검색할 수 있습니다.", |
| 1432 | "Download Extensions & Assets": "확장 프로그램 및 자산 다운로드", | 1452 | "Download Extensions & Assets": "확장 프로그램 및 에셋 다운로드", |
| 1453 | "Character Expressions": "캐릭터 감정 표현들", | ||
| 1454 | "ext_translate_title": "채팅 번역", | ||
| 1455 | "ext_translate_auto_mode": "자동 번역 모드", | ||
| 1456 | "ext_translate_mode_none": "없음", | ||
| 1457 | "ext_translate_mode_responses": "응답 자동 번역", | ||
| 1458 | "ext_translate_mode_inputs": "입력 자동 번역", | ||
| 1459 | "ext_translate_mode_both": "응답과 입력 모두 번역", | ||
| 1460 | "ext_translate_mode_provider": "번역 공급자", | ||
| 1461 | "ext_translate_target_lang": "번역 도착 언어", | ||
| 1462 | "ext_translate_clear": "번역 지우기", | ||
| 1463 | "ext_sum_title": "채팅 요약", | ||
| 1464 | "ext_sum_with": "요약에 사용될 API:", | ||
| 1465 | "ext_sum_main_api": "메인 API", | ||
| 1466 | "Vector Storage": "벡터 저장소", | ||
| 1433 | "menu within": "내의 메뉴", | 1467 | "menu within": "내의 메뉴", |
| 1468 | "Translate text to English before classification": "분류 전에 텍스트를 영어로 번역합니다.", | ||
| 1469 | "Show default images (emojis) if sprite missing": "해당하는 스프라이트가 없으면 기본 이미지 (이모지들)을 표시합니다.", | ||
| 1470 | "Image Type - talkinghead (extras)": "이미지 유형 - 토킹 헤드 (부가 사항)", | ||
| 1471 | "Classifier API": "분류를 위한 API", | ||
| 1472 | "Select the API for classifying expressions.": "감정 이미지들을 분류할 API를 선택하세요.", | ||
| 1473 | "Local": "로컬", | ||
| 1474 | "Extras": "외부", | ||
| 1475 | "LLM": "대형 언어 모델(LLM)", | ||
| 1476 | "LLM Prompt": "LLM 프롬프트", | ||
| 1477 | "Will be used if the API doesn't support JSON schemas or function calling.": "API가 JSON 스키마나 함수 호출을 지원하지 않는 경우 사용됩니다.", | ||
| 1478 | "Default / Fallback Expression": "기본 / 대체 감정들", | ||
| 1479 | "Set the default and fallback expression being used when no matching expression is found.": "일치하는 표현이 없을 때 사용되는 기본 및 대체 표현을 설정합니다.", | ||
| 1480 | "Custom Expressions": "커스텀 감정들", | ||
| 1481 | "Can be set manually or with an _space": "수동으로 설정하거나 또는", | ||
| 1482 | "space_ slash command.": "슬래시 명령어로 설정할 수 있습니다.", | ||
| 1483 | "Open a chat to see the character expressions.": "캐릭터 감정을 보려면 채팅창을 열어주세요.", | ||
| 1484 | "Sprite Folder Override": "스프라이트 폴더 덮어쓰기", | ||
| 1485 | "Upload sprite pack (ZIP)": "스프라이트 압축팩 (ZIP) 업로드하기", | ||
| 1486 | "Remove all image overrides": "모든 이미지 재정의 제거하기", | ||
| 1487 | "Hint:": "힌트:", | ||
| 1488 | "Create new folder in the _space": "사용자 데이터 경로에 있는", | ||
| 1489 | "folder of your user data directory and name it as the name of the character.": "폴더에 새 폴더를 만들고 해당 폴더의 이름을 캐릭터의 이름으로 지정하세요.", | ||
| 1490 | "Put images with expressions there. File names should follow the pattern:": "그리고 그곳에 표정이 담긴 이미지를 넣으세요. 파일 이름은 다음 패턴을 따라야 합니다:", | ||
| 1491 | "Sprite set:": "스프라이트 세트:", | ||
| 1492 | "sd_free_extend_txt": "무료 모드 프롬프트 확장", | ||
| 1434 | "Confused or lost?": "혼란스러우시거나 길을 잃으셨나요?", | 1493 | "Confused or lost?": "혼란스러우시거나 길을 잃으셨나요?", |
| 1435 | "click these icons!": "이 아이콘을 클릭하세요!", | 1494 | "click these icons!": "이 아이콘을 클릭하세요!", |
| 1436 | "in the chat bar": "채팅 바에서", | 1495 | "in the chat bar": "채팅 바에서", |
| 1437 | "SillyTavern Documentation Site": "SillyTavern 문서 사이트", | 1496 | "SillyTavern Documentation Site": "SillyTavern 공식 문서 사이트", |
| 1438 | "Extras Installation Guide": "Extras 설치 안내서", | 1497 | "Extras Installation Guide": "Extras 설치 안내서", |
| 1439 | "Still have questions?": "아직 질문이 있으신가요?", | 1498 | "Still have questions?": "아직 질문이 있으신가요?", |
| 1440 | "Join the SillyTavern Discord": "SillyTavern Discord에 참여하세요", | 1499 | "Join the SillyTavern Discord": "SillyTavern 디스코드에 참여하세요", |
| 1441 | "Post a GitHub issue": "GitHub 이슈 게시", | 1500 | "Post a GitHub issue": "GitHub 이슈 게시", |
| 1442 | "Contact the developers": "개발자에게 연락하기" | 1501 | "Contact the developers": "개발자에게 연락하기", |
| 1502 | "enable_functions_desc_1": "다양한 확장 프로그램에서 추가 기능을 제공하기 위한", | ||
| 1503 | "enable_functions_desc_2": "기능 도구", | ||
| 1504 | "enable_functions_desc_3": "를 사용할 수 있게 합니다.", | ||
| 1505 | "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "삽입 깊이. 상대적인 (프롬프트 관리 목록에 있는 다른 프롬프트들에 비해) 또는 @Depth 깊이에 따라.", | ||
| 1506 | "Instruct Template": "지시 템플릿", | ||
| 1507 | "System Message Sequences": "시스템 메시지 시퀀스", | ||
| 1508 | "System Prompt Sequences": "시스템 프롬프트 시퀀스", | ||
| 1509 | "First User Prefix": "첫 번째 유저 접두사", | ||
| 1510 | "Last User Prefix": "마지막 유저 접두사", | ||
| 1511 | "System Prefix": "시스템 메시지 접두사", | ||
| 1512 | "System Suffix": "시스템 메시지 접미사", | ||
| 1513 | "Assistant Message Sequences": "어시스턴트 메시지 시퀀스", | ||
| 1514 | "Assistant Prefix": "어시스턴트 메시지 접두사", | ||
| 1515 | "Assistant Suffix": "어시스턴트 메시지 접미사", | ||
| 1516 | "User Message Sequences": "유저 메시지 시퀀스", | ||
| 1517 | "User Prefix": "유저 메시지 접미사", | ||
| 1518 | "User Suffix": "유저 메시지 접두사", | ||
| 1519 | "Groups and Past Personas": "그룹과 과거 페르소나들", | ||
| 1520 | "Never": "절대 추가하지 않음", | ||
| 1521 | "Always": "항상 추가함", | ||
| 1522 | "Separators as Stop Strings": "구분 기호를 정지 문자열로 사용하기", | ||
| 1523 | "Names as Stop Strings": "캐릭터의 이름들을 정지 문자열로 사용하기", | ||
| 1524 | "Allow Post-History Instructions": "Post-History 지침 허용", | ||
| 1525 | "Image Captioning": "이미지 캡셔닝", | ||
| 1526 | "Automatically caption images": "자동으로 이미지에 대한 설명 문장으로 나타내기", | ||
| 1527 | "Edit captions before saving": "저장하기 전에 이미지에 대한 설명 문장 편집하기", | ||
| 1528 | "Enable Quick Replies": "빠른 답장 활성화", | ||
| 1529 | "Combine Quick Replies": "빠른 답장 결합하기", | ||
| 1530 | "Show Popout Button": "팝아웃 버튼 표시 (데스크톱에서)", | ||
| 1531 | "Global Quick Reply Sets": "글로벌 빠른 답장 세트들", | ||
| 1532 | "Edit Quick Replies": "빠른 답변 편집하기", | ||
| 1533 | "Disable send (insert into input field)": "보내기 비활성화 (입력 필드에 삽입)", | ||
| 1534 | "Place quick reply before input": "인풋 전에 빠른 답변 위치하게 하기", | ||
| 1535 | "Inject user input automatically": "사용자 인풋 자동으로 주입하기", | ||
| 1536 | "(if disabled, use ": "비활성화된 경우,", | ||
| 1537 | "macro for manual injection)": "매크로를 사용하여 수동으로 주입하세요.", | ||
| 1538 | "Only apply color as accent": "색상은 오직 강조로써만 적용됩니다", | ||
| 1539 | "qr--colorClear": "색상 지우기", | ||
| 1540 | "Color": "색상", | ||
| 1541 | "[title]world_button_title": "캐릭터 로어. 클릭하여 로드하세요. Shift를 클릭하면 '월드 인포 링크' 팝업이 열립니다.", | ||
| 1542 | "Select TTS Provider": "TTS 공급자 선택", | ||
| 1543 | "tts_enabled": "활성화", | ||
| 1544 | "Narrate user messages": "사용자 메시지 나레이션", | ||
| 1545 | "Auto Generation": "자동 생성", | ||
| 1546 | "Requires auto generation to be enabled.": "자동 생성이 활성화 된 상태여야 합니다.", | ||
| 1547 | "Narrate by paragraphs (when streaming)": "(스트리밍이 진행 중일 때) 단락 별로 설명하기", | ||
| 1548 | "Only narrate quotes": "대사만 나레이션 하기", | ||
| 1549 | "Ignore text, even quotes, inside asterisk": "대사나 별표에 관계없이 모든 텍스트를 무시하기", | ||
| 1550 | "Narrate only the translated text": "오직 번역된 텍스트만 나레이션", | ||
| 1551 | "Skip codeblocks": "코드 블럭 안의 내용 읽지 않기", | ||
| 1552 | "Skip tagged blocks": "태그 안의 내용 읽지 않기", | ||
| 1553 | "Pass Asterisks to TTS Engine": "TTS 엔진에 별표 전달하기", | ||
| 1554 | "Audio Playback Speed": "음성 재생 속도", | ||
| 1555 | "Vectorization Model": "벡터화 모델", | ||
| 1556 | "Keep model in memory": "모델을 메모리에 유지하기", | ||
| 1557 | "Hint: Set the URL in the API connection settings.": "힌트: API 연결 설정에서 URL을 설정하세요.", | ||
| 1558 | "The server MUST be started with the --embedding flag to use this feature!": "이 기능을 사용하려면 서버를 --embedding 플래그와 함께 시작해야 합니다!", | ||
| 1559 | "Click to set": "설정하려면 클릭하세요", | ||
| 1560 | "Chunk boundary": "청크 바운더리", | ||
| 1561 | "World Info settings": "월드인포 설정", | ||
| 1562 | "Enable for World Info": "월드인포에 활성화", | ||
| 1563 | "Vectorization Source": "벡터화 근원", | ||
| 1564 | "File vectorization settings": "파일 벡터화 설정", | ||
| 1565 | "Enable for files": "파일에 활성화", | ||
| 1566 | "Chat vectorization settings": "채팅 벡터화 설정", | ||
| 1567 | "Enabled for chat messages": "채팅 메시지에 활성화", | ||
| 1568 | "Injection Position": "삽입 깊이", | ||
| 1569 | "Chunk size (chars)": "청크 사이즈 (단위: 문자당)", | ||
| 1570 | "Vector Summarization": "벡터 요약", | ||
| 1571 | "Summarize chat messages for vector generation": "벡터 생성을 위한 채팅 메시지 요약하기", | ||
| 1572 | "Warning: This will slow down vector generation drastically, as all messages have to be summarized first.": "경고: 모든 메시지를 먼저 요약해야 하므로 벡터 생성 속도가 크게 느려질 것입니다.", | ||
| 1573 | "Summarize chat messages when sending": "채팅 메시지를 전송할 때 요약하기", | ||
| 1574 | "Warning: This might cause your sent messages to take a bit to process and slow down response time.": "경고: 이로 인해 전송한 메시지가 처리되는 데 시간이 걸리고 응답 속도가 느려질 수 있습니다.", | ||
| 1575 | "Summarize with:": "요약을 위해 사용:", | ||
| 1576 | "Summary Prompt:": "요약 프롬프트", | ||
| 1577 | "Only used when Main API or WebLLM Extension is selected.": "메인 API 또는 WebLLM 확장이 선택될 때만 사용됩니다.", | ||
| 1578 | "Old messages are vectorized gradually as you chat. To process all previous messages, click the button below.": "이전 메시지는 채팅하는 동안 점진적으로 벡터화됩니다. 모든 이전 메시지를 처리하려면 아래 버튼을 클릭하세요.", | ||
| 1579 | "Vectorize All": "전부 벡터화", | ||
| 1580 | "Purge Vectors": "벡터 정리", | ||
| 1581 | "View Stats": "상태 확인", | ||
| 1582 | "Connection Profile": "연결 프로필", | ||
| 1583 | "Prompt Content": "프롬프트 내용", | ||
| 1584 | "Instruct Sequences": "지시 시퀀스", | ||
| 1585 | "Prefer Character Card Instructions": "캐릭터 카드의 지시사항을 선호", | ||
| 1586 | "[title]If checked and the character card contains a Post-History Instructions override, use that instead": "활성화 된 경우, 캐릭터 카드에 Post-History 지시 무시 항목이 포함되어 있으면, 카드 지시사항의 내용으로 대신 사용합니다.", | ||
| 1587 | "Auto-select Input Text": "입력 텍스트 자동 선택", | ||
| 1588 | "[title]Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "일부 텍스트 필드를 클릭하거나 선택할 때 자동으로 입력된 텍스트가 선택되도록 설정합니다. 팝업 입력창과 기타 커스텀 입력 필드에 적용됩니다.", | ||
| 1589 | "Markdown Hotkeys": "마크다운 입력 단축키", | ||
| 1590 | "[title]markdown_hotkeys_desc": "특정 텍스트 입력창에서 마크다운 형식 문자를 입력하기 위한 단축키를 활성화합니다. '/help hotkeys'를 참고하세요.", | ||
| 1591 | "Show group chat queue": "그룹 채팅 대기열 표시", | ||
| 1592 | "[title]In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond.": "그룹 채팅에서 응답을 생성하기 위해 현재 대기 중인 캐릭터와 응답할 순서를 강조 표시합니다.", | ||
| 1593 | "Quick 'Impersonate' button": "빠른 '사칭' 버튼", | ||
| 1594 | "[title]Show a button in the input area to ask the AI to impersonate your character for a single message": "입력 영역에 AI에게 한 메시지 동안 당신의 캐릭터 연기를 사칭하도록 요청하는 버튼을 표시합니다.", | ||
| 1595 | "Injection Template": "삽입 템플릿", | ||
| 1596 | "Query messages": "쿼리 메시지 수", | ||
| 1597 | "Score threshold": "점수 임계값", | ||
| 1598 | "ext_sum_include_wi_scan": "월드 인포를 요약 범위에 포함", | ||
| 1599 | "(use _space": "이", | ||
| 1600 | "macro)": "매크로를 사용하세요", | ||
| 1601 | "Disable Send (Insert Into Input Field)": "전송 비활성화 (입력 필드에 삽입)", | ||
| 1602 | "Place Quick Reply Before Input": "빠른 답변을 입력란 앞에 배치", | ||
| 1603 | "Chat Message Visibility (by source)": "채팅 메시지 가시성 (근원별)", | ||
| 1604 | "Uncheck to hide the extension's messages in chat prompts.": "체크를 해제하여 채팅 프롬프트에서 확장 프로그램의 메시지를 숨기세요.", | ||
| 1605 | "Extensions Menu": "확장 메뉴", | ||
| 1606 | "Slash Command": "슬래시 명령어", | ||
| 1607 | "Interactive Mode": "인터랙티브 모드", | ||
| 1608 | "Load a custom asset list or select": "커스텀 에셋 목록을 불러오거나", | ||
| 1609 | "to install 3rd party extensions.": "를 선택하여 3rd 파티 확장 프로그램을 설치하세요.", | ||
| 1610 | "Assets URL": "에셋 URL", | ||
| 1611 | "Load an asset list": "에셋 목록을 불러옵니다.", | ||
| 1612 | "ext_translate_btn_chat": "채팅 번역하기", | ||
| 1613 | "ext_translate_btn_input": "입력 번역하기", | ||
| 1614 | "Ask": "묻기", | ||
| 1615 | "tag_import_none": "불러오지 않음", | ||
| 1616 | "tag_import_all": "전부", | ||
| 1617 | "Existing": "기존 태그 참조", | ||
| 1618 | "You can add more": "원한다면", | ||
| 1619 | "or_welcome": "또는", | ||
| 1620 | "from other websites": "를 통해 다른 웹사이트들로부터 불러올 수 있습니다.", | ||
| 1621 | "Go to the": "추가 기능 설치를 하려면", | ||
| 1622 | "to install additional features.": "으로 가세요.", | ||
| 1623 | "Master Import": "마스터 불러오기", | ||
| 1624 | "Master Export": "마스터 내보내기", | ||
| 1625 | "Chat Quick Reply Sets": "채팅 빠른 답장 세트들" | ||
| 1443 | } | 1626 | } |
| 1443 | \ No newline at end of file | 1626 | \ No newline at end of file |
| @@ -267,6 +267,7 @@ import { applyBrowserFixes } from './scripts/browser-fixes.js'; | |||
| 267 | import { initServerHistory } from './scripts/server-history.js'; | 267 | import { initServerHistory } from './scripts/server-history.js'; |
| 268 | import { initSettingsSearch } from './scripts/setting-search.js'; | 268 | import { initSettingsSearch } from './scripts/setting-search.js'; |
| 269 | import { initBulkEdit } from './scripts/bulk-edit.js'; | 269 | import { initBulkEdit } from './scripts/bulk-edit.js'; |
| 270 | import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js'; | ||
| 270 | 271 | ||
| 271 | //exporting functions and vars for mods | 272 | //exporting functions and vars for mods |
| 272 | export { | 273 | export { |
| @@ -1235,6 +1236,38 @@ async function getStatusTextgen() { | |||
| 1235 | const supportsTokenization = response.headers.get('x-supports-tokenization') === 'true'; | 1236 | const supportsTokenization = response.headers.get('x-supports-tokenization') === 'true'; |
| 1236 | supportsTokenization ? sessionStorage.setItem(TOKENIZER_SUPPORTED_KEY, 'true') : sessionStorage.removeItem(TOKENIZER_SUPPORTED_KEY); | 1237 | supportsTokenization ? sessionStorage.setItem(TOKENIZER_SUPPORTED_KEY, 'true') : sessionStorage.removeItem(TOKENIZER_SUPPORTED_KEY); |
| 1237 | 1238 | ||
| 1239 | const wantsInstructDerivation = (power_user.instruct.enabled && power_user.instruct.derived); | ||
| 1240 | const wantsContextDerivation = power_user.context_derived; | ||
| 1241 | const supportsChatTemplate = [textgen_types.KOBOLDCPP, textgen_types.LLAMACPP].includes(textgen_settings.type); | ||
| 1242 | if (supportsChatTemplate && (wantsInstructDerivation || wantsContextDerivation)) { | ||
| 1243 | const response = await fetch('/api/backends/text-completions/props', { | ||
| 1244 | method: 'POST', | ||
| 1245 | headers: getRequestHeaders(), | ||
| 1246 | body: JSON.stringify({ | ||
| 1247 | api_server: endpoint, | ||
| 1248 | api_type: textgen_settings.type, | ||
| 1249 | }), | ||
| 1250 | }); | ||
| 1251 | |||
| 1252 | if (response.ok) { | ||
| 1253 | const data = await response.json(); | ||
| 1254 | if (data) { | ||
| 1255 | const { chat_template, chat_template_hash } = data; | ||
| 1256 | console.log(`We have chat template ${chat_template.split('\n')[0]}...`); | ||
| 1257 | const templates = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash); | ||
| 1258 | if (templates) { | ||
| 1259 | const { context, instruct } = templates; | ||
| 1260 | if (wantsContextDerivation) { | ||
| 1261 | selectContextPreset(context, { isAuto: true }); | ||
| 1262 | } | ||
| 1263 | if (wantsInstructDerivation) { | ||
| 1264 | selectInstructPreset(instruct, { isAuto: true }); | ||
| 1265 | } | ||
| 1266 | } | ||
| 1267 | } | ||
| 1268 | } | ||
| 1269 | } | ||
| 1270 | |||
| 1238 | // We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress. | 1271 | // We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress. |
| 1239 | if (online_status === 'no_connection' && data.response) { | 1272 | if (online_status === 'no_connection' && data.response) { |
| 1240 | toastr.error(data.response, t`API Error`, { timeOut: 5000, preventDuplicates: true }); | 1273 | toastr.error(data.response, t`API Error`, { timeOut: 5000, preventDuplicates: true }); |
| @@ -2672,8 +2705,7 @@ export async function generateQuietPrompt(quiet_prompt, quietToLoud, skipWIAN, q | |||
| 2672 | quietName: quietName, | 2705 | quietName: quietName, |
| 2673 | }; | 2706 | }; |
| 2674 | originalResponseLength = responseLengthCustomized ? saveResponseLength(main_api, responseLength) : -1; | 2707 | originalResponseLength = responseLengthCustomized ? saveResponseLength(main_api, responseLength) : -1; |
| 2675 | const generateFinished = await Generate('quiet', options); | 2708 | return await Generate('quiet', options); |
| 2676 | return generateFinished; | ||
| 2677 | } finally { | 2709 | } finally { |
| 2678 | if (responseLengthCustomized) { | 2710 | if (responseLengthCustomized) { |
| 2679 | restoreResponseLength(main_api, originalResponseLength); | 2711 | restoreResponseLength(main_api, originalResponseLength); |
| @@ -3328,9 +3360,9 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy | |||
| 3328 | 3360 | ||
| 3329 | let data = {}; | 3361 | let data = {}; |
| 3330 | 3362 | ||
| 3331 | if (api == 'koboldhorde') { | 3363 | if (api === 'koboldhorde') { |
| 3332 | data = await generateHorde(prompt, generateData, abortController.signal, false); | 3364 | data = await generateHorde(prompt, generateData, abortController.signal, false); |
| 3333 | } else if (api == 'openai') { | 3365 | } else if (api === 'openai') { |
| 3334 | data = await sendOpenAIRequest('quiet', generateData, abortController.signal); | 3366 | data = await sendOpenAIRequest('quiet', generateData, abortController.signal); |
| 3335 | } else { | 3367 | } else { |
| 3336 | const generateUrl = getGenerateUrl(api); | 3368 | const generateUrl = getGenerateUrl(api); |
| @@ -3343,13 +3375,15 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy | |||
| 3343 | }); | 3375 | }); |
| 3344 | 3376 | ||
| 3345 | if (!response.ok) { | 3377 | if (!response.ok) { |
| 3346 | const error = await response.json(); | 3378 | throw await response.json(); |
| 3347 | throw error; | ||
| 3348 | } | 3379 | } |
| 3349 | 3380 | ||
| 3350 | data = await response.json(); | 3381 | data = await response.json(); |
| 3351 | } | 3382 | } |
| 3352 | 3383 | ||
| 3384 | // should only happen for text completions | ||
| 3385 | // other frontend paths do not return data if calling the backend fails, | ||
| 3386 | // they throw things instead | ||
| 3353 | if (data.error) { | 3387 | if (data.error) { |
| 3354 | throw new Error(data.response); | 3388 | throw new Error(data.response); |
| 3355 | } | 3389 | } |
| @@ -4401,6 +4435,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4401 | return Promise.resolve(); | 4435 | return Promise.resolve(); |
| 4402 | } | 4436 | } |
| 4403 | 4437 | ||
| 4438 | /** | ||
| 4439 | * Saves itemized prompt bits and calls streaming or non-streaming generation API. | ||
| 4440 | * @returns {Promise<void|*|Awaited<*>|String|{fromStream}|string|undefined|Object>} | ||
| 4441 | * @throws {Error|object} Error with message text, or Error with response JSON (OAI/Horde), or the actual response JSON (novel|textgenerationwebui|kobold) | ||
| 4442 | */ | ||
| 4404 | async function finishGenerating() { | 4443 | async function finishGenerating() { |
| 4405 | if (power_user.console_log_prompts) { | 4444 | if (power_user.console_log_prompts) { |
| 4406 | console.log(generate_data.prompt); | 4445 | console.log(generate_data.prompt); |
| @@ -4512,6 +4551,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4512 | 4551 | ||
| 4513 | return finishGenerating().then(onSuccess, onError); | 4552 | return finishGenerating().then(onSuccess, onError); |
| 4514 | 4553 | ||
| 4554 | /** | ||
| 4555 | * Handles the successful response from the generation API. | ||
| 4556 | * @param data | ||
| 4557 | * @returns {Promise<String|{fromStream}|*|string|string|void|Awaited<*>|undefined>} | ||
| 4558 | * @throws {Error} Throws an error if the response data contains an error message | ||
| 4559 | */ | ||
| 4515 | async function onSuccess(data) { | 4560 | async function onSuccess(data) { |
| 4516 | if (!data) return; | 4561 | if (!data) return; |
| 4517 | 4562 | ||
| @@ -4521,6 +4566,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4521 | 4566 | ||
| 4522 | let messageChunk = ''; | 4567 | let messageChunk = ''; |
| 4523 | 4568 | ||
| 4569 | // if an error was returned in data (textgenwebui), show it and throw it | ||
| 4524 | if (data.error) { | 4570 | if (data.error) { |
| 4525 | unblockGeneration(type); | 4571 | unblockGeneration(type); |
| 4526 | generatedPromptCache = ''; | 4572 | generatedPromptCache = ''; |
| @@ -4635,9 +4681,15 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4635 | return Object.defineProperty(new String(getMessage), 'messageChunk', { value: messageChunk }); | 4681 | return Object.defineProperty(new String(getMessage), 'messageChunk', { value: messageChunk }); |
| 4636 | } | 4682 | } |
| 4637 | 4683 | ||
| 4684 | /** | ||
| 4685 | * Exception handler for finishGenerating | ||
| 4686 | * @param {Error|object} exception Error or response JSON | ||
| 4687 | * @throws {Error|object} Re-throws the exception | ||
| 4688 | */ | ||
| 4638 | function onError(exception) { | 4689 | function onError(exception) { |
| 4690 | // if the response JSON was thrown (novel|textgenerationwebui|kobold), show the error message | ||
| 4639 | if (typeof exception?.error?.message === 'string') { | 4691 | if (typeof exception?.error?.message === 'string') { |
| 4640 | toastr.error(exception.error.message, t`Error`, { timeOut: 10000, extendedTimeOut: 20000 }); | 4692 | toastr.error(exception.error.message, t`Text generation error`, { timeOut: 10000, extendedTimeOut: 20000 }); |
| 4641 | } | 4693 | } |
| 4642 | 4694 | ||
| 4643 | generatedPromptCache = ''; | 4695 | generatedPromptCache = ''; |
| @@ -5305,6 +5357,7 @@ function setInContextMessages(lastmsg, type) { | |||
| 5305 | * @param {string} type Generation type | 5357 | * @param {string} type Generation type |
| 5306 | * @param {object} data Generation data | 5358 | * @param {object} data Generation data |
| 5307 | * @returns {Promise<object>} Response data from the API | 5359 | * @returns {Promise<object>} Response data from the API |
| 5360 | * @throws {Error|object} | ||
| 5308 | */ | 5361 | */ |
| 5309 | export async function sendGenerationRequest(type, data) { | 5362 | export async function sendGenerationRequest(type, data) { |
| 5310 | if (main_api === 'openai') { | 5363 | if (main_api === 'openai') { |
| @@ -5324,12 +5377,10 @@ export async function sendGenerationRequest(type, data) { | |||
| 5324 | }); | 5377 | }); |
| 5325 | 5378 | ||
| 5326 | if (!response.ok) { | 5379 | if (!response.ok) { |
| 5327 | const error = await response.json(); | 5380 | throw await response.json(); |
| 5328 | throw error; | ||
| 5329 | } | 5381 | } |
| 5330 | 5382 | ||
| 5331 | const responseData = await response.json(); | 5383 | return await response.json(); |
| 5332 | return responseData; | ||
| 5333 | } | 5384 | } |
| 5334 | 5385 | ||
| 5335 | /** | 5386 | /** |
| @@ -5361,6 +5412,7 @@ export async function sendStreamingRequest(type, data) { | |||
| 5361 | * Gets the generation endpoint URL for the specified API. | 5412 | * Gets the generation endpoint URL for the specified API. |
| 5362 | * @param {string} api API name | 5413 | * @param {string} api API name |
| 5363 | * @returns {string} Generation URL | 5414 | * @returns {string} Generation URL |
| 5415 | * @throws {Error} If the API is unknown | ||
| 5364 | */ | 5416 | */ |
| 5365 | function getGenerateUrl(api) { | 5417 | function getGenerateUrl(api) { |
| 5366 | switch (api) { | 5418 | switch (api) { |
| @@ -37,12 +37,15 @@ const chara_note_position = { | |||
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | function setNoteTextCommand(_, text) { | 39 | function setNoteTextCommand(_, text) { |
| 40 | if (text) { | ||
| 40 | $('#extension_floating_prompt').val(text).trigger('input'); | 41 | $('#extension_floating_prompt').val(text).trigger('input'); |
| 41 | toastr.success(t`Author's Note text updated`); | 42 | toastr.success(t`Author's Note text updated`); |
| 42 | return ''; | 43 | } |
| 44 | return chat_metadata[metadata_keys.prompt]; | ||
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | function setNoteDepthCommand(_, text) { | 47 | function setNoteDepthCommand(_, text) { |
| 48 | if (text) { | ||
| 46 | const value = Number(text); | 49 | const value = Number(text); |
| 47 | 50 | ||
| 48 | if (Number.isNaN(value)) { | 51 | if (Number.isNaN(value)) { |
| @@ -52,10 +55,12 @@ function setNoteDepthCommand(_, text) { | |||
| 52 | 55 | ||
| 53 | $('#extension_floating_depth').val(Math.abs(value)).trigger('input'); | 56 | $('#extension_floating_depth').val(Math.abs(value)).trigger('input'); |
| 54 | toastr.success(t`Author's Note depth updated`); | 57 | toastr.success(t`Author's Note depth updated`); |
| 55 | return ''; | 58 | } |
| 59 | return chat_metadata[metadata_keys.depth]; | ||
| 56 | } | 60 | } |
| 57 | 61 | ||
| 58 | function setNoteIntervalCommand(_, text) { | 62 | function setNoteIntervalCommand(_, text) { |
| 63 | if (text) { | ||
| 59 | const value = Number(text); | 64 | const value = Number(text); |
| 60 | 65 | ||
| 61 | if (Number.isNaN(value)) { | 66 | if (Number.isNaN(value)) { |
| @@ -65,25 +70,52 @@ function setNoteIntervalCommand(_, text) { | |||
| 65 | 70 | ||
| 66 | $('#extension_floating_interval').val(Math.abs(value)).trigger('input'); | 71 | $('#extension_floating_interval').val(Math.abs(value)).trigger('input'); |
| 67 | toastr.success(t`Author's Note frequency updated`); | 72 | toastr.success(t`Author's Note frequency updated`); |
| 68 | return ''; | 73 | } |
| 74 | return chat_metadata[metadata_keys.interval]; | ||
| 69 | } | 75 | } |
| 70 | 76 | ||
| 71 | function setNotePositionCommand(_, text) { | 77 | function setNotePositionCommand(_, text) { |
| 72 | const validPositions = { | 78 | const validPositions = { |
| 79 | 'after': 0, | ||
| 73 | 'scenario': 0, | 80 | 'scenario': 0, |
| 74 | 'chat': 1, | 81 | 'chat': 1, |
| 82 | 'before_scenario': 2, | ||
| 83 | 'before': 2, | ||
| 75 | }; | 84 | }; |
| 76 | 85 | ||
| 77 | const position = validPositions[text?.trim()]; | 86 | if (text) { |
| 87 | const position = validPositions[text?.trim()?.toLowerCase()]; | ||
| 78 | 88 | ||
| 79 | if (Number.isNaN(position)) { | 89 | if (typeof position === 'undefined') { |
| 80 | toastr.error(t`Not a valid position`); | 90 | toastr.error(t`Not a valid position`); |
| 81 | return; | 91 | return; |
| 82 | } | 92 | } |
| 83 | 93 | ||
| 84 | $(`input[name="extension_floating_position"][value="${position}"]`).prop('checked', true).trigger('input'); | 94 | $(`input[name="extension_floating_position"][value="${position}"]`).prop('checked', true).trigger('input'); |
| 85 | toastr.info(t`Author's Note position updated`); | 95 | toastr.info(t`Author's Note position updated`); |
| 86 | return ''; | 96 | } |
| 97 | return Object.keys(validPositions).find(key => validPositions[key] == chat_metadata[metadata_keys.position]); | ||
| 98 | } | ||
| 99 | |||
| 100 | function setNoteRoleCommand(_, text) { | ||
| 101 | const validRoles = { | ||
| 102 | 'system': 0, | ||
| 103 | 'user': 1, | ||
| 104 | 'assistant': 2, | ||
| 105 | }; | ||
| 106 | |||
| 107 | if (text) { | ||
| 108 | const role = validRoles[text?.trim()?.toLowerCase()]; | ||
| 109 | |||
| 110 | if (typeof role === 'undefined') { | ||
| 111 | toastr.error(t`Not a valid role`); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | |||
| 115 | $('#extension_floating_role').val(Math.abs(role)).trigger('input'); | ||
| 116 | toastr.info(t`Author's Note role updated`); | ||
| 117 | } | ||
| 118 | return Object.keys(validRoles).find(key => validRoles[key] == chat_metadata[metadata_keys.role]); | ||
| 87 | } | 119 | } |
| 88 | 120 | ||
| 89 | function updateSettings() { | 121 | function updateSettings() { |
| @@ -462,57 +494,84 @@ export function initAuthorsNote() { | |||
| 462 | }); | 494 | }); |
| 463 | $('#option_toggle_AN').on('click', onANMenuItemClick); | 495 | $('#option_toggle_AN').on('click', onANMenuItemClick); |
| 464 | 496 | ||
| 465 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'note', | 497 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 498 | name: 'note', | ||
| 466 | callback: setNoteTextCommand, | 499 | callback: setNoteTextCommand, |
| 500 | returns: 'current author\'s note', | ||
| 467 | unnamedArgumentList: [ | 501 | unnamedArgumentList: [ |
| 468 | new SlashCommandArgument( | 502 | new SlashCommandArgument( |
| 469 | 'text', [ARGUMENT_TYPE.STRING], true, | 503 | 'text', [ARGUMENT_TYPE.STRING], false, |
| 470 | ), | 504 | ), |
| 471 | ], | 505 | ], |
| 472 | helpString: ` | 506 | helpString: ` |
| 473 | <div> | 507 | <div> |
| 474 | Sets an author's note for the currently selected chat. | 508 | Sets an author's note for the currently selected chat if specified and returns the current note. |
| 475 | </div> | 509 | </div> |
| 476 | `, | 510 | `, |
| 477 | })); | 511 | })); |
| 478 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'depth', | 512 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 513 | name: 'note-depth', | ||
| 514 | aliases: ['depth'], | ||
| 479 | callback: setNoteDepthCommand, | 515 | callback: setNoteDepthCommand, |
| 516 | returns: 'current author\'s note depth', | ||
| 480 | unnamedArgumentList: [ | 517 | unnamedArgumentList: [ |
| 481 | new SlashCommandArgument( | 518 | new SlashCommandArgument( |
| 482 | 'number', [ARGUMENT_TYPE.NUMBER], true, | 519 | 'number', [ARGUMENT_TYPE.NUMBER], false, |
| 483 | ), | 520 | ), |
| 484 | ], | 521 | ], |
| 485 | helpString: ` | 522 | helpString: ` |
| 486 | <div> | 523 | <div> |
| 487 | Sets an author's note depth for in-chat positioning. | 524 | Sets an author's note depth for in-chat positioning if specified and returns the current depth. |
| 488 | </div> | 525 | </div> |
| 489 | `, | 526 | `, |
| 490 | })); | 527 | })); |
| 491 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'freq', | 528 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 529 | name: 'note-frequency', | ||
| 530 | aliases: ['freq', 'note-freq'], | ||
| 492 | callback: setNoteIntervalCommand, | 531 | callback: setNoteIntervalCommand, |
| 532 | returns: 'current author\'s note insertion frequency', | ||
| 493 | namedArgumentList: [], | 533 | namedArgumentList: [], |
| 494 | unnamedArgumentList: [ | 534 | unnamedArgumentList: [ |
| 495 | new SlashCommandArgument( | 535 | new SlashCommandArgument( |
| 496 | 'number', [ARGUMENT_TYPE.NUMBER], true, | 536 | 'number', [ARGUMENT_TYPE.NUMBER], false, |
| 497 | ), | 537 | ), |
| 498 | ], | 538 | ], |
| 499 | helpString: ` | 539 | helpString: ` |
| 500 | <div> | 540 | <div> |
| 501 | Sets an author's note insertion frequency. | 541 | Sets an author's note insertion frequency if specified and returns the current frequency. |
| 502 | </div> | 542 | </div> |
| 503 | `, | 543 | `, |
| 504 | })); | 544 | })); |
| 505 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'pos', | 545 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 546 | name: 'note-position', | ||
| 506 | callback: setNotePositionCommand, | 547 | callback: setNotePositionCommand, |
| 548 | aliases: ['pos', 'note-pos'], | ||
| 549 | returns: 'current author\'s note insertion position', | ||
| 550 | namedArgumentList: [], | ||
| 551 | unnamedArgumentList: [ | ||
| 552 | new SlashCommandArgument( | ||
| 553 | 'position', [ARGUMENT_TYPE.STRING], false, false, null, ['before', 'after', 'chat'], | ||
| 554 | ), | ||
| 555 | ], | ||
| 556 | helpString: ` | ||
| 557 | <div> | ||
| 558 | Sets an author's note position if specified and returns the current position. | ||
| 559 | </div> | ||
| 560 | `, | ||
| 561 | })); | ||
| 562 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 563 | name: 'note-role', | ||
| 564 | callback: setNoteRoleCommand, | ||
| 565 | returns: 'current author\'s note chat insertion role', | ||
| 507 | namedArgumentList: [], | 566 | namedArgumentList: [], |
| 508 | unnamedArgumentList: [ | 567 | unnamedArgumentList: [ |
| 509 | new SlashCommandArgument( | 568 | new SlashCommandArgument( |
| 510 | 'position', [ARGUMENT_TYPE.STRING], true, false, null, ['chat', 'scenario'], | 569 | 'position', [ARGUMENT_TYPE.STRING], false, false, null, ['system', 'user', 'assistant'], |
| 511 | ), | 570 | ), |
| 512 | ], | 571 | ], |
| 513 | helpString: ` | 572 | helpString: ` |
| 514 | <div> | 573 | <div> |
| 515 | Sets an author's note position. | 574 | Sets an author's note chat insertion role if specified and returns the current role. |
| 516 | </div> | 575 | </div> |
| 517 | `, | 576 | `, |
| 518 | })); | 577 | })); |
| @@ -89,7 +89,7 @@ | |||
| 89 | * @property {boolean} markdownOnly - Whether the script only applies to Markdown | 89 | * @property {boolean} markdownOnly - Whether the script only applies to Markdown |
| 90 | * @property {boolean} promptOnly - Whether the script only applies to prompts | 90 | * @property {boolean} promptOnly - Whether the script only applies to prompts |
| 91 | * @property {boolean} runOnEdit - Whether the script runs on edit | 91 | * @property {boolean} runOnEdit - Whether the script runs on edit |
| 92 | * @property {boolean} substituteRegex - Whether the regex should be substituted | 92 | * @property {number} substituteRegex - Whether the regex should be substituted |
| 93 | * @property {number} minDepth - The minimum depth | 93 | * @property {number} minDepth - The minimum depth |
| 94 | * @property {number} maxDepth - The maximum depth | 94 | * @property {number} maxDepth - The maximum depth |
| 95 | */ | 95 | */ |
| @@ -0,0 +1,81 @@ | |||
| 1 | // the hash can be obtained from command line e.g. via: MODEL=path_to_model; python -c "import json, hashlib, sys; print(hashlib.sha256(json.load(open('"$MODEL"/tokenizer_config.json'))['chat_template'].encode()).hexdigest())" | ||
| 2 | // note that chat templates must be trimmed to match the llama.cpp metadata value | ||
| 3 | const hash_derivations = { | ||
| 4 | // Meta | ||
| 5 | 'e10ca381b1ccc5cf9db52e371f3b6651576caee0a630b452e2816b2d404d4b65': | ||
| 6 | // Meta-Llama-3.1-8B-Instruct | ||
| 7 | // Meta-Llama-3.1-70B-Instruct | ||
| 8 | 'Llama 3 Instruct' | ||
| 9 | , | ||
| 10 | '5816fce10444e03c2e9ee1ef8a4a1ea61ae7e69e438613f3b17b69d0426223a4': | ||
| 11 | // Llama-3.2-1B-Instruct | ||
| 12 | // Llama-3.2-3B-Instruct | ||
| 13 | 'Llama 3 Instruct' | ||
| 14 | , | ||
| 15 | '73e87b1667d87ab7d7b579107f01151b29ce7f3ccdd1018fdc397e78be76219d': | ||
| 16 | // Nemotron 70B | ||
| 17 | 'Llama 3 Instruct' | ||
| 18 | , | ||
| 19 | |||
| 20 | // Mistral | ||
| 21 | // Mistral Reference: https://github.com/mistralai/mistral-common | ||
| 22 | 'e16746b40344d6c5b5265988e0328a0bf7277be86f1c335156eae07e29c82826': | ||
| 23 | // Mistral-Small-Instruct-2409 | ||
| 24 | // Mistral-Large-Instruct-2407 | ||
| 25 | 'Mistral V2 & V3' | ||
| 26 | , | ||
| 27 | '3c4ad5fa60dd8c7ccdf82fa4225864c903e107728fcaf859fa6052cb80c92ee9': | ||
| 28 | // Mistral-Large-Instruct-2411 | ||
| 29 | 'Mistral V7' // https://huggingface.co/mistralai/Mistral-Large-Instruct-2411 | ||
| 30 | , | ||
| 31 | 'e4676cb56dffea7782fd3e2b577cfaf1e123537e6ef49b3ec7caa6c095c62272': | ||
| 32 | // Mistral-Nemo-Instruct-2407 | ||
| 33 | 'Mistral V3-Tekken' | ||
| 34 | , | ||
| 35 | '26a59556925c987317ce5291811ba3b7f32ec4c647c400c6cc7e3a9993007ba7': | ||
| 36 | // Mistral-7B-Instruct-v0.3 | ||
| 37 | 'Mistral V2 & V3' | ||
| 38 | , | ||
| 39 | |||
| 40 | // Gemma | ||
| 41 | 'ecd6ae513fe103f0eb62e8ab5bfa8d0fe45c1074fa398b089c93a7e70c15cfd6': | ||
| 42 | // gemma-2-9b-it | ||
| 43 | // gemma-2-27b-it | ||
| 44 | 'Gemma 2' | ||
| 45 | , | ||
| 46 | '87fa45af6cdc3d6a9e4dd34a0a6848eceaa73a35dcfe976bd2946a5822a38bf3': | ||
| 47 | // gemma-2-2b-it | ||
| 48 | 'Gemma 2' | ||
| 49 | , | ||
| 50 | |||
| 51 | // Cohere | ||
| 52 | '3b54f5c219ae1caa5c0bb2cdc7c001863ca6807cf888e4240e8739fa7eb9e02e': | ||
| 53 | // command-r-08-2024 | ||
| 54 | 'Command R' | ||
| 55 | , | ||
| 56 | }; | ||
| 57 | |||
| 58 | const substr_derivations = { | ||
| 59 | '<|im_start|>': 'ChatML', // qwen2.5, ... | ||
| 60 | }; | ||
| 61 | |||
| 62 | const parse_derivation = derivation => (typeof derivation === 'string') ? { | ||
| 63 | 'context': derivation, | ||
| 64 | 'instruct': derivation, | ||
| 65 | } : derivation; | ||
| 66 | |||
| 67 | export async function deriveTemplatesFromChatTemplate(chat_template, hash) { | ||
| 68 | if (hash in hash_derivations) { | ||
| 69 | return parse_derivation(hash_derivations[hash]); | ||
| 70 | } | ||
| 71 | |||
| 72 | // heuristics | ||
| 73 | for (const [substr, derivation] of Object.entries(substr_derivations) ) { | ||
| 74 | if (chat_template.includes(substr)) { | ||
| 75 | return parse_derivation(derivation); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | console.log(`Unknown chat template hash: ${hash} for [${chat_template}]`); | ||
| 80 | return null; | ||
| 81 | } | ||
| @@ -61,6 +61,7 @@ | |||
| 61 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> | 61 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> |
| 62 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> | 62 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> |
| 63 | <option data-type="google" value="gemini-exp-1114">gemini-exp-1114</option> | 63 | <option data-type="google" value="gemini-exp-1114">gemini-exp-1114</option> |
| 64 | <option data-type="google" value="gemini-exp-1121">gemini-exp-1121</option> | ||
| 64 | <option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option> | 65 | <option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option> |
| 65 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | 66 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> |
| 66 | <option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> | 67 | <option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> |
| @@ -121,12 +121,16 @@ | |||
| 121 | <input type="checkbox" name="run_on_edit" /> | 121 | <input type="checkbox" name="run_on_edit" /> |
| 122 | <span data-i18n="Run On Edit">Run On Edit</span> | 122 | <span data-i18n="Run On Edit">Run On Edit</span> |
| 123 | </label> | 123 | </label> |
| 124 | <label class="checkbox flex-container" data-i18n="[title]ext_regex_substitute_regex_desc" title="Substitute {{macros}} in Find Regex before running it"> | 124 | <label class="checkbox flex-container flexNoGap marginBot5" data-i18n="[title]ext_regex_substitute_regex_desc" title="Substitute {{macros}} in Find Regex before running it"> |
| 125 | <input type="checkbox" name="substitute_regex" /> | ||
| 126 | <span> | 125 | <span> |
| 127 | <span data-i18n="Substitute Regex">Substitute Regex</span> | 126 | <small data-i18n="Macro in Find Regex">Macros in Find Regex</small> |
| 128 | <span class="fa-solid fa-circle-question note-link-span"></span> | 127 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 129 | </span> | 128 | </span> |
| 129 | <select name="substitute_regex" class="text_pole textarea_compact margin0"> | ||
| 130 | <option value="0" data-i18n="Don't substitute">Don't substitute</option> | ||
| 131 | <option value="1" data-i18n="Substitute (raw)">Substitute (raw)</option> | ||
| 132 | <option value="2" data-i18n="Substitute (escaped)">Substitute (escaped)</option> | ||
| 133 | </select> | ||
| 130 | </label> | 134 | </label> |
| 131 | <span> | 135 | <span> |
| 132 | <small data-i18n="ext_regex_other_options" data-i18n="Ephemerality">Ephemerality</small> | 136 | <small data-i18n="ext_regex_other_options" data-i18n="Ephemerality">Ephemerality</small> |
| @@ -22,6 +22,12 @@ const regex_placement = { | |||
| 22 | WORLD_INFO: 5, | 22 | WORLD_INFO: 5, |
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| 25 | export const substitute_find_regex = { | ||
| 26 | NONE: 0, | ||
| 27 | RAW: 1, | ||
| 28 | ESCAPED: 2, | ||
| 29 | }; | ||
| 30 | |||
| 25 | function sanitizeRegexMacro(x) { | 31 | function sanitizeRegexMacro(x) { |
| 26 | return (x && typeof x === 'string') ? | 32 | return (x && typeof x === 'string') ? |
| 27 | x.replaceAll(/[\n\r\t\v\f\0.^$*+?{}[\]\\/|()]/gs, function (s) { | 33 | x.replaceAll(/[\n\r\t\v\f\0.^$*+?{}[\]\\/|()]/gs, function (s) { |
| @@ -131,9 +137,20 @@ function runRegexScript(regexScript, rawString, { characterOverride } = {}) { | |||
| 131 | return newString; | 137 | return newString; |
| 132 | } | 138 | } |
| 133 | 139 | ||
| 134 | const regexString = regexScript.substituteRegex | 140 | const getRegexString = () => { |
| 135 | ? substituteParamsExtended(regexScript.findRegex, {}, sanitizeRegexMacro) | 141 | switch(Number(regexScript.substituteRegex)) { |
| 136 | : regexScript.findRegex; | 142 | case substitute_find_regex.NONE: |
| 143 | return regexScript.findRegex; | ||
| 144 | case substitute_find_regex.RAW: | ||
| 145 | return substituteParamsExtended(regexScript.findRegex); | ||
| 146 | case substitute_find_regex.ESCAPED: | ||
| 147 | return substituteParamsExtended(regexScript.findRegex, {}, sanitizeRegexMacro); | ||
| 148 | default: | ||
| 149 | console.warn(`runRegexScript: Unknown substituteRegex value ${regexScript.substituteRegex}. Using raw regex.`); | ||
| 150 | return regexScript.findRegex; | ||
| 151 | } | ||
| 152 | }; | ||
| 153 | const regexString = getRegexString(); | ||
| 137 | const findRegex = regexFromString(regexString); | 154 | const findRegex = regexFromString(regexString); |
| 138 | 155 | ||
| 139 | // The user skill issued. Return with nothing. | 156 | // The user skill issued. Return with nothing. |
| @@ -8,7 +8,7 @@ import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider. | |||
| 8 | import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js'; | 8 | import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js'; |
| 9 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; | 9 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; |
| 10 | import { download, getFileText, getSortableDelay, uuidv4 } from '../../utils.js'; | 10 | import { download, getFileText, getSortableDelay, uuidv4 } from '../../utils.js'; |
| 11 | import { regex_placement, runRegexScript } from './engine.js'; | 11 | import { regex_placement, runRegexScript, substitute_find_regex } from './engine.js'; |
| 12 | import { t } from '../../i18n.js'; | 12 | import { t } from '../../i18n.js'; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| @@ -227,7 +227,7 @@ async function onRegexEditorOpenClick(existingId, isScoped) { | |||
| 227 | editorHtml.find('input[name="only_format_display"]').prop('checked', existingScript.markdownOnly ?? false); | 227 | editorHtml.find('input[name="only_format_display"]').prop('checked', existingScript.markdownOnly ?? false); |
| 228 | editorHtml.find('input[name="only_format_prompt"]').prop('checked', existingScript.promptOnly ?? false); | 228 | editorHtml.find('input[name="only_format_prompt"]').prop('checked', existingScript.promptOnly ?? false); |
| 229 | editorHtml.find('input[name="run_on_edit"]').prop('checked', existingScript.runOnEdit ?? false); | 229 | editorHtml.find('input[name="run_on_edit"]').prop('checked', existingScript.runOnEdit ?? false); |
| 230 | editorHtml.find('input[name="substitute_regex"]').prop('checked', existingScript.substituteRegex ?? false); | 230 | editorHtml.find('select[name="substitute_regex"]').val(existingScript.substituteRegex ?? substitute_find_regex.NONE); |
| 231 | editorHtml.find('input[name="min_depth"]').val(existingScript.minDepth ?? ''); | 231 | editorHtml.find('input[name="min_depth"]').val(existingScript.minDepth ?? ''); |
| 232 | editorHtml.find('input[name="max_depth"]').val(existingScript.maxDepth ?? ''); | 232 | editorHtml.find('input[name="max_depth"]').val(existingScript.maxDepth ?? ''); |
| 233 | 233 | ||
| @@ -267,7 +267,7 @@ async function onRegexEditorOpenClick(existingId, isScoped) { | |||
| 267 | findRegex: editorHtml.find('.find_regex').val(), | 267 | findRegex: editorHtml.find('.find_regex').val(), |
| 268 | replaceString: editorHtml.find('.regex_replace_string').val(), | 268 | replaceString: editorHtml.find('.regex_replace_string').val(), |
| 269 | trimStrings: String(editorHtml.find('.regex_trim_strings').val()).split('\n').filter((e) => e.length !== 0) || [], | 269 | trimStrings: String(editorHtml.find('.regex_trim_strings').val()).split('\n').filter((e) => e.length !== 0) || [], |
| 270 | substituteRegex: editorHtml.find('input[name="substitute_regex"]').prop('checked'), | 270 | substituteRegex: Number(editorHtml.find('select[name="substitute_regex"]').val()), |
| 271 | }; | 271 | }; |
| 272 | const rawTestString = String(editorHtml.find('#regex_test_input').val()); | 272 | const rawTestString = String(editorHtml.find('#regex_test_input').val()); |
| 273 | const result = runRegexScript(testScript, rawTestString); | 273 | const result = runRegexScript(testScript, rawTestString); |
| @@ -295,7 +295,7 @@ async function onRegexEditorOpenClick(existingId, isScoped) { | |||
| 295 | markdownOnly: editorHtml.find('input[name="only_format_display"]').prop('checked'), | 295 | markdownOnly: editorHtml.find('input[name="only_format_display"]').prop('checked'), |
| 296 | promptOnly: editorHtml.find('input[name="only_format_prompt"]').prop('checked'), | 296 | promptOnly: editorHtml.find('input[name="only_format_prompt"]').prop('checked'), |
| 297 | runOnEdit: editorHtml.find('input[name="run_on_edit"]').prop('checked'), | 297 | runOnEdit: editorHtml.find('input[name="run_on_edit"]').prop('checked'), |
| 298 | substituteRegex: editorHtml.find('input[name="substitute_regex"]').prop('checked'), | 298 | substituteRegex: Number(editorHtml.find('select[name="substitute_regex"]').val()), |
| 299 | minDepth: parseInt(String(editorHtml.find('input[name="min_depth"]').val())), | 299 | minDepth: parseInt(String(editorHtml.find('input[name="min_depth"]').val())), |
| 300 | maxDepth: parseInt(String(editorHtml.find('input[name="max_depth"]').val())), | 300 | maxDepth: parseInt(String(editorHtml.find('input[name="max_depth"]').val())), |
| 301 | }; | 301 | }; |
| @@ -1,37 +1,62 @@ | |||
| 1 | import { Popper } from '../../../lib.js'; | 1 | import { Popper } from '../../../lib.js'; |
| 2 | import { | 2 | import { |
| 3 | saveSettingsDebounced, | 3 | animation_duration, |
| 4 | systemUserName, | 4 | appendMediaToMessage, |
| 5 | getRequestHeaders, | ||
| 6 | event_types, | 5 | event_types, |
| 7 | eventSource, | 6 | eventSource, |
| 7 | formatCharacterAvatar, | ||
| 8 | generateQuietPrompt, | 8 | generateQuietPrompt, |
| 9 | this_chid, | 9 | getCharacterAvatar, |
| 10 | getCurrentChatId, | 10 | getCurrentChatId, |
| 11 | animation_duration, | 11 | getRequestHeaders, |
| 12 | appendMediaToMessage, | ||
| 13 | getUserAvatar, | 12 | getUserAvatar, |
| 14 | user_avatar, | 13 | saveSettingsDebounced, |
| 15 | getCharacterAvatar, | ||
| 16 | formatCharacterAvatar, | ||
| 17 | substituteParams, | 14 | substituteParams, |
| 18 | substituteParamsExtended, | 15 | substituteParamsExtended, |
| 16 | systemUserName, | ||
| 17 | this_chid, | ||
| 18 | user_avatar, | ||
| 19 | } from '../../../script.js'; | 19 | } from '../../../script.js'; |
| 20 | import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules, renderExtensionTemplateAsync, writeExtensionField } from '../../extensions.js'; | 20 | import { |
| 21 | doExtrasFetch, | ||
| 22 | extension_settings, | ||
| 23 | getApiUrl, | ||
| 24 | getContext, | ||
| 25 | modules, | ||
| 26 | renderExtensionTemplateAsync, | ||
| 27 | writeExtensionField, | ||
| 28 | } from '../../extensions.js'; | ||
| 21 | import { selected_group } from '../../group-chats.js'; | 29 | import { selected_group } from '../../group-chats.js'; |
| 22 | import { stringFormat, initScrollHeight, resetScrollHeight, getCharaFilename, saveBase64AsFile, getBase64Async, delay, isTrueBoolean, debounce, isFalseBoolean, deepMerge } from '../../utils.js'; | 30 | import { |
| 31 | debounce, | ||
| 32 | deepMerge, | ||
| 33 | delay, | ||
| 34 | getBase64Async, | ||
| 35 | getCharaFilename, | ||
| 36 | initScrollHeight, | ||
| 37 | isFalseBoolean, | ||
| 38 | isTrueBoolean, | ||
| 39 | resetScrollHeight, | ||
| 40 | saveBase64AsFile, | ||
| 41 | stringFormat, | ||
| 42 | } from '../../utils.js'; | ||
| 23 | import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js'; | 43 | import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js'; |
| 24 | import { SECRET_KEYS, secret_state, writeSecret } from '../../secrets.js'; | 44 | import { SECRET_KEYS, secret_state, writeSecret } from '../../secrets.js'; |
| 25 | import { getNovelUnlimitedImageGeneration, getNovelAnlas, loadNovelSubscriptionData } from '../../nai-settings.js'; | 45 | import { getNovelAnlas, getNovelUnlimitedImageGeneration, loadNovelSubscriptionData } from '../../nai-settings.js'; |
| 26 | import { getMultimodalCaption } from '../shared.js'; | 46 | import { getMultimodalCaption } from '../shared.js'; |
| 27 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; | 47 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; |
| 28 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; | 48 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; |
| 29 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; | 49 | import { |
| 50 | ARGUMENT_TYPE, | ||
| 51 | SlashCommandArgument, | ||
| 52 | SlashCommandNamedArgument, | ||
| 53 | } from '../../slash-commands/SlashCommandArgument.js'; | ||
| 30 | import { debounce_timeout } from '../../constants.js'; | 54 | import { debounce_timeout } from '../../constants.js'; |
| 31 | import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; | 55 | import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; |
| 32 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; | 56 | import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; |
| 33 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | 57 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 34 | import { ToolManager } from '../../tool-calling.js'; | 58 | import { ToolManager } from '../../tool-calling.js'; |
| 59 | |||
| 35 | export { MODULE_NAME }; | 60 | export { MODULE_NAME }; |
| 36 | 61 | ||
| 37 | const MODULE_NAME = 'sd'; | 62 | const MODULE_NAME = 'sd'; |
| @@ -118,13 +143,13 @@ const triggerWords = { | |||
| 118 | }; | 143 | }; |
| 119 | 144 | ||
| 120 | const messageTrigger = { | 145 | const messageTrigger = { |
| 121 | activationRegex: /\b(send|mail|imagine|generate|make|create|draw|paint|render|show)\b.{0,10}\b(pic|picture|image|drawing|painting|photo|photograph)\b(?:\s+of)?(?:\s+(?:a|an|the|this|that|those|your)?)?(.+)/i, | 146 | activationRegex: /\b(send|mail|imagine|generate|make|create|draw|paint|render|show)\b.{0,10}\b(pic|picture|image|drawing|painting|photo|photograph)\b(?:\s+of)?(?:\s+(?:a|an|the|this|that|those|your)?\s+)?(.+)/i, |
| 122 | specialCases: { | 147 | specialCases: { |
| 123 | [generationMode.CHARACTER]: ['you', 'yourself'], | 148 | [generationMode.CHARACTER]: ['you', 'yourself'], |
| 124 | [generationMode.USER]: ['me', 'myself'], | 149 | [generationMode.USER]: ['me', 'myself'], |
| 125 | [generationMode.SCENARIO]: ['story', 'scenario', 'whole story'], | 150 | [generationMode.SCENARIO]: ['story', 'scenario', 'whole story'], |
| 126 | [generationMode.NOW]: ['last message'], | 151 | [generationMode.NOW]: ['last message'], |
| 127 | [generationMode.FACE]: ['your face', 'your portrait', 'your selfie'], | 152 | [generationMode.FACE]: ['face', 'portrait', 'selfie'], |
| 128 | [generationMode.BACKGROUND]: ['background', 'scene background', 'scene', 'scenery', 'surroundings', 'environment'], | 153 | [generationMode.BACKGROUND]: ['background', 'scene background', 'scene', 'scenery', 'surroundings', 'environment'], |
| 129 | }, | 154 | }, |
| 130 | }; | 155 | }; |
| @@ -343,7 +368,7 @@ function processTriggers(chat, _, abort) { | |||
| 343 | return; | 368 | return; |
| 344 | } | 369 | } |
| 345 | 370 | ||
| 346 | console.log(`SD: Triggered by "${message}", detected subject: ${subject}"`); | 371 | console.log(`SD: Triggered by "${message}", detected subject: "${subject}"`); |
| 347 | 372 | ||
| 348 | outer: for (const [specialMode, triggers] of Object.entries(messageTrigger.specialCases)) { | 373 | outer: for (const [specialMode, triggers] of Object.entries(messageTrigger.specialCases)) { |
| 349 | for (const trigger of triggers) { | 374 | for (const trigger of triggers) { |
| @@ -359,7 +384,6 @@ function processTriggers(chat, _, abort) { | |||
| 359 | setTimeout(() => generatePicture(initiators.interactive, {}, subject, message), 1); | 384 | setTimeout(() => generatePicture(initiators.interactive, {}, subject, message), 1); |
| 360 | } catch { | 385 | } catch { |
| 361 | console.log('SD: Failed to process triggers.'); | 386 | console.log('SD: Failed to process triggers.'); |
| 362 | return; | ||
| 363 | } | 387 | } |
| 364 | } | 388 | } |
| 365 | 389 | ||
| @@ -685,7 +709,7 @@ async function refinePrompt(prompt, isNegative) { | |||
| 685 | return prompt; | 709 | return prompt; |
| 686 | } | 710 | } |
| 687 | 711 | ||
| 688 | function onChatChanged() { | 712 | async function onChatChanged() { |
| 689 | if (this_chid === undefined || selected_group) { | 713 | if (this_chid === undefined || selected_group) { |
| 690 | $('#sd_character_prompt_block').hide(); | 714 | $('#sd_character_prompt_block').hide(); |
| 691 | return; | 715 | return; |
| @@ -713,7 +737,7 @@ function onChatChanged() { | |||
| 713 | $('#sd_character_prompt').val(characterPrompt); | 737 | $('#sd_character_prompt').val(characterPrompt); |
| 714 | $('#sd_character_negative_prompt').val(negativePrompt); | 738 | $('#sd_character_negative_prompt').val(negativePrompt); |
| 715 | $('#sd_character_prompt_share').prop('checked', hasSharedData); | 739 | $('#sd_character_prompt_share').prop('checked', hasSharedData); |
| 716 | adjustElementScrollHeight(); | 740 | await adjustElementScrollHeight(); |
| 717 | } | 741 | } |
| 718 | 742 | ||
| 719 | async function adjustElementScrollHeight() { | 743 | async function adjustElementScrollHeight() { |
| @@ -1285,8 +1309,7 @@ async function getAutoRemoteModel() { | |||
| 1285 | throw new Error('SD WebUI returned an error.'); | 1309 | throw new Error('SD WebUI returned an error.'); |
| 1286 | } | 1310 | } |
| 1287 | 1311 | ||
| 1288 | const data = await result.text(); | 1312 | return await result.text(); |
| 1289 | return data; | ||
| 1290 | } catch (error) { | 1313 | } catch (error) { |
| 1291 | console.error(error); | 1314 | console.error(error); |
| 1292 | return null; | 1315 | return null; |
| @@ -1305,9 +1328,7 @@ async function getDrawthingsRemoteModel() { | |||
| 1305 | throw new Error('SD DrawThings API returned an error.'); | 1328 | throw new Error('SD DrawThings API returned an error.'); |
| 1306 | } | 1329 | } |
| 1307 | 1330 | ||
| 1308 | const data = await result.text(); | 1331 | return await result.text(); |
| 1309 | |||
| 1310 | return data; | ||
| 1311 | } catch (error) { | 1332 | } catch (error) { |
| 1312 | console.error(error); | 1333 | console.error(error); |
| 1313 | return null; | 1334 | return null; |
| @@ -1330,8 +1351,7 @@ async function getAutoRemoteUpscalers() { | |||
| 1330 | throw new Error('SD WebUI returned an error.'); | 1351 | throw new Error('SD WebUI returned an error.'); |
| 1331 | } | 1352 | } |
| 1332 | 1353 | ||
| 1333 | const data = await result.json(); | 1354 | return await result.json(); |
| 1334 | return data; | ||
| 1335 | } catch (error) { | 1355 | } catch (error) { |
| 1336 | console.error(error); | 1356 | console.error(error); |
| 1337 | return [extension_settings.sd.hr_upscaler]; | 1357 | return [extension_settings.sd.hr_upscaler]; |
| @@ -1350,8 +1370,7 @@ async function getAutoRemoteSchedulers() { | |||
| 1350 | throw new Error('SD WebUI returned an error.'); | 1370 | throw new Error('SD WebUI returned an error.'); |
| 1351 | } | 1371 | } |
| 1352 | 1372 | ||
| 1353 | const data = await result.json(); | 1373 | return await result.json(); |
| 1354 | return data; | ||
| 1355 | } catch (error) { | 1374 | } catch (error) { |
| 1356 | console.error(error); | 1375 | console.error(error); |
| 1357 | return ['N/A']; | 1376 | return ['N/A']; |
| @@ -1370,8 +1389,7 @@ async function getVladRemoteUpscalers() { | |||
| 1370 | throw new Error('SD.Next returned an error.'); | 1389 | throw new Error('SD.Next returned an error.'); |
| 1371 | } | 1390 | } |
| 1372 | 1391 | ||
| 1373 | const data = await result.json(); | 1392 | return await result.json(); |
| 1374 | return data; | ||
| 1375 | } catch (error) { | 1393 | } catch (error) { |
| 1376 | console.error(error); | 1394 | console.error(error); |
| 1377 | return [extension_settings.sd.hr_upscaler]; | 1395 | return [extension_settings.sd.hr_upscaler]; |
| @@ -1504,8 +1522,7 @@ async function loadHordeSamplers() { | |||
| 1504 | }); | 1522 | }); |
| 1505 | 1523 | ||
| 1506 | if (result.ok) { | 1524 | if (result.ok) { |
| 1507 | const data = await result.json(); | 1525 | return await result.json(); |
| 1508 | return data; | ||
| 1509 | } | 1526 | } |
| 1510 | 1527 | ||
| 1511 | return []; | 1528 | return []; |
| @@ -1544,8 +1561,7 @@ async function loadAutoSamplers() { | |||
| 1544 | throw new Error('SD WebUI returned an error.'); | 1561 | throw new Error('SD WebUI returned an error.'); |
| 1545 | } | 1562 | } |
| 1546 | 1563 | ||
| 1547 | const data = await result.json(); | 1564 | return await result.json(); |
| 1548 | return data; | ||
| 1549 | } catch (error) { | 1565 | } catch (error) { |
| 1550 | return []; | 1566 | return []; |
| 1551 | } | 1567 | } |
| @@ -1583,8 +1599,7 @@ async function loadVladSamplers() { | |||
| 1583 | throw new Error('SD.Next returned an error.'); | 1599 | throw new Error('SD.Next returned an error.'); |
| 1584 | } | 1600 | } |
| 1585 | 1601 | ||
| 1586 | const data = await result.json(); | 1602 | return await result.json(); |
| 1587 | return data; | ||
| 1588 | } catch (error) { | 1603 | } catch (error) { |
| 1589 | return []; | 1604 | return []; |
| 1590 | } | 1605 | } |
| @@ -1723,8 +1738,7 @@ async function loadPollinationsModels() { | |||
| 1723 | }); | 1738 | }); |
| 1724 | 1739 | ||
| 1725 | if (result.ok) { | 1740 | if (result.ok) { |
| 1726 | const data = await result.json(); | 1741 | return await result.json(); |
| 1727 | return data; | ||
| 1728 | } | 1742 | } |
| 1729 | 1743 | ||
| 1730 | return []; | 1744 | return []; |
| @@ -1742,8 +1756,7 @@ async function loadTogetherAIModels() { | |||
| 1742 | }); | 1756 | }); |
| 1743 | 1757 | ||
| 1744 | if (result.ok) { | 1758 | if (result.ok) { |
| 1745 | const data = await result.json(); | 1759 | return await result.json(); |
| 1746 | return data; | ||
| 1747 | } | 1760 | } |
| 1748 | 1761 | ||
| 1749 | return []; | 1762 | return []; |
| @@ -1781,8 +1794,7 @@ async function loadNanoGPTModels() { | |||
| 1781 | }); | 1794 | }); |
| 1782 | 1795 | ||
| 1783 | if (result.ok) { | 1796 | if (result.ok) { |
| 1784 | const data = await result.json(); | 1797 | return await result.json(); |
| 1785 | return data; | ||
| 1786 | } | 1798 | } |
| 1787 | 1799 | ||
| 1788 | return []; | 1800 | return []; |
| @@ -1798,8 +1810,10 @@ async function loadHordeModels() { | |||
| 1798 | if (result.ok) { | 1810 | if (result.ok) { |
| 1799 | const data = await result.json(); | 1811 | const data = await result.json(); |
| 1800 | data.sort((a, b) => b.count - a.count); | 1812 | data.sort((a, b) => b.count - a.count); |
| 1801 | const models = data.map(x => ({ value: x.name, text: `${x.name} (ETA: ${x.eta}s, Queue: ${x.queued}, Workers: ${x.count})` })); | 1813 | return data.map(x => ({ |
| 1802 | return models; | 1814 | value: x.name, |
| 1815 | text: `${x.name} (ETA: ${x.eta}s, Queue: ${x.queued}, Workers: ${x.count})`, | ||
| 1816 | })); | ||
| 1803 | } | 1817 | } |
| 1804 | 1818 | ||
| 1805 | return []; | 1819 | return []; |
| @@ -1824,8 +1838,7 @@ async function loadExtrasModels() { | |||
| 1824 | 1838 | ||
| 1825 | if (getModelsResult.ok) { | 1839 | if (getModelsResult.ok) { |
| 1826 | const data = await getModelsResult.json(); | 1840 | const data = await getModelsResult.json(); |
| 1827 | const view_models = data.models.map(x => ({ value: x, text: x })); | 1841 | return data.models.map(x => ({ value: x, text: x })); |
| 1828 | return view_models; | ||
| 1829 | } | 1842 | } |
| 1830 | 1843 | ||
| 1831 | return []; | 1844 | return []; |
| @@ -1867,8 +1880,7 @@ async function loadAutoModels() { | |||
| 1867 | } | 1880 | } |
| 1868 | } | 1881 | } |
| 1869 | 1882 | ||
| 1870 | const data = await result.json(); | 1883 | return await result.json(); |
| 1871 | return data; | ||
| 1872 | } catch (error) { | 1884 | } catch (error) { |
| 1873 | return []; | 1885 | return []; |
| 1874 | } | 1886 | } |
| @@ -1953,8 +1965,7 @@ async function loadVladModels() { | |||
| 1953 | } | 1965 | } |
| 1954 | } | 1966 | } |
| 1955 | 1967 | ||
| 1956 | const data = await result.json(); | 1968 | return await result.json(); |
| 1957 | return data; | ||
| 1958 | } catch (error) { | 1969 | } catch (error) { |
| 1959 | return []; | 1970 | return []; |
| 1960 | } | 1971 | } |
| @@ -2242,7 +2253,7 @@ async function loadComfyWorkflows() { | |||
| 2242 | $('#sd_comfy_workflow').append(option); | 2253 | $('#sd_comfy_workflow').append(option); |
| 2243 | } | 2254 | } |
| 2244 | } catch (error) { | 2255 | } catch (error) { |
| 2245 | return; | 2256 | console.error(`Could not load ComfyUI workflows: ${error.message}`); |
| 2246 | } | 2257 | } |
| 2247 | } | 2258 | } |
| 2248 | 2259 | ||
| @@ -2361,7 +2372,8 @@ function ensureSelectionExists(setting, selector) { | |||
| 2361 | * @param {string} trigger Subject trigger word | 2372 | * @param {string} trigger Subject trigger word |
| 2362 | * @param {string} [message] Chat message | 2373 | * @param {string} [message] Chat message |
| 2363 | * @param {function} [callback] Callback function | 2374 | * @param {function} [callback] Callback function |
| 2364 | * @returns {Promise<string>} Image path | 2375 | * @returns {Promise<string|undefined>} Image path |
| 2376 | * @throws {Error} If the prompt or image generation fails | ||
| 2365 | */ | 2377 | */ |
| 2366 | async function generatePicture(initiator, args, trigger, message, callback) { | 2378 | async function generatePicture(initiator, args, trigger, message, callback) { |
| 2367 | if (!trigger || trigger.trim().length === 0) { | 2379 | if (!trigger || trigger.trim().length === 0) { |
| @@ -2379,7 +2391,9 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2379 | 2391 | ||
| 2380 | trigger = trigger.trim(); | 2392 | trigger = trigger.trim(); |
| 2381 | const generationType = getGenerationType(trigger); | 2393 | const generationType = getGenerationType(trigger); |
| 2382 | console.log('Generation mode', generationType, 'triggered with', trigger); | 2394 | const generationTypeKey = Object.keys(generationMode).find(key => generationMode[key] === generationType); |
| 2395 | console.log(`Image generation mode ${generationTypeKey} triggered with "${trigger}"`); | ||
| 2396 | |||
| 2383 | const quietPrompt = getQuietPrompt(generationType, trigger); | 2397 | const quietPrompt = getQuietPrompt(generationType, trigger); |
| 2384 | const context = getContext(); | 2398 | const context = getContext(); |
| 2385 | 2399 | ||
| @@ -2387,11 +2401,11 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2387 | ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString() | 2401 | ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString() |
| 2388 | : context.characters[context.characterId]?.name; | 2402 | : context.characters[context.characterId]?.name; |
| 2389 | 2403 | ||
| 2390 | if (generationType == generationMode.BACKGROUND) { | 2404 | if (generationType === generationMode.BACKGROUND) { |
| 2391 | const callbackOriginal = callback; | 2405 | const callbackOriginal = callback; |
| 2392 | callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) { | 2406 | callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) { |
| 2393 | const imgUrl = `url("${encodeURI(imagePath)}")`; | 2407 | const imgUrl = `url("${encodeURI(imagePath)}")`; |
| 2394 | eventSource.emit(event_types.FORCE_SET_BACKGROUND, { url: imgUrl, path: imagePath }); | 2408 | await eventSource.emit(event_types.FORCE_SET_BACKGROUND, { url: imgUrl, path: imagePath }); |
| 2395 | 2409 | ||
| 2396 | if (typeof callbackOriginal === 'function') { | 2410 | if (typeof callbackOriginal === 'function') { |
| 2397 | await callbackOriginal(prompt, imagePath, generationType, negativePromptPrefix, initiator, prefixedPrompt); | 2411 | await callbackOriginal(prompt, imagePath, generationType, negativePromptPrefix, initiator, prefixedPrompt); |
| @@ -2415,6 +2429,8 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2415 | 2429 | ||
| 2416 | try { | 2430 | try { |
| 2417 | const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); }; | 2431 | const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); }; |
| 2432 | |||
| 2433 | // generate the text prompt for the image | ||
| 2418 | const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives); | 2434 | const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives); |
| 2419 | console.log('Processed image prompt:', prompt); | 2435 | console.log('Processed image prompt:', prompt); |
| 2420 | 2436 | ||
| @@ -2425,11 +2441,16 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2425 | args._abortController.addEventListener('abort', stopListener); | 2441 | args._abortController.addEventListener('abort', stopListener); |
| 2426 | } | 2442 | } |
| 2427 | 2443 | ||
| 2444 | // generate the image | ||
| 2428 | imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal); | 2445 | imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal); |
| 2429 | } catch (err) { | 2446 | } catch (err) { |
| 2430 | console.trace(err); | 2447 | console.trace(err); |
| 2431 | toastr.error('SD prompt text generation failed. Reason: ' + err, 'Image Generation'); | 2448 | // errors here are most likely due to text generation failure |
| 2432 | throw new Error('SD prompt text generation failed. Reason: ' + err); | 2449 | // sendGenerationRequest mostly deals with its own errors |
| 2450 | const reason = err.error?.message || err.message || 'Unknown error'; | ||
| 2451 | const errorText = 'SD prompt text generation failed. ' + reason; | ||
| 2452 | toastr.error(errorText, 'Image Generation'); | ||
| 2453 | throw new Error(errorText); | ||
| 2433 | } | 2454 | } |
| 2434 | finally { | 2455 | finally { |
| 2435 | $(stopButton).hide(); | 2456 | $(stopButton).hide(); |
| @@ -2446,12 +2467,12 @@ function setTypeSpecificDimensions(generationType) { | |||
| 2446 | const aspectRatio = extension_settings.sd.width / extension_settings.sd.height; | 2467 | const aspectRatio = extension_settings.sd.width / extension_settings.sd.height; |
| 2447 | 2468 | ||
| 2448 | // Face images are always portrait (pun intended) | 2469 | // Face images are always portrait (pun intended) |
| 2449 | if ((generationType == generationMode.FACE || generationType == generationMode.FACE_MULTIMODAL) && aspectRatio >= 1) { | 2470 | if ((generationType === generationMode.FACE || generationType === generationMode.FACE_MULTIMODAL) && aspectRatio >= 1) { |
| 2450 | // Round to nearest multiple of 64 | 2471 | // Round to nearest multiple of 64 |
| 2451 | extension_settings.sd.height = Math.round(extension_settings.sd.width * 1.5 / 64) * 64; | 2472 | extension_settings.sd.height = Math.round(extension_settings.sd.width * 1.5 / 64) * 64; |
| 2452 | } | 2473 | } |
| 2453 | 2474 | ||
| 2454 | if (generationType == generationMode.BACKGROUND) { | 2475 | if (generationType === generationMode.BACKGROUND) { |
| 2455 | // Background images are always landscape | 2476 | // Background images are always landscape |
| 2456 | if (aspectRatio <= 1) { | 2477 | if (aspectRatio <= 1) { |
| 2457 | // Round to nearest multiple of 64 | 2478 | // Round to nearest multiple of 64 |
| @@ -2500,7 +2521,7 @@ function restoreOriginalDimensions(savedParams) { | |||
| 2500 | */ | 2521 | */ |
| 2501 | async function getPrompt(generationType, message, trigger, quietPrompt, combineNegatives) { | 2522 | async function getPrompt(generationType, message, trigger, quietPrompt, combineNegatives) { |
| 2502 | let prompt; | 2523 | let prompt; |
| 2503 | 2524 | console.log('getPrompt: Generation mode', generationType, 'triggered with', trigger); | |
| 2504 | switch (generationType) { | 2525 | switch (generationType) { |
| 2505 | case generationMode.RAW_LAST: | 2526 | case generationMode.RAW_LAST: |
| 2506 | prompt = message || getRawLastMessage(); | 2527 | prompt = message || getRawLastMessage(); |
| @@ -2537,7 +2558,7 @@ async function getPrompt(generationType, message, trigger, quietPrompt, combineN | |||
| 2537 | */ | 2558 | */ |
| 2538 | function generateFreeModePrompt(trigger, combineNegatives) { | 2559 | function generateFreeModePrompt(trigger, combineNegatives) { |
| 2539 | return trigger | 2560 | return trigger |
| 2540 | .replace(/(?:^char(\s|,)|\{\{charPrefix\}\})/gi, (_, suffix) => { | 2561 | .replace(/^char(\s|,)|{{charPrefix}}/gi, (_, suffix) => { |
| 2541 | const getLastCharacterKey = () => { | 2562 | const getLastCharacterKey = () => { |
| 2542 | if (typeof this_chid !== 'undefined') { | 2563 | if (typeof this_chid !== 'undefined') { |
| 2543 | return getCharaFilename(this_chid); | 2564 | return getCharaFilename(this_chid); |
| @@ -2545,9 +2566,7 @@ function generateFreeModePrompt(trigger, combineNegatives) { | |||
| 2545 | const context = getContext(); | 2566 | const context = getContext(); |
| 2546 | for (let i = context.chat.length - 1; i >= 0; i--) { | 2567 | for (let i = context.chat.length - 1; i >= 0; i--) { |
| 2547 | const message = context.chat[i]; | 2568 | const message = context.chat[i]; |
| 2548 | if (message.is_user || message.is_system) { | 2569 | if (!message.is_user && !message.is_system && typeof message.original_avatar === 'string') { |
| 2549 | continue; | ||
| 2550 | } else if (typeof message.original_avatar === 'string') { | ||
| 2551 | return message.original_avatar.replace(/\.[^/.]+$/, ''); | 2570 | return message.original_avatar.replace(/\.[^/.]+$/, ''); |
| 2552 | } | 2571 | } |
| 2553 | } | 2572 | } |
| @@ -2570,11 +2589,11 @@ function generateFreeModePrompt(trigger, combineNegatives) { | |||
| 2570 | async function generateMultimodalPrompt(generationType, quietPrompt) { | 2589 | async function generateMultimodalPrompt(generationType, quietPrompt) { |
| 2571 | let avatarUrl; | 2590 | let avatarUrl; |
| 2572 | 2591 | ||
| 2573 | if (generationType == generationMode.USER_MULTIMODAL) { | 2592 | if (generationType === generationMode.USER_MULTIMODAL) { |
| 2574 | avatarUrl = getUserAvatarUrl(); | 2593 | avatarUrl = getUserAvatarUrl(); |
| 2575 | } | 2594 | } |
| 2576 | 2595 | ||
| 2577 | if (generationType == generationMode.CHARACTER_MULTIMODAL || generationType === generationMode.FACE_MULTIMODAL) { | 2596 | if (generationType === generationMode.CHARACTER_MULTIMODAL || generationType === generationMode.FACE_MULTIMODAL) { |
| 2578 | avatarUrl = getCharacterAvatarUrl(); | 2597 | avatarUrl = getCharacterAvatarUrl(); |
| 2579 | } | 2598 | } |
| 2580 | 2599 | ||
| @@ -2718,7 +2737,7 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | |||
| 2718 | throw new Error('Endpoint did not return image data.'); | 2737 | throw new Error('Endpoint did not return image data.'); |
| 2719 | } | 2738 | } |
| 2720 | } catch (err) { | 2739 | } catch (err) { |
| 2721 | console.error(err); | 2740 | console.error('Image generation request error: ', err); |
| 2722 | toastr.error('Image generation failed. Please try again.' + '\n\n' + String(err), 'Image Generation'); | 2741 | toastr.error('Image generation failed. Please try again.' + '\n\n' + String(err), 'Image Generation'); |
| 2723 | return; | 2742 | return; |
| 2724 | } | 2743 | } |
| @@ -3182,8 +3201,8 @@ function getNovelParams() { | |||
| 3182 | const ratio = Math.sqrt(MAX_PIXELS / (width * height)); | 3201 | const ratio = Math.sqrt(MAX_PIXELS / (width * height)); |
| 3183 | 3202 | ||
| 3184 | // Calculate new width and height while maintaining aspect ratio. | 3203 | // Calculate new width and height while maintaining aspect ratio. |
| 3185 | var newWidth = Math.round(width * ratio); | 3204 | let newWidth = Math.round(width * ratio); |
| 3186 | var newHeight = Math.round(height * ratio); | 3205 | let newHeight = Math.round(height * ratio); |
| 3187 | 3206 | ||
| 3188 | // Ensure new dimensions are multiples of 64. If not, reduce accordingly. | 3207 | // Ensure new dimensions are multiples of 64. If not, reduce accordingly. |
| 3189 | if (newWidth % 64 !== 0) { | 3208 | if (newWidth % 64 !== 0) { |
| @@ -3479,9 +3498,9 @@ async function onComfyOpenWorkflowEditorClick() { | |||
| 3479 | const popupResult = popup.show(); | 3498 | const popupResult = popup.show(); |
| 3480 | const checkPlaceholders = () => { | 3499 | const checkPlaceholders = () => { |
| 3481 | workflow = $('#sd_comfy_workflow_editor_workflow').val().toString(); | 3500 | workflow = $('#sd_comfy_workflow_editor_workflow').val().toString(); |
| 3482 | $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function (idx) { | 3501 | $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function () { |
| 3483 | const key = this.getAttribute('data-placeholder'); | 3502 | const key = this.getAttribute('data-placeholder'); |
| 3484 | const found = workflow.search(`"%${key}%"`) != -1; | 3503 | const found = workflow.search(`"%${key}%"`) !== -1; |
| 3485 | this.classList[found ? 'remove' : 'add']('sd_comfy_workflow_editor_not_found'); | 3504 | this.classList[found ? 'remove' : 'add']('sd_comfy_workflow_editor_not_found'); |
| 3486 | }); | 3505 | }); |
| 3487 | }; | 3506 | }; |
| @@ -3841,7 +3860,7 @@ async function sdMessageButton(e) { | |||
| 3841 | swipes.push(image); | 3860 | swipes.push(image); |
| 3842 | 3861 | ||
| 3843 | // If already contains an image and it's not inline - leave it as is | 3862 | // If already contains an image and it's not inline - leave it as is |
| 3844 | message.extra.inline_image = message.extra.image && !message.extra.inline_image ? false : true; | 3863 | message.extra.inline_image = !(message.extra.image && !message.extra.inline_image); |
| 3845 | message.extra.image = image; | 3864 | message.extra.image = image; |
| 3846 | message.extra.title = prompt; | 3865 | message.extra.title = prompt; |
| 3847 | message.extra.generationType = generationType; | 3866 | message.extra.generationType = generationType; |
| @@ -7,7 +7,7 @@ | |||
| 7 | <div class="inline-drawer-content"> | 7 | <div class="inline-drawer-content"> |
| 8 | <div id="tts_status"> | 8 | <div id="tts_status"> |
| 9 | </div> | 9 | </div> |
| 10 | <span>Select TTS Provider</span> </br> | 10 | <span data-i18n="Select TTS Provider">Select TTS Provider</span> </br> |
| 11 | <div class="tts_block"> | 11 | <div class="tts_block"> |
| 12 | <select id="tts_provider" class="flex1"> | 12 | <select id="tts_provider" class="flex1"> |
| 13 | </select> | 13 | </select> |
| @@ -16,49 +16,49 @@ | |||
| 16 | <div> | 16 | <div> |
| 17 | <label class="checkbox_label" for="tts_enabled"> | 17 | <label class="checkbox_label" for="tts_enabled"> |
| 18 | <input type="checkbox" id="tts_enabled" name="tts_enabled"> | 18 | <input type="checkbox" id="tts_enabled" name="tts_enabled"> |
| 19 | <small>Enabled</small> | 19 | <small data-i18n="tts_enabled">Enabled</small> |
| 20 | </label> | 20 | </label> |
| 21 | <label class="checkbox_label" for="tts_narrate_user"> | 21 | <label class="checkbox_label" for="tts_narrate_user"> |
| 22 | <input type="checkbox" id="tts_narrate_user"> | 22 | <input type="checkbox" id="tts_narrate_user"> |
| 23 | <small>Narrate user messages</small> | 23 | <small data-i18n="Narrate user messages">Narrate user messages</small> |
| 24 | </label> | 24 | </label> |
| 25 | <label class="checkbox_label" for="tts_auto_generation"> | 25 | <label class="checkbox_label" for="tts_auto_generation"> |
| 26 | <input type="checkbox" id="tts_auto_generation"> | 26 | <input type="checkbox" id="tts_auto_generation"> |
| 27 | <small>Auto Generation</small> | 27 | <small data-i18n="Auto Generation">Auto Generation</small> |
| 28 | </label> | 28 | </label> |
| 29 | <label class="checkbox_label" for="tts_periodic_auto_generation" title="Requires auto generation to be enabled."> | 29 | <label class="checkbox_label" for="tts_periodic_auto_generation" data-i18n="[title]Requires auto generation to be enabled." title="Requires auto generation to be enabled."> |
| 30 | <input type="checkbox" id="tts_periodic_auto_generation"> | 30 | <input type="checkbox" id="tts_periodic_auto_generation"> |
| 31 | <small>Narrate by paragraphs (when streaming)</small> | 31 | <small data-i18n="Narrate by paragraphs (when streaming)">Narrate by paragraphs (when streaming)</small> |
| 32 | </label> | 32 | </label> |
| 33 | <label class="checkbox_label" for="tts_narrate_quoted"> | 33 | <label class="checkbox_label" for="tts_narrate_quoted"> |
| 34 | <input type="checkbox" id="tts_narrate_quoted"> | 34 | <input type="checkbox" id="tts_narrate_quoted"> |
| 35 | <small>Only narrate "quotes"</small> | 35 | <small data-i18n="Only narrate quotes">Only narrate "quotes"</small> |
| 36 | </label> | 36 | </label> |
| 37 | <label class="checkbox_label" for="tts_narrate_dialogues"> | 37 | <label class="checkbox_label" for="tts_narrate_dialogues"> |
| 38 | <input type="checkbox" id="tts_narrate_dialogues"> | 38 | <input type="checkbox" id="tts_narrate_dialogues"> |
| 39 | <small>Ignore *text, even "quotes", inside asterisks*</small> | 39 | <small data-i18n="Ignore text, even quotes, inside asterisk">Ignore *text, even "quotes", inside asterisks*</small> |
| 40 | </label> | 40 | </label> |
| 41 | <label class="checkbox_label" for="tts_narrate_translated_only"> | 41 | <label class="checkbox_label" for="tts_narrate_translated_only"> |
| 42 | <input type="checkbox" id="tts_narrate_translated_only"> | 42 | <input type="checkbox" id="tts_narrate_translated_only"> |
| 43 | <small>Narrate only the translated text</small> | 43 | <small data-i18n="Narrate only the translated text">Narrate only the translated text</small> |
| 44 | </label> | 44 | </label> |
| 45 | <label class="checkbox_label" for="tts_skip_codeblocks"> | 45 | <label class="checkbox_label" for="tts_skip_codeblocks"> |
| 46 | <input type="checkbox" id="tts_skip_codeblocks"> | 46 | <input type="checkbox" id="tts_skip_codeblocks"> |
| 47 | <small>Skip codeblocks</small> | 47 | <small data-i18n="Skip codeblocks">Skip codeblocks</small> |
| 48 | </label> | 48 | </label> |
| 49 | <label class="checkbox_label" for="tts_skip_tags"> | 49 | <label class="checkbox_label" for="tts_skip_tags"> |
| 50 | <input type="checkbox" id="tts_skip_tags"> | 50 | <input type="checkbox" id="tts_skip_tags"> |
| 51 | <small>Skip <tagged> blocks</small> | 51 | <small data-i18n="Skip tagged blocks">Skip <tagged> blocks</small> |
| 52 | </label> | 52 | </label> |
| 53 | <label class="checkbox_label" for="tts_pass_asterisks"> | 53 | <label class="checkbox_label" for="tts_pass_asterisks"> |
| 54 | <input type="checkbox" id="tts_pass_asterisks"> | 54 | <input type="checkbox" id="tts_pass_asterisks"> |
| 55 | <small>Pass Asterisks to TTS Engine</small> | 55 | <small data-i18n="Pass Asterisks to TTS Engine">Pass Asterisks to TTS Engine</small> |
| 56 | </label> | 56 | </label> |
| 57 | </div> | 57 | </div> |
| 58 | <div id="playback_rate_block" class="range-block"> | 58 | <div id="playback_rate_block" class="range-block"> |
| 59 | <hr> | 59 | <hr> |
| 60 | <div class="range-block-title justifyLeft" data-i18n="Audio Playback Speed"> | 60 | <div class="range-block-title justifyLeft" data-i18n="Audio Playback Speed"> |
| 61 | <small>Audio Playback Speed</small> | 61 | <small data-i18n="Audio Playback Speed">Audio Playback Speed</small> |
| 62 | </div> | 62 | </div> |
| 63 | <div class="range-block-range-and-counter"> | 63 | <div class="range-block-range-and-counter"> |
| 64 | <div class="range-block-range"> | 64 | <div class="range-block-range"> |
| @@ -181,6 +181,14 @@ function setContextSizePreview() { | |||
| 181 | } | 181 | } |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | /** Generates text using the Horde API. | ||
| 185 | * @param {string} prompt | ||
| 186 | * @param params | ||
| 187 | * @param signal | ||
| 188 | * @param reportProgress | ||
| 189 | * @returns {Promise<{text: *, workerName: string}>} | ||
| 190 | * @throws {Error} | ||
| 191 | */ | ||
| 184 | async function generateHorde(prompt, params, signal, reportProgress) { | 192 | async function generateHorde(prompt, params, signal, reportProgress) { |
| 185 | validateHordeModel(); | 193 | validateHordeModel(); |
| 186 | delete params.prompt; | 194 | delete params.prompt; |
| @@ -39,6 +39,7 @@ const controls = [ | |||
| 39 | { id: 'instruct_first_input_sequence', property: 'first_input_sequence', isCheckbox: false }, | 39 | { id: 'instruct_first_input_sequence', property: 'first_input_sequence', isCheckbox: false }, |
| 40 | { id: 'instruct_last_input_sequence', property: 'last_input_sequence', isCheckbox: false }, | 40 | { id: 'instruct_last_input_sequence', property: 'last_input_sequence', isCheckbox: false }, |
| 41 | { id: 'instruct_activation_regex', property: 'activation_regex', isCheckbox: false }, | 41 | { id: 'instruct_activation_regex', property: 'activation_regex', isCheckbox: false }, |
| 42 | { id: 'instruct_derived', property: 'derived', isCheckbox: true }, | ||
| 42 | { id: 'instruct_bind_to_context', property: 'bind_to_context', isCheckbox: true }, | 43 | { id: 'instruct_bind_to_context', property: 'bind_to_context', isCheckbox: true }, |
| 43 | { id: 'instruct_skip_examples', property: 'skip_examples', isCheckbox: true }, | 44 | { id: 'instruct_skip_examples', property: 'skip_examples', isCheckbox: true }, |
| 44 | { id: 'instruct_names_behavior', property: 'names_behavior', isCheckbox: false }, | 45 | { id: 'instruct_names_behavior', property: 'names_behavior', isCheckbox: false }, |
| @@ -100,6 +101,7 @@ export async function loadInstructMode(data) { | |||
| 100 | 101 | ||
| 101 | $('#instruct_enabled').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.enabled); | 102 | $('#instruct_enabled').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.enabled); |
| 102 | $('#instructSettingsBlock, #InstructSequencesColumn').toggleClass('disabled', !power_user.instruct.enabled); | 103 | $('#instructSettingsBlock, #InstructSequencesColumn').toggleClass('disabled', !power_user.instruct.enabled); |
| 104 | $('#instruct_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.derived); | ||
| 103 | $('#instruct_bind_to_context').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.bind_to_context); | 105 | $('#instruct_bind_to_context').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.bind_to_context); |
| 104 | 106 | ||
| 105 | controls.forEach(control => { | 107 | controls.forEach(control => { |
| @@ -146,6 +148,12 @@ export async function loadInstructMode(data) { | |||
| 146 | * @param {boolean} [options.isAuto=false] Is auto-select. | 148 | * @param {boolean} [options.isAuto=false] Is auto-select. |
| 147 | */ | 149 | */ |
| 148 | export function selectContextPreset(preset, { quiet = false, isAuto = false } = {}) { | 150 | export function selectContextPreset(preset, { quiet = false, isAuto = false } = {}) { |
| 151 | const presetExists = context_presets.some(x => x.name === preset); | ||
| 152 | if (!presetExists) { | ||
| 153 | console.warn(`Context template "${preset}" not found`); | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | |||
| 149 | // If context template is not already selected, select it | 157 | // If context template is not already selected, select it |
| 150 | if (preset !== power_user.context.preset) { | 158 | if (preset !== power_user.context.preset) { |
| 151 | $('#context_presets').val(preset).trigger('change'); | 159 | $('#context_presets').val(preset).trigger('change'); |
| @@ -163,6 +171,12 @@ export function selectContextPreset(preset, { quiet = false, isAuto = false } = | |||
| 163 | * @param {boolean} [options.isAuto=false] Is auto-select. | 171 | * @param {boolean} [options.isAuto=false] Is auto-select. |
| 164 | */ | 172 | */ |
| 165 | export function selectInstructPreset(preset, { quiet = false, isAuto = false } = {}) { | 173 | export function selectInstructPreset(preset, { quiet = false, isAuto = false } = {}) { |
| 174 | const presetExists = instruct_presets.some(x => x.name === preset); | ||
| 175 | if (!presetExists) { | ||
| 176 | console.warn(`Instruct template "${preset}" not found`); | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | |||
| 166 | // If instruct preset is not already selected, select it | 180 | // If instruct preset is not already selected, select it |
| 167 | if (preset !== power_user.instruct.preset) { | 181 | if (preset !== power_user.instruct.preset) { |
| 168 | $('#instruct_presets').val(preset).trigger('change'); | 182 | $('#instruct_presets').val(preset).trigger('change'); |
| @@ -715,6 +729,10 @@ jQuery(() => { | |||
| 715 | } | 729 | } |
| 716 | }); | 730 | }); |
| 717 | 731 | ||
| 732 | $('#instruct_derived').on('change', function () { | ||
| 733 | $('#instruct_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.derived); | ||
| 734 | }); | ||
| 735 | |||
| 718 | $('#instruct_bind_to_context').on('change', function () { | 736 | $('#instruct_bind_to_context').on('change', function () { |
| 719 | $('#instruct_bind_to_context').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.bind_to_context); | 737 | $('#instruct_bind_to_context').parent().find('i').toggleClass('toggleEnabled', !!power_user.instruct.bind_to_context); |
| 720 | }); | 738 | }); |
| @@ -519,14 +519,14 @@ function convertTokenIdLogprobsToText(input) { | |||
| 519 | 519 | ||
| 520 | const tokenizerId = getTokenizerBestMatch(api); | 520 | const tokenizerId = getTokenizerBestMatch(api); |
| 521 | 521 | ||
| 522 | // Flatten unique token IDs across all logprobs | 522 | /** @type {any[]} Flatten unique token IDs across all logprobs */ |
| 523 | const tokenIds = Array.from(new Set(input.flatMap(logprobs => | 523 | const tokenIds = Array.from(new Set(input.flatMap(logprobs => |
| 524 | logprobs.topLogprobs.map(([token]) => token).concat(logprobs.token), | 524 | logprobs.topLogprobs.map(([token]) => token).concat(logprobs.token), |
| 525 | ))); | 525 | ))); |
| 526 | 526 | ||
| 527 | // Submit token IDs to tokenizer to get token text, then build ID->text map | 527 | // Submit token IDs to tokenizer to get token text, then build ID->text map |
| 528 | // noinspection JSCheckFunctionSignatures - mutates input in-place | 528 | // noinspection JSCheckFunctionSignatures - mutates input in-place |
| 529 | const { chunks } = decodeTextTokens(tokenizerId, tokenIds.map(parseInt)); | 529 | const { chunks } = decodeTextTokens(tokenizerId, tokenIds); |
| 530 | const tokenIdText = new Map(tokenIds.map((id, i) => [id, chunks[i]])); | 530 | const tokenIdText = new Map(tokenIds.map((id, i) => [id, chunks[i]])); |
| 531 | 531 | ||
| 532 | // Fixup logprobs data with token text | 532 | // Fixup logprobs data with token text |
| @@ -752,7 +752,8 @@ async function populateChatHistory(messages, prompts, chatCompletion, type = nul | |||
| 752 | if (type === 'continue' && oai_settings.continue_prefill && chatPrompt === firstNonInjected) { | 752 | if (type === 'continue' && oai_settings.continue_prefill && chatPrompt === firstNonInjected) { |
| 753 | // in case we are using continue_prefill and the latest message is an assistant message, we want to prepend the users assistant prefill on the message | 753 | // in case we are using continue_prefill and the latest message is an assistant message, we want to prepend the users assistant prefill on the message |
| 754 | if (chatPrompt.role === 'assistant') { | 754 | if (chatPrompt.role === 'assistant') { |
| 755 | const continueMessage = await Message.createAsync(chatMessage.role, substituteParams(oai_settings.assistant_prefill + '\n\n') + chatMessage.content, chatMessage.identifier); | 755 | const messageContent = [substituteParams(oai_settings.assistant_prefill), chatMessage.content].filter(x => x).join('\n\n'); |
| 756 | const continueMessage = await Message.createAsync(chatMessage.role, messageContent, chatMessage.identifier); | ||
| 756 | const collection = new MessageCollection('continuePrefill', continueMessage); | 757 | const collection = new MessageCollection('continuePrefill', continueMessage); |
| 757 | chatCompletion.add(collection, -1); | 758 | chatCompletion.add(collection, -1); |
| 758 | continue; | 759 | continue; |
| @@ -1312,6 +1313,11 @@ export async function prepareOpenAIMessages({ | |||
| 1312 | return [chat, promptManager.tokenHandler.counts]; | 1313 | return [chat, promptManager.tokenHandler.counts]; |
| 1313 | } | 1314 | } |
| 1314 | 1315 | ||
| 1316 | /** | ||
| 1317 | * Handles errors during streaming requests. | ||
| 1318 | * @param {Response} response | ||
| 1319 | * @param {string} decoded - response text or decoded stream data | ||
| 1320 | */ | ||
| 1315 | function tryParseStreamingError(response, decoded) { | 1321 | function tryParseStreamingError(response, decoded) { |
| 1316 | try { | 1322 | try { |
| 1317 | const data = JSON.parse(decoded); | 1323 | const data = JSON.parse(decoded); |
| @@ -1323,6 +1329,9 @@ function tryParseStreamingError(response, decoded) { | |||
| 1323 | checkQuotaError(data); | 1329 | checkQuotaError(data); |
| 1324 | checkModerationError(data); | 1330 | checkModerationError(data); |
| 1325 | 1331 | ||
| 1332 | // these do not throw correctly (equiv to Error("[object Object]")) | ||
| 1333 | // if trying to fix "[object Object]" displayed to users, start here | ||
| 1334 | |||
| 1326 | if (data.error) { | 1335 | if (data.error) { |
| 1327 | toastr.error(data.error.message || response.statusText, 'Chat Completion API'); | 1336 | toastr.error(data.error.message || response.statusText, 'Chat Completion API'); |
| 1328 | throw new Error(data); | 1337 | throw new Error(data); |
| @@ -1338,15 +1347,22 @@ function tryParseStreamingError(response, decoded) { | |||
| 1338 | } | 1347 | } |
| 1339 | } | 1348 | } |
| 1340 | 1349 | ||
| 1341 | async function checkQuotaError(data) { | 1350 | /** |
| 1342 | const errorText = await renderTemplateAsync('quotaError'); | 1351 | * Checks if the response contains a quota error and displays a popup if it does. |
| 1343 | 1352 | * @param data | |
| 1353 | * @returns {void} | ||
| 1354 | * @throws {object} - response JSON | ||
| 1355 | */ | ||
| 1356 | function checkQuotaError(data) { | ||
| 1344 | if (!data) { | 1357 | if (!data) { |
| 1345 | return; | 1358 | return; |
| 1346 | } | 1359 | } |
| 1347 | 1360 | ||
| 1348 | if (data.quota_error) { | 1361 | if (data.quota_error) { |
| 1349 | callPopup(errorText, 'text'); | 1362 | renderTemplateAsync('quotaError').then((html) => Popup.show.text('Quota Error', html)); |
| 1363 | |||
| 1364 | // this does not throw correctly (equiv to Error("[object Object]")) | ||
| 1365 | // if trying to fix "[object Object]" displayed to users, start here | ||
| 1350 | throw new Error(data); | 1366 | throw new Error(data); |
| 1351 | } | 1367 | } |
| 1352 | } | 1368 | } |
| @@ -1765,6 +1781,15 @@ async function sendAltScaleRequest(messages, logit_bias, signal, type) { | |||
| 1765 | return data.output; | 1781 | return data.output; |
| 1766 | } | 1782 | } |
| 1767 | 1783 | ||
| 1784 | /** | ||
| 1785 | * Send a chat completion request to backend | ||
| 1786 | * @param {string} type (impersonate, quiet, continue, etc) | ||
| 1787 | * @param {Array} messages | ||
| 1788 | * @param {AbortSignal?} signal | ||
| 1789 | * @returns {Promise<unknown>} | ||
| 1790 | * @throws {Error} | ||
| 1791 | */ | ||
| 1792 | |||
| 1768 | async function sendOpenAIRequest(type, messages, signal) { | 1793 | async function sendOpenAIRequest(type, messages, signal) { |
| 1769 | // Provide default abort signal | 1794 | // Provide default abort signal |
| 1770 | if (!signal) { | 1795 | if (!signal) { |
| @@ -2027,12 +2052,13 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2027 | else { | 2052 | else { |
| 2028 | const data = await response.json(); | 2053 | const data = await response.json(); |
| 2029 | 2054 | ||
| 2030 | await checkQuotaError(data); | 2055 | checkQuotaError(data); |
| 2031 | checkModerationError(data); | 2056 | checkModerationError(data); |
| 2032 | 2057 | ||
| 2033 | if (data.error) { | 2058 | if (data.error) { |
| 2034 | toastr.error(data.error.message || response.statusText, t`API returned an error`); | 2059 | const message = data.error.message || response.statusText || t`Unknown error`; |
| 2035 | throw new Error(data); | 2060 | toastr.error(message, t`API returned an error`); |
| 2061 | throw new Error(message); | ||
| 2036 | } | 2062 | } |
| 2037 | 2063 | ||
| 2038 | if (type !== 'quiet') { | 2064 | if (type !== 'quiet') { |
| @@ -4056,7 +4082,7 @@ async function onModelChange() { | |||
| 4056 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { | 4082 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { |
| 4057 | if (oai_settings.max_context_unlocked) { | 4083 | if (oai_settings.max_context_unlocked) { |
| 4058 | $('#openai_max_context').attr('max', max_2mil); | 4084 | $('#openai_max_context').attr('max', max_2mil); |
| 4059 | } else if (value.includes('gemini-exp-1114')){ | 4085 | } else if (value.includes('gemini-exp-1114') || value.includes('gemini-exp-1121')) { |
| 4060 | $('#openai_max_context').attr('max', max_32k); | 4086 | $('#openai_max_context').attr('max', max_32k); |
| 4061 | } else if (value.includes('gemini-1.5-pro')) { | 4087 | } else if (value.includes('gemini-1.5-pro')) { |
| 4062 | $('#openai_max_context').attr('max', max_2mil); | 4088 | $('#openai_max_context').attr('max', max_2mil); |
| @@ -4196,10 +4222,10 @@ async function onModelChange() { | |||
| 4196 | else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) { | 4222 | else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) { |
| 4197 | $('#openai_max_context').attr('max', max_8k); | 4223 | $('#openai_max_context').attr('max', max_8k); |
| 4198 | } | 4224 | } |
| 4199 | else if (oai_settings.cohere_model.includes('command-r')) { | 4225 | else if (oai_settings.cohere_model.includes('command-r') || ['c4ai-aya-expanse-32b'].includes(oai_settings.cohere_model)) { |
| 4200 | $('#openai_max_context').attr('max', max_128k); | 4226 | $('#openai_max_context').attr('max', max_128k); |
| 4201 | } | 4227 | } |
| 4202 | else if (['c4ai-aya-23'].includes(oai_settings.cohere_model)) { | 4228 | else if (['c4ai-aya-23', 'c4ai-aya-expanse-8b'].includes(oai_settings.cohere_model)) { |
| 4203 | $('#openai_max_context').attr('max', max_8k); | 4229 | $('#openai_max_context').attr('max', max_8k); |
| 4204 | } | 4230 | } |
| 4205 | else { | 4231 | else { |
| @@ -4745,6 +4771,7 @@ export function isImageInliningSupported() { | |||
| 4745 | 'gemini-1.5-flash-8b-exp-0827', | 4771 | 'gemini-1.5-flash-8b-exp-0827', |
| 4746 | 'gemini-1.5-flash-8b-exp-0924', | 4772 | 'gemini-1.5-flash-8b-exp-0924', |
| 4747 | 'gemini-exp-1114', | 4773 | 'gemini-exp-1114', |
| 4774 | 'gemini-exp-1121', | ||
| 4748 | 'gemini-1.0-pro-vision-latest', | 4775 | 'gemini-1.0-pro-vision-latest', |
| 4749 | 'gemini-1.5-pro', | 4776 | 'gemini-1.5-pro', |
| 4750 | 'gemini-1.5-pro-latest', | 4777 | 'gemini-1.5-pro-latest', |
| @@ -226,6 +226,7 @@ let power_user = { | |||
| 226 | macro: true, | 226 | macro: true, |
| 227 | names_behavior: names_behavior_types.FORCE, | 227 | names_behavior: names_behavior_types.FORCE, |
| 228 | activation_regex: '', | 228 | activation_regex: '', |
| 229 | derived: false, | ||
| 229 | bind_to_context: false, | 230 | bind_to_context: false, |
| 230 | user_alignment_message: '', | 231 | user_alignment_message: '', |
| 231 | system_same_as_user: false, | 232 | system_same_as_user: false, |
| @@ -243,6 +244,8 @@ let power_user = { | |||
| 243 | names_as_stop_strings: true, | 244 | names_as_stop_strings: true, |
| 244 | }, | 245 | }, |
| 245 | 246 | ||
| 247 | context_derived: false, | ||
| 248 | |||
| 246 | sysprompt: { | 249 | sysprompt: { |
| 247 | enabled: true, | 250 | enabled: true, |
| 248 | name: 'Neutral - Chat', | 251 | name: 'Neutral - Chat', |
| @@ -1477,6 +1480,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1477 | $('#encode_tags').prop('checked', power_user.encode_tags); | 1480 | $('#encode_tags').prop('checked', power_user.encode_tags); |
| 1478 | $('#example_messages_behavior').val(getExampleMessagesBehavior()); | 1481 | $('#example_messages_behavior').val(getExampleMessagesBehavior()); |
| 1479 | $(`#example_messages_behavior option[value="${getExampleMessagesBehavior()}"]`).prop('selected', true); | 1482 | $(`#example_messages_behavior option[value="${getExampleMessagesBehavior()}"]`).prop('selected', true); |
| 1483 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); | ||
| 1480 | 1484 | ||
| 1481 | $('#console_log_prompts').prop('checked', power_user.console_log_prompts); | 1485 | $('#console_log_prompts').prop('checked', power_user.console_log_prompts); |
| 1482 | $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities); | 1486 | $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities); |
| @@ -3062,6 +3066,16 @@ $(document).ready(() => { | |||
| 3062 | saveSettingsDebounced(); | 3066 | saveSettingsDebounced(); |
| 3063 | }); | 3067 | }); |
| 3064 | 3068 | ||
| 3069 | $('#context_derived').on('input', function () { | ||
| 3070 | const value = !!$(this).prop('checked'); | ||
| 3071 | power_user.context_derived = value; | ||
| 3072 | saveSettingsDebounced(); | ||
| 3073 | }); | ||
| 3074 | |||
| 3075 | $('#context_derived').on('change', function () { | ||
| 3076 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); | ||
| 3077 | }); | ||
| 3078 | |||
| 3065 | $('#always-force-name2-checkbox').change(function () { | 3079 | $('#always-force-name2-checkbox').change(function () { |
| 3066 | power_user.always_force_name2 = !!$(this).prop('checked'); | 3080 | power_user.always_force_name2 = !!$(this).prop('checked'); |
| 3067 | saveSettingsDebounced(); | 3081 | saveSettingsDebounced(); |
| @@ -584,6 +584,7 @@ class PresetManager { | |||
| 584 | 'openrouter_providers', | 584 | 'openrouter_providers', |
| 585 | 'openrouter_allow_fallbacks', | 585 | 'openrouter_allow_fallbacks', |
| 586 | 'tabby_model', | 586 | 'tabby_model', |
| 587 | 'derived', | ||
| 587 | ]; | 588 | ]; |
| 588 | const settings = Object.assign({}, getSettingsByApiId(this.apiId)); | 589 | const settings = Object.assign({}, getSettingsByApiId(this.apiId)); |
| 589 | 590 | ||
| @@ -1827,6 +1827,30 @@ export function initDefaultSlashCommands() { | |||
| 1827 | </div> | 1827 | </div> |
| 1828 | `, | 1828 | `, |
| 1829 | })); | 1829 | })); |
| 1830 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 1831 | name: 'upper', | ||
| 1832 | aliases: ['uppercase', 'to-upper'], | ||
| 1833 | callback: (_, text) => typeof text === 'string' ? text.toUpperCase() : '', | ||
| 1834 | returns: 'uppercase string', | ||
| 1835 | unnamedArgumentList: [ | ||
| 1836 | new SlashCommandArgument( | ||
| 1837 | 'string', [ARGUMENT_TYPE.STRING], true, false, | ||
| 1838 | ), | ||
| 1839 | ], | ||
| 1840 | helpString: 'Converts the provided string to uppercase.', | ||
| 1841 | })); | ||
| 1842 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 1843 | name: 'lower', | ||
| 1844 | aliases: ['lowercase', 'to-lower'], | ||
| 1845 | callback: (_, text) => typeof text === 'string' ? text.toLowerCase() : '', | ||
| 1846 | returns: 'lowercase string', | ||
| 1847 | unnamedArgumentList: [ | ||
| 1848 | new SlashCommandArgument( | ||
| 1849 | 'string', [ARGUMENT_TYPE.STRING], true, false, | ||
| 1850 | ), | ||
| 1851 | ], | ||
| 1852 | helpString: 'Converts the provided string to lowercase.', | ||
| 1853 | })); | ||
| 1830 | 1854 | ||
| 1831 | registerVariableCommands(); | 1855 | registerVariableCommands(); |
| 1832 | } | 1856 | } |
| @@ -1,5 +1,4 @@ | |||
| 1 | import { escapeRegex } from '../utils.js'; | 1 | import { escapeRegex } from '../utils.js'; |
| 2 | import { SlashCommand } from './SlashCommand.js'; | ||
| 3 | import { SlashCommandParser } from './SlashCommandParser.js'; | 2 | import { SlashCommandParser } from './SlashCommandParser.js'; |
| 4 | 3 | ||
| 5 | export class SlashCommandBrowser { | 4 | export class SlashCommandBrowser { |
| @@ -30,7 +29,7 @@ export class SlashCommandBrowser { | |||
| 30 | this.details?.remove(); | 29 | this.details?.remove(); |
| 31 | this.details = null; | 30 | this.details = null; |
| 32 | let query = inp.value.trim(); | 31 | let query = inp.value.trim(); |
| 33 | if (query.slice(-1) == '"' && !/(?:^|\s+)"/.test(query)) { | 32 | if (query.slice(-1) === '"' && !/(?:^|\s+)"/.test(query)) { |
| 34 | query = `"${query}`; | 33 | query = `"${query}`; |
| 35 | } | 34 | } |
| 36 | let fuzzyList = []; | 35 | let fuzzyList = []; |
| @@ -59,7 +58,7 @@ export class SlashCommandBrowser { | |||
| 59 | cmd.helpString, | 58 | cmd.helpString, |
| 60 | ]; | 59 | ]; |
| 61 | const find = ()=>targets.find(t=>(fuzzyList.find(f=>f.test(t)) ?? quotedList.find(q=>t.includes(q))) !== undefined) !== undefined; | 60 | const find = ()=>targets.find(t=>(fuzzyList.find(f=>f.test(t)) ?? quotedList.find(q=>t.includes(q))) !== undefined) !== undefined; |
| 62 | if (fuzzyList.length + quotedList.length == 0 || find()) { | 61 | if (fuzzyList.length + quotedList.length === 0 || find()) { |
| 63 | this.itemMap[cmd.name].classList.remove('isFiltered'); | 62 | this.itemMap[cmd.name].classList.remove('isFiltered'); |
| 64 | } else { | 63 | } else { |
| 65 | this.itemMap[cmd.name].classList.add('isFiltered'); | 64 | this.itemMap[cmd.name].classList.add('isFiltered'); |
| @@ -78,7 +77,7 @@ export class SlashCommandBrowser { | |||
| 78 | list.classList.add('autoComplete'); | 77 | list.classList.add('autoComplete'); |
| 79 | this.cmdList = Object | 78 | this.cmdList = Object |
| 80 | .keys(SlashCommandParser.commands) | 79 | .keys(SlashCommandParser.commands) |
| 81 | .filter(key => SlashCommandParser.commands[key].name == key) // exclude aliases | 80 | .filter(key => SlashCommandParser.commands[key].name === key) // exclude aliases |
| 82 | .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())) | 81 | .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())) |
| 83 | .map(key => SlashCommandParser.commands[key]) | 82 | .map(key => SlashCommandParser.commands[key]) |
| 84 | ; | 83 | ; |
| @@ -97,7 +96,7 @@ export class SlashCommandBrowser { | |||
| 97 | } | 96 | } |
| 98 | } | 97 | } |
| 99 | } | 98 | } |
| 100 | if (this.details != details) { | 99 | if (this.details !== details) { |
| 101 | Array.from(list.querySelectorAll('.selected')).forEach(it=>it.classList.remove('selected')); | 100 | Array.from(list.querySelectorAll('.selected')).forEach(it=>it.classList.remove('selected')); |
| 102 | item.classList.add('selected'); | 101 | item.classList.add('selected'); |
| 103 | this.details?.remove(); | 102 | this.details?.remove(); |
| @@ -124,7 +123,7 @@ export class SlashCommandBrowser { | |||
| 124 | parent.append(this.dom); | 123 | parent.append(this.dom); |
| 125 | 124 | ||
| 126 | this.mo = new MutationObserver(muts=>{ | 125 | this.mo = new MutationObserver(muts=>{ |
| 127 | if (muts.find(mut=>Array.from(mut.removedNodes).find(it=>it == this.dom || it.contains(this.dom)))) { | 126 | if (muts.find(mut=>Array.from(mut.removedNodes).find(it=>it === this.dom || it.contains(this.dom)))) { |
| 128 | this.mo.disconnect(); | 127 | this.mo.disconnect(); |
| 129 | window.removeEventListener('keydown', boundHandler); | 128 | window.removeEventListener('keydown', boundHandler); |
| 130 | } | 129 | } |
| @@ -136,7 +135,7 @@ export class SlashCommandBrowser { | |||
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | handleKeyDown(evt) { | 137 | handleKeyDown(evt) { |
| 139 | if (!evt.shiftKey && !evt.altKey && evt.ctrlKey && evt.key.toLowerCase() == 'f') { | 138 | if (!evt.shiftKey && !evt.altKey && evt.ctrlKey && evt.key.toLowerCase() === 'f') { |
| 140 | if (!this.dom.closest('body')) return; | 139 | if (!this.dom.closest('body')) return; |
| 141 | if (this.dom.closest('.mes') && !this.dom.closest('.last_mes')) return; | 140 | if (this.dom.closest('.mes') && !this.dom.closest('.last_mes')) return; |
| 142 | evt.preventDefault(); | 141 | evt.preventDefault(); |
| @@ -882,6 +882,13 @@ function setSettingByName(setting, value, trigger) { | |||
| 882 | } | 882 | } |
| 883 | } | 883 | } |
| 884 | 884 | ||
| 885 | /** | ||
| 886 | * Sends a streaming request for textgenerationwebui. | ||
| 887 | * @param generate_data | ||
| 888 | * @param signal | ||
| 889 | * @returns {Promise<(function(): AsyncGenerator<{swipes: [], text: string, toolCalls: [], logprobs: {token: string, topLogprobs: Candidate[]}|null}, void, *>)|*>} | ||
| 890 | * @throws {Error} - If the response status is not OK, or from within the generator | ||
| 891 | */ | ||
| 885 | async function generateTextGenWithStreaming(generate_data, signal) { | 892 | async function generateTextGenWithStreaming(generate_data, signal) { |
| 886 | generate_data.stream = true; | 893 | generate_data.stream = true; |
| 887 | 894 | ||
| @@ -997,6 +1004,7 @@ export function parseTabbyLogprobs(data) { | |||
| 997 | * @param {Response} response - Response from the server. | 1004 | * @param {Response} response - Response from the server. |
| 998 | * @param {string} decoded - Decoded response body. | 1005 | * @param {string} decoded - Decoded response body. |
| 999 | * @returns {void} Nothing. | 1006 | * @returns {void} Nothing. |
| 1007 | * @throws {Error} If the response contains an error message, throws Error with the message. | ||
| 1000 | */ | 1008 | */ |
| 1001 | function tryParseStreamingError(response, decoded) { | 1009 | function tryParseStreamingError(response, decoded) { |
| 1002 | let data = {}; | 1010 | let data = {}; |
| @@ -280,7 +280,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 280 | delete generationConfig.stopSequences; | 280 | delete generationConfig.stopSequences; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | const should_use_system_prompt = (model.includes('gemini-1.5-flash') || model.includes('gemini-1.5-pro') || model.includes('gemini-exp-1114')) && request.body.use_makersuite_sysprompt; | 283 | const should_use_system_prompt = (model.includes('gemini-1.5-flash') || model.includes('gemini-1.5-pro') || model.includes('gemini-exp-1114') || model.includes('gemini-exp-1121')) && request.body.use_makersuite_sysprompt; |
| 284 | const prompt = convertGooglePrompt(request.body.messages, model, should_use_system_prompt, request.body.char_name, request.body.user_name); | 284 | const prompt = convertGooglePrompt(request.body.messages, model, should_use_system_prompt, request.body.char_name, request.body.user_name); |
| 285 | let body = { | 285 | let body = { |
| 286 | contents: prompt.contents, | 286 | contents: prompt.contents, |
| @@ -1051,8 +1051,12 @@ router.post('/generate', jsonParser, function (request, response) { | |||
| 1051 | } | 1051 | } |
| 1052 | } catch (error) { | 1052 | } catch (error) { |
| 1053 | console.log('Generation failed', error); | 1053 | console.log('Generation failed', error); |
| 1054 | const message = error.code === 'ECONNREFUSED' | ||
| 1055 | ? `Connection refused: ${error.message}` | ||
| 1056 | : error.message || 'Unknown error occurred'; | ||
| 1057 | |||
| 1054 | if (!response.headersSent) { | 1058 | if (!response.headersSent) { |
| 1055 | response.send({ error: true }); | 1059 | response.status(502).send({ error: { message, ...error } }); |
| 1056 | } else { | 1060 | } else { |
| 1057 | response.end(); | 1061 | response.end(); |
| 1058 | } | 1062 | } |
| @@ -1068,7 +1072,7 @@ router.post('/generate', jsonParser, function (request, response) { | |||
| 1068 | 1072 | ||
| 1069 | const message = errorResponse.statusText || 'Unknown error occurred'; | 1073 | const message = errorResponse.statusText || 'Unknown error occurred'; |
| 1070 | const quota_error = errorResponse.status === 429 && errorData?.error?.type === 'insufficient_quota'; | 1074 | const quota_error = errorResponse.status === 429 && errorData?.error?.type === 'insufficient_quota'; |
| 1071 | console.log(message, responseText); | 1075 | console.log('Chat completion request error: ', message, responseText); |
| 1072 | 1076 | ||
| 1073 | if (!response.headersSent) { | 1077 | if (!response.headersSent) { |
| 1074 | response.send({ error: { message }, quota_error: quota_error }); | 1078 | response.send({ error: { message }, quota_error: quota_error }); |
| @@ -16,6 +16,7 @@ import { | |||
| 16 | } from '../../constants.js'; | 16 | } from '../../constants.js'; |
| 17 | import { forwardFetchResponse, trimV1, getConfigValue } from '../../util.js'; | 17 | import { forwardFetchResponse, trimV1, getConfigValue } from '../../util.js'; |
| 18 | import { setAdditionalHeaders } from '../../additional-headers.js'; | 18 | import { setAdditionalHeaders } from '../../additional-headers.js'; |
| 19 | import { createHash } from 'node:crypto'; | ||
| 19 | 20 | ||
| 20 | export const router = express.Router(); | 21 | export const router = express.Router(); |
| 21 | 22 | ||
| @@ -227,6 +228,40 @@ router.post('/status', jsonParser, async function (request, response) { | |||
| 227 | } | 228 | } |
| 228 | }); | 229 | }); |
| 229 | 230 | ||
| 231 | router.post('/props', jsonParser, async function (request, response) { | ||
| 232 | if (!request.body.api_server) return response.sendStatus(400); | ||
| 233 | |||
| 234 | try { | ||
| 235 | const baseUrl = trimV1(request.body.api_server); | ||
| 236 | const args = { | ||
| 237 | headers: {}, | ||
| 238 | }; | ||
| 239 | |||
| 240 | setAdditionalHeaders(request, args, baseUrl); | ||
| 241 | |||
| 242 | const apiType = request.body.api_type; | ||
| 243 | const propsUrl = baseUrl + '/props'; | ||
| 244 | const propsReply = await fetch(propsUrl, args); | ||
| 245 | |||
| 246 | if (!propsReply.ok) { | ||
| 247 | return response.status(400); | ||
| 248 | } | ||
| 249 | |||
| 250 | /** @type {any} */ | ||
| 251 | const props = await propsReply.json(); | ||
| 252 | // TEMPORARY: llama.cpp's /props endpoint has a bug which replaces the last newline with a \0 | ||
| 253 | if (apiType === TEXTGEN_TYPES.LLAMACPP && props['chat_template'].endsWith('\u0000')) { | ||
| 254 | props['chat_template'] = props['chat_template'].slice(0, -1) + '\n'; | ||
| 255 | } | ||
| 256 | props['chat_template_hash'] = createHash('sha256').update(props['chat_template']).digest('hex'); | ||
| 257 | console.log(`Model properties: ${JSON.stringify(props)}`); | ||
| 258 | return response.send(props); | ||
| 259 | } catch (error) { | ||
| 260 | console.error(error); | ||
| 261 | return response.status(500); | ||
| 262 | } | ||
| 263 | }); | ||
| 264 | |||
| 230 | router.post('/generate', jsonParser, async function (request, response) { | 265 | router.post('/generate', jsonParser, async function (request, response) { |
| 231 | if (!request.body) return response.sendStatus(400); | 266 | if (!request.body) return response.sendStatus(400); |
| 232 | 267 | ||
| @@ -24,6 +24,8 @@ const defaultAvatarPath = './public/img/ai4.png'; | |||
| 24 | 24 | ||
| 25 | // KV-store for parsed character data | 25 | // KV-store for parsed character data |
| 26 | const characterDataCache = new Map(); | 26 | const characterDataCache = new Map(); |
| 27 | // Some Android devices require tighter memory management | ||
| 28 | const isAndroid = process.platform === 'android'; | ||
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 29 | * Reads the character card from the specified image file. | 31 | * Reads the character card from the specified image file. |
| @@ -39,7 +41,7 @@ async function readCharacterData(inputFile, inputFormat = 'png') { | |||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | const result = parse(inputFile, inputFormat); | 43 | const result = parse(inputFile, inputFormat); |
| 42 | characterDataCache.set(cacheKey, result); | 44 | !isAndroid && characterDataCache.set(cacheKey, result); |
| 43 | return result; | 45 | return result; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| @@ -6,7 +6,7 @@ import { publicLibConfig } from '../../webpack.config.js'; | |||
| 6 | export default function getWebpackServeMiddleware() { | 6 | export default function getWebpackServeMiddleware() { |
| 7 | const compiler = webpack(publicLibConfig); | 7 | const compiler = webpack(publicLibConfig); |
| 8 | 8 | ||
| 9 | if (process.env.NODE_ENV === 'production') { | 9 | if (process.env.NODE_ENV === 'production' || process.platform === 'android') { |
| 10 | compiler.hooks.done.tap('serve', () => { | 10 | compiler.hooks.done.tap('serve', () => { |
| 11 | if (compiler.watching) { | 11 | if (compiler.watching) { |
| 12 | compiler.watching.close(() => { }); | 12 | compiler.watching.close(() => { }); |
| @@ -347,6 +347,7 @@ export function convertGooglePrompt(messages, model, useSysPrompt = false, charN | |||
| 347 | 'gemini-1.5-flash-8b-exp-0827', | 347 | 'gemini-1.5-flash-8b-exp-0827', |
| 348 | 'gemini-1.5-flash-8b-exp-0924', | 348 | 'gemini-1.5-flash-8b-exp-0924', |
| 349 | 'gemini-exp-1114', | 349 | 'gemini-exp-1114', |
| 350 | 'gemini-exp-1121', | ||
| 350 | 'gemini-1.5-pro', | 351 | 'gemini-1.5-pro', |
| 351 | 'gemini-1.5-pro-latest', | 352 | 'gemini-1.5-pro-latest', |
| 352 | 'gemini-1.5-pro-001', | 353 | 'gemini-1.5-pro-001', |
| @@ -628,11 +629,30 @@ export function convertMistralMessages(messages, charName = '', userName = '') { | |||
| 628 | export function mergeMessages(messages, charName, userName, strict) { | 629 | export function mergeMessages(messages, charName, userName, strict) { |
| 629 | let mergedMessages = []; | 630 | let mergedMessages = []; |
| 630 | 631 | ||
| 632 | /** @type {Map<string,object>} */ | ||
| 633 | const contentTokens = new Map(); | ||
| 634 | |||
| 631 | // Remove names from the messages | 635 | // Remove names from the messages |
| 632 | messages.forEach((message) => { | 636 | messages.forEach((message) => { |
| 633 | if (!message.content) { | 637 | if (!message.content) { |
| 634 | message.content = ''; | 638 | message.content = ''; |
| 635 | } | 639 | } |
| 640 | // Flatten contents and replace image URLs with random tokens | ||
| 641 | if (Array.isArray(message.content)) { | ||
| 642 | const text = message.content.map((content) => { | ||
| 643 | if (content.type === 'text') { | ||
| 644 | return content.text; | ||
| 645 | } | ||
| 646 | // Could be extended with other non-text types | ||
| 647 | if (content.type === 'image_url') { | ||
| 648 | const token = crypto.randomBytes(32).toString('base64'); | ||
| 649 | contentTokens.set(token, content); | ||
| 650 | return token; | ||
| 651 | } | ||
| 652 | return ''; | ||
| 653 | }).join('\n\n'); | ||
| 654 | message.content = text; | ||
| 655 | } | ||
| 636 | if (message.role === 'system' && message.name === 'example_assistant') { | 656 | if (message.role === 'system' && message.name === 'example_assistant') { |
| 637 | if (charName && !message.content.startsWith(`${charName}: `)) { | 657 | if (charName && !message.content.startsWith(`${charName}: `)) { |
| 638 | message.content = `${charName}: ${message.content}`; | 658 | message.content = `${charName}: ${message.content}`; |
| @@ -673,6 +693,32 @@ export function mergeMessages(messages, charName, userName, strict) { | |||
| 673 | }); | 693 | }); |
| 674 | } | 694 | } |
| 675 | 695 | ||
| 696 | // Check for content tokens and replace them with the actual content objects | ||
| 697 | if (contentTokens.size > 0) { | ||
| 698 | mergedMessages.forEach((message) => { | ||
| 699 | const hasValidToken = Array.from(contentTokens.keys()).some(token => message.content.includes(token)); | ||
| 700 | |||
| 701 | if (hasValidToken) { | ||
| 702 | const splitContent = message.content.split('\n\n'); | ||
| 703 | const mergedContent = []; | ||
| 704 | |||
| 705 | splitContent.forEach((content) => { | ||
| 706 | if (contentTokens.has(content)) { | ||
| 707 | mergedContent.push(contentTokens.get(content)); | ||
| 708 | } else { | ||
| 709 | if (mergedContent.length > 0 && mergedContent[mergedContent.length - 1].type === 'text') { | ||
| 710 | mergedContent[mergedContent.length - 1].text += `\n\n${content}`; | ||
| 711 | } else { | ||
| 712 | mergedContent.push({ type: 'text', text: content }); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | }); | ||
| 716 | |||
| 717 | message.content = mergedContent; | ||
| 718 | } | ||
| 719 | }); | ||
| 720 | } | ||
| 721 | |||
| 676 | if (strict) { | 722 | if (strict) { |
| 677 | for (let i = 0; i < mergedMessages.length; i++) { | 723 | for (let i = 0; i < mergedMessages.length; i++) { |
| 678 | // Force mid-prompt system messages to be user messages | 724 | // Force mid-prompt system messages to be user messages |