Move command from script.js
| @@ -20,8 +20,6 @@ import { | |||
| 20 | validateTextGenUrl, | 20 | validateTextGenUrl, |
| 21 | parseTextgenLogprobs, | 21 | parseTextgenLogprobs, |
| 22 | parseTabbyLogprobs, | 22 | parseTabbyLogprobs, |
| 23 | textgenerationwebui_settings, | ||
| 24 | SERVER_INPUTS, | ||
| 25 | } from './scripts/textgen-settings.js'; | 23 | } from './scripts/textgen-settings.js'; |
| 26 | 24 | ||
| 27 | const { MANCER, TOGETHERAI, OOBA, VLLM, APHRODITE, TABBY, OLLAMA, INFERMATICAI, DREAMGEN, OPENROUTER, FEATHERLESS } = textgen_types; | 25 | const { MANCER, TOGETHERAI, OOBA, VLLM, APHRODITE, TABBY, OLLAMA, INFERMATICAI, DREAMGEN, OPENROUTER, FEATHERLESS } = textgen_types; |
| @@ -244,7 +242,7 @@ import { DragAndDropHandler } from './scripts/dragdrop.js'; | |||
| 244 | import { INTERACTABLE_CONTROL_CLASS, initKeyboard } from './scripts/keyboard.js'; | 242 | import { INTERACTABLE_CONTROL_CLASS, initKeyboard } from './scripts/keyboard.js'; |
| 245 | import { initDynamicStyles } from './scripts/dynamic-styles.js'; | 243 | import { initDynamicStyles } from './scripts/dynamic-styles.js'; |
| 246 | import { SlashCommandEnumValue, enumTypes } from './scripts/slash-commands/SlashCommandEnumValue.js'; | 244 | import { SlashCommandEnumValue, enumTypes } from './scripts/slash-commands/SlashCommandEnumValue.js'; |
| 247 | import { commonEnumProviders, enumIcons } from './scripts/slash-commands/SlashCommandCommonEnumsProvider.js'; | 245 | import { enumIcons } from './scripts/slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 248 | 246 | ||
| 249 | //exporting functions and vars for mods | 247 | //exporting functions and vars for mods |
| 250 | export { | 248 | export { |
| @@ -8522,77 +8520,6 @@ async function connectAPISlash(_, text) { | |||
| 8522 | } | 8520 | } |
| 8523 | 8521 | ||
| 8524 | /** | 8522 | /** |
| 8525 | * Sets the API URL and triggers the text generation web UI button click. | ||
| 8526 | * | ||
| 8527 | * @param {object} args - named args | ||
| 8528 | * @param {string?} [args.api=null] - the API name to set/get the URL for | ||
| 8529 | * @param {string?} [args.connect=true] - whether to connect to the API after setting | ||
| 8530 | * @param {string} url - the API URL to set | ||
| 8531 | * @returns {Promise<string>} | ||
| 8532 | */ | ||
| 8533 | async function setApiUrlCallback({ api = null, connect = 'true' }, url) { | ||
| 8534 | // Special handling for Chat Completion Custom OpenAI compatible, that one can also support API url handling | ||
| 8535 | const isCurrentlyCustomOpenai = main_api === 'openai' && oai_settings.chat_completion_source === chat_completion_sources.CUSTOM; | ||
| 8536 | if (api === chat_completion_sources.CUSTOM || (!api && isCurrentlyCustomOpenai)) { | ||
| 8537 | if (url && !isCurrentlyCustomOpenai) { | ||
| 8538 | toastr.warning(`Custom OpenAI API is not the currently selected API, so we cannot do an auto-connect. Consider switching to it via /api beforehand.`); | ||
| 8539 | return ''; | ||
| 8540 | } | ||
| 8541 | |||
| 8542 | if (!url) { | ||
| 8543 | return oai_settings.custom_url ?? ''; | ||
| 8544 | } | ||
| 8545 | |||
| 8546 | $('#custom_api_url_text').val(url).trigger('input'); | ||
| 8547 | |||
| 8548 | if (isTrueBoolean(connect)) { | ||
| 8549 | $('#api_button_openai').trigger('click'); | ||
| 8550 | } | ||
| 8551 | |||
| 8552 | return url; | ||
| 8553 | } | ||
| 8554 | |||
| 8555 | // Do some checks and get the api type we are targeting with this command | ||
| 8556 | if (api && !Object.values(textgen_types).includes(api)) { | ||
| 8557 | toastr.warning(`API '${api}' is not a valid text_gen API.`); | ||
| 8558 | return ''; | ||
| 8559 | } | ||
| 8560 | if (!api && !Object.values(textgen_types).includes(textgenerationwebui_settings.type)) { | ||
| 8561 | toastr.warning(`API '${textgenerationwebui_settings.type}' is not a valid text_gen API.`); | ||
| 8562 | return ''; | ||
| 8563 | } | ||
| 8564 | if (api && url && isTrueBoolean(connect) && api !== textgenerationwebui_settings.type) { | ||
| 8565 | toastr.warning(`API '${api}' is not the currently selected API, so we cannot do an auto-connect. Consider switching to it via /api beforehand.`); | ||
| 8566 | return ''; | ||
| 8567 | } | ||
| 8568 | const type = api || textgenerationwebui_settings.type; | ||
| 8569 | |||
| 8570 | const inputSelector = SERVER_INPUTS[type]; | ||
| 8571 | if (!inputSelector) { | ||
| 8572 | toastr.warning(`API '${type}' does not have a server url input.`); | ||
| 8573 | return ''; | ||
| 8574 | } | ||
| 8575 | |||
| 8576 | // If no url was provided, return the current one | ||
| 8577 | if (!url) { | ||
| 8578 | return textgenerationwebui_settings.server_urls[type] ?? ''; | ||
| 8579 | } | ||
| 8580 | |||
| 8581 | // else, we want to actually set the url | ||
| 8582 | $(inputSelector).val(url).trigger('input'); | ||
| 8583 | // trigger blur debounced, so we hide the autocomplete menu | ||
| 8584 | setTimeout(() => $(inputSelector).trigger('blur'), 1); | ||
| 8585 | |||
| 8586 | // Trigger the auto connect via connect button, if requested | ||
| 8587 | if (isTrueBoolean(connect)) { | ||
| 8588 | $('#api_button_textgenerationwebui').trigger('click'); | ||
| 8589 | } | ||
| 8590 | |||
| 8591 | // We still re-acquire the value, as it might have been modified by the validation on connect | ||
| 8592 | return textgenerationwebui_settings.server_urls[type] ?? ''; | ||
| 8593 | } | ||
| 8594 | |||
| 8595 | /** | ||
| 8596 | * Imports supported files dropped into the app window. | 8523 | * Imports supported files dropped into the app window. |
| 8597 | * @param {File[]} files Array of files to process | 8524 | * @param {File[]} files Array of files to process |
| 8598 | * @param {Map<File, string>} [data] Extra data to pass to the import function | 8525 | * @param {Map<File, string>} [data] Extra data to pass to the import function |
| @@ -9071,49 +8998,6 @@ jQuery(async function () { | |||
| 9071 | `, | 8998 | `, |
| 9072 | })); | 8999 | })); |
| 9073 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 9000 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 9074 | name: 'api-url', | ||
| 9075 | callback: setApiUrlCallback, | ||
| 9076 | returns: 'the current API url', | ||
| 9077 | aliases: ['server'], | ||
| 9078 | namedArgumentList: [ | ||
| 9079 | SlashCommandNamedArgument.fromProps({ | ||
| 9080 | name: 'api', | ||
| 9081 | description: 'API to set/get the URL for - if not provided, current API is used', | ||
| 9082 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 9083 | enumList: [ | ||
| 9084 | new SlashCommandEnumValue('custom', 'custom openai compatible', enumTypes.getBasedOnIndex(uniqueAPIs.findIndex(x => x === 'openai')), 'O'), | ||
| 9085 | ...Object.values(textgen_types).map(api => new SlashCommandEnumValue(api, null, enumTypes.getBasedOnIndex(uniqueAPIs.findIndex(x => x === 'textgenerationwebui')), 'T')), | ||
| 9086 | ], | ||
| 9087 | }), | ||
| 9088 | SlashCommandNamedArgument.fromProps({ | ||
| 9089 | name: 'connect', | ||
| 9090 | description: 'Whether to auto-connect to the API after setting the URL', | ||
| 9091 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 9092 | defaultValue: 'true', | ||
| 9093 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 9094 | }), | ||
| 9095 | ], | ||
| 9096 | unnamedArgumentList: [ | ||
| 9097 | SlashCommandArgument.fromProps({ | ||
| 9098 | description: 'API url to connect to', | ||
| 9099 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 9100 | }), | ||
| 9101 | ], | ||
| 9102 | helpString: ` | ||
| 9103 | <div> | ||
| 9104 | Set the API url / server url for the currently selected API, including the port. If no argument is provided, it will return the current API url. | ||
| 9105 | </div> | ||
| 9106 | <div> | ||
| 9107 | If a manual API is provided to <b>set</b>the URL, make sure to set <code>connect=false</code>, as auto-connect only works for the currently selected API, | ||
| 9108 | or consider switching to it with <code>/api</code> first. | ||
| 9109 | </div> | ||
| 9110 | <div> | ||
| 9111 | This slash command works for most of the Text Completion sources, and also Custom OpenAI compatible for the Chat Completion sources. If unsure which APIs are supported, | ||
| 9112 | check the auto-completion of the optional <code>api</code> argument of this command. | ||
| 9113 | </div> | ||
| 9114 | `, | ||
| 9115 | })); | ||
| 9116 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 9117 | name: 'impersonate', | 9001 | name: 'impersonate', |
| 9118 | callback: doImpersonate, | 9002 | callback: doImpersonate, |
| 9119 | aliases: ['imp'], | 9003 | aliases: ['imp'], |
| @@ -49,7 +49,7 @@ import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSel | |||
| 49 | import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js'; | 49 | import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js'; |
| 50 | import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; | 50 | import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; |
| 51 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; | 51 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; |
| 52 | import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; | 52 | import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; |
| 53 | import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync } from './tokenizers.js'; | 53 | import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync } from './tokenizers.js'; |
| 54 | import { debounce, delay, isFalseBoolean, isTrueBoolean, showFontAwesomePicker, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; | 54 | import { debounce, delay, isFalseBoolean, isTrueBoolean, showFontAwesomePicker, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; |
| 55 | import { registerVariableCommands, resolveVariable } from './variables.js'; | 55 | import { registerVariableCommands, resolveVariable } from './variables.js'; |
| @@ -1511,6 +1511,49 @@ export function initDefaultSlashCommands() { | |||
| 1511 | </div> | 1511 | </div> |
| 1512 | `, | 1512 | `, |
| 1513 | })); | 1513 | })); |
| 1514 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 1515 | name: 'api-url', | ||
| 1516 | callback: setApiUrlCallback, | ||
| 1517 | returns: 'the current API url', | ||
| 1518 | aliases: ['server'], | ||
| 1519 | namedArgumentList: [ | ||
| 1520 | SlashCommandNamedArgument.fromProps({ | ||
| 1521 | name: 'api', | ||
| 1522 | description: 'API to set/get the URL for - if not provided, current API is used', | ||
| 1523 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 1524 | enumList: [ | ||
| 1525 | new SlashCommandEnumValue('custom', 'custom openai compatible', enumTypes.getBasedOnIndex(uniqueAPIs.findIndex(x => x === 'openai')), 'O'), | ||
| 1526 | ...Object.values(textgen_types).map(api => new SlashCommandEnumValue(api, null, enumTypes.getBasedOnIndex(uniqueAPIs.findIndex(x => x === 'textgenerationwebui')), 'T')), | ||
| 1527 | ], | ||
| 1528 | }), | ||
| 1529 | SlashCommandNamedArgument.fromProps({ | ||
| 1530 | name: 'connect', | ||
| 1531 | description: 'Whether to auto-connect to the API after setting the URL', | ||
| 1532 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 1533 | defaultValue: 'true', | ||
| 1534 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 1535 | }), | ||
| 1536 | ], | ||
| 1537 | unnamedArgumentList: [ | ||
| 1538 | SlashCommandArgument.fromProps({ | ||
| 1539 | description: 'API url to connect to', | ||
| 1540 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 1541 | }), | ||
| 1542 | ], | ||
| 1543 | helpString: ` | ||
| 1544 | <div> | ||
| 1545 | Set the API url / server url for the currently selected API, including the port. If no argument is provided, it will return the current API url. | ||
| 1546 | </div> | ||
| 1547 | <div> | ||
| 1548 | If a manual API is provided to <b>set</b>the URL, make sure to set <code>connect=false</code>, as auto-connect only works for the currently selected API, | ||
| 1549 | or consider switching to it with <code>/api</code> first. | ||
| 1550 | </div> | ||
| 1551 | <div> | ||
| 1552 | This slash command works for most of the Text Completion sources, and also Custom OpenAI compatible for the Chat Completion sources. If unsure which APIs are supported, | ||
| 1553 | check the auto-completion of the optional <code>api</code> argument of this command. | ||
| 1554 | </div> | ||
| 1555 | `, | ||
| 1556 | })); | ||
| 1514 | 1557 | ||
| 1515 | registerVariableCommands(); | 1558 | registerVariableCommands(); |
| 1516 | } | 1559 | } |
| @@ -3418,6 +3461,77 @@ function setPromptEntryCallback(args, targetState) { | |||
| 3418 | return ''; | 3461 | return ''; |
| 3419 | } | 3462 | } |
| 3420 | 3463 | ||
| 3464 | /** | ||
| 3465 | * Sets the API URL and triggers the text generation web UI button click. | ||
| 3466 | * | ||
| 3467 | * @param {object} args - named args | ||
| 3468 | * @param {string?} [args.api=null] - the API name to set/get the URL for | ||
| 3469 | * @param {string?} [args.connect=true] - whether to connect to the API after setting | ||
| 3470 | * @param {string} url - the API URL to set | ||
| 3471 | * @returns {Promise<string>} | ||
| 3472 | */ | ||
| 3473 | async function setApiUrlCallback({ api = null, connect = 'true' }, url) { | ||
| 3474 | // Special handling for Chat Completion Custom OpenAI compatible, that one can also support API url handling | ||
| 3475 | const isCurrentlyCustomOpenai = main_api === 'openai' && oai_settings.chat_completion_source === chat_completion_sources.CUSTOM; | ||
| 3476 | if (api === chat_completion_sources.CUSTOM || (!api && isCurrentlyCustomOpenai)) { | ||
| 3477 | if (url && !isCurrentlyCustomOpenai) { | ||
| 3478 | toastr.warning('Custom OpenAI API is not the currently selected API, so we cannot do an auto-connect. Consider switching to it via /api beforehand.'); | ||
| 3479 | return ''; | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | if (!url) { | ||
| 3483 | return oai_settings.custom_url ?? ''; | ||
| 3484 | } | ||
| 3485 | |||
| 3486 | $('#custom_api_url_text').val(url).trigger('input'); | ||
| 3487 | |||
| 3488 | if (isTrueBoolean(connect)) { | ||
| 3489 | $('#api_button_openai').trigger('click'); | ||
| 3490 | } | ||
| 3491 | |||
| 3492 | return url; | ||
| 3493 | } | ||
| 3494 | |||
| 3495 | // Do some checks and get the api type we are targeting with this command | ||
| 3496 | if (api && !Object.values(textgen_types).includes(api)) { | ||
| 3497 | toastr.warning(`API '${api}' is not a valid text_gen API.`); | ||
| 3498 | return ''; | ||
| 3499 | } | ||
| 3500 | if (!api && !Object.values(textgen_types).includes(textgenerationwebui_settings.type)) { | ||
| 3501 | toastr.warning(`API '${textgenerationwebui_settings.type}' is not a valid text_gen API.`); | ||
| 3502 | return ''; | ||
| 3503 | } | ||
| 3504 | if (api && url && isTrueBoolean(connect) && api !== textgenerationwebui_settings.type) { | ||
| 3505 | toastr.warning(`API '${api}' is not the currently selected API, so we cannot do an auto-connect. Consider switching to it via /api beforehand.`); | ||
| 3506 | return ''; | ||
| 3507 | } | ||
| 3508 | const type = api || textgenerationwebui_settings.type; | ||
| 3509 | |||
| 3510 | const inputSelector = SERVER_INPUTS[type]; | ||
| 3511 | if (!inputSelector) { | ||
| 3512 | toastr.warning(`API '${type}' does not have a server url input.`); | ||
| 3513 | return ''; | ||
| 3514 | } | ||
| 3515 | |||
| 3516 | // If no url was provided, return the current one | ||
| 3517 | if (!url) { | ||
| 3518 | return textgenerationwebui_settings.server_urls[type] ?? ''; | ||
| 3519 | } | ||
| 3520 | |||
| 3521 | // else, we want to actually set the url | ||
| 3522 | $(inputSelector).val(url).trigger('input'); | ||
| 3523 | // trigger blur debounced, so we hide the autocomplete menu | ||
| 3524 | setTimeout(() => $(inputSelector).trigger('blur'), 1); | ||
| 3525 | |||
| 3526 | // Trigger the auto connect via connect button, if requested | ||
| 3527 | if (isTrueBoolean(connect)) { | ||
| 3528 | $('#api_button_textgenerationwebui').trigger('click'); | ||
| 3529 | } | ||
| 3530 | |||
| 3531 | // We still re-acquire the value, as it might have been modified by the validation on connect | ||
| 3532 | return textgenerationwebui_settings.server_urls[type] ?? ''; | ||
| 3533 | } | ||
| 3534 | |||
| 3421 | export let isExecutingCommandsFromChatInput = false; | 3535 | export let isExecutingCommandsFromChatInput = false; |
| 3422 | export let commandsFromChatInputAbortController; | 3536 | export let commandsFromChatInputAbortController; |
| 3423 | 3537 | ||