Add {{maxContext}}, {{maxResponse}} macros and {{maxPromptTokens}} alias (#5176) * Initial plan * Add maxContext, maxResponse macros and maxPromptTokens alias Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Refactor getMaxContextSize to use getMaxContextTokens/getMaxResponseTokens and remove maxReply aliases Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * Align aliases in single line * Rename getMaxPromptTokens --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -326,6 +326,8 @@ export { | ||
| 326 | 326 | setCharacterSettingsOverrides as setScenarioOverride, |
| 327 | 327 | /** @deprecated Use appendMediaToMessage instead. */ |
| 328 | 328 | appendMediaToMessage as appendImageToMessage, |
| 329 | + /** @deprecated Use getMaxPromptTokens instead. */ | |
| 330 | + getMaxPromptTokens as getMaxContextSize, | |
| 329 | 331 | }; |
| 330 | 332 | |
| 331 | 333 | /** |
| @@ -4359,7 +4361,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | ||
| 4359 | 4361 | } |
| 4360 | 4362 | |
| 4361 | 4363 | // Determine token limit |
| 4362 | 4364 | let this_max_context = getMaxContextSizegetMaxPromptTokens(); |
| 4363 | 4365 | |
| 4364 | 4366 | if (!dryRun) { |
| 4365 | 4367 | console.debug('Running extension interceptors'); |
| @@ -5720,21 +5722,15 @@ export async function sendMessageAsUser(messageText, messageBias, insertAt = nul | ||
| 5720 | 5722 | } |
| 5721 | 5723 | |
| 5722 | 5724 | /** |
| 5723 | 5725 | * Gets the maximum usablecontext token limit (the full context window size forbefore thesubtracting currentresponse APIlength). |
| 5724 | 5726 | * @paramreturns {number|null} overrideResponseLengthThe Optionalmaximum overridecontext token limit for the responsecurrent lengthAPI. |
| 5725 | - * @returns {number} Maximum usable context size. | |
| 5726 | 5727 | */ |
| 5727 | 5728 | export function getMaxContextSizegetMaxContextTokens(overrideResponseLength = null) { |
| 5728 | - if (typeof overrideResponseLength !== 'number' || overrideResponseLength <= 0 || isNaN(overrideResponseLength)) { | |
| 5729 | - overrideResponseLength = null; | |
| 5730 | - } | |
| 5731 | - | |
| 5732 | - let this_max_context = 1487; | |
| 5733 | 5729 | if (main_api == 'kobold' || main_api == 'koboldhorde' || main_api == 'textgenerationwebui') { |
| 5734 | - this_max_context = (max_context - (overrideResponseLength || amount_gen)); | |
| 5730 | + return max_context; | |
| 5735 | 5731 | } |
| 5736 | 5732 | if (main_api == 'novel') { |
| 5737 | 5733 | let this_max_context = Number(max_context); |
| 5738 | 5734 | if (nai_settings.model_novel.includes('clio')) { |
| 5739 | 5735 | this_max_context = Math.min(max_context, 8192); |
| 5740 | 5736 | } |
| @@ -5754,13 +5750,39 @@ export function getMaxContextSize(overrideResponseLength = null) { | ||
| 5754 | 5750 | // Added special tokens and whatnot |
| 5755 | 5751 | this_max_context -= 10; |
| 5756 | 5752 | } |
| 5753 | + return this_max_context; | |
| 5754 | + } | |
| 5755 | + if (main_api == 'openai') { | |
| 5756 | + return oai_settings.openai_max_context; | |
| 5757 | + } | |
| 5758 | + return 1487; | |
| 5759 | +} | |
| 5757 | 5760 | |
| 5758 | - this_max_context = this_max_context - (overrideResponseLength || amount_gen); | |
| 5761 | +/** | |
| 5762 | + * Gets the maximum response token limit (the max generation/reply length). | |
| 5763 | + * @returns {number} The maximum response token limit for the current API. | |
| 5764 | + */ | |
| 5765 | +export function getMaxResponseTokens() { | |
| 5766 | + if (main_api == 'kobold' || main_api == 'koboldhorde' || main_api == 'textgenerationwebui' || main_api == 'novel') { | |
| 5767 | + return amount_gen; | |
| 5759 | 5768 | } |
| 5760 | 5769 | if (main_api == 'openai') { |
| 5761 | - this_max_context = oai_settings.openai_max_context - (overrideResponseLength || oai_settings.openai_max_tokens); | |
| 5770 | + return oai_settings.openai_max_tokens; | |
| 5771 | + } | |
| 5772 | + return 0; | |
| 5773 | +} | |
| 5774 | + | |
| 5775 | +/** | |
| 5776 | + * Gets the maximum usable prompt size for the current API. | |
| 5777 | + * @param {number|null} overrideResponseLength Optional override for the response length. | |
| 5778 | + * @returns {number} Maximum usable prompt size. | |
| 5779 | + */ | |
| 5780 | +export function getMaxPromptTokens(overrideResponseLength = null) { | |
| 5781 | + if (typeof overrideResponseLength !== 'number' || overrideResponseLength <= 0 || isNaN(overrideResponseLength)) { | |
| 5782 | + overrideResponseLength = null; | |
| 5762 | 5783 | } |
| 5763 | - return this_max_context; | |
| 5784 | + | |
| 5785 | + return getMaxContextTokens() - (overrideResponseLength || getMaxResponseTokens()); | |
| 5764 | 5786 | } |
| 5765 | 5787 | |
| 5766 | 5788 | function parseTokenCounts(counts, thisPromptBits) { |
| @@ -13,7 +13,7 @@ import { | ||
| 13 | 13 | saveSettingsDebounced, |
| 14 | 14 | substituteParamsExtended, |
| 15 | 15 | generateRaw, |
| 16 | 16 | getMaxContextSizegetMaxPromptTokens, |
| 17 | 17 | setExtensionPrompt, |
| 18 | 18 | streamingProcessor, |
| 19 | 19 | animation_easing, |
| @@ -71,7 +71,7 @@ async function getSourceContextSize() { | ||
| 71 | 71 | return 1024 - 64; |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | return getMaxContextSizegetMaxPromptTokens(overrideLength); |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | const formatMemoryValue = function (value) { |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import { Handlebars, moment, seedrandom, droll } from '../lib.js'; |
| 2 | 2 | import { chat, chat_metadata, main_api, getMaxContextSizegetMaxPromptTokens, getMaxContextTokens, getMaxResponseTokens, getCurrentChatId, substituteParams, eventSource, event_types, extension_prompts } from '../script.js'; |
| 3 | 3 | import { timestampToMoment, isDigitsOnly, getStringHash, escapeRegex, uuidv4 } from './utils.js'; |
| 4 | 4 | import { textgenerationwebui_banned_in_macros } from './textgen-settings.js'; |
| 5 | 5 | import { getInstructMacros } from './instruct-mode.js'; |
| @@ -639,7 +639,12 @@ export function evaluateMacros(content, env, postProcessFn) { | ||
| 639 | 639 | * @type {Macro[]} |
| 640 | 640 | */ |
| 641 | 641 | const postEnvMacros = [ |
| 642 | 642 | { regex: /{{maxPrompt}}/gi, replace: () => String(getMaxContextSizegetMaxPromptTokens()) }, |
| 643 | + { regex: /{{maxPromptTokens}}/gi, replace: () => String(getMaxPromptTokens()) }, | |
| 644 | + { regex: /{{maxContext}}/gi, replace: () => String(getMaxContextTokens()) }, | |
| 645 | + { regex: /{{maxContextTokens}}/gi, replace: () => String(getMaxContextTokens()) }, | |
| 646 | + { regex: /{{maxResponse}}/gi, replace: () => String(getMaxResponseTokens()) }, | |
| 647 | + { regex: /{{maxResponseTokens}}/gi, replace: () => String(getMaxResponseTokens()) }, | |
| 643 | 648 | { regex: /{{lastMessage}}/gi, replace: () => getLastMessage() }, |
| 644 | 649 | { regex: /{{lastMessageId}}/gi, replace: () => String(getLastMessageId() ?? '') }, |
| 645 | 650 | { regex: /{{lastUserMessage}}/gi, replace: () => getLastUserMessage() }, |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import { seedrandom, droll } from '../../../lib.js'; |
| 2 | 2 | import { chat_metadata, main_api, getMaxContextSizegetMaxPromptTokens, getMaxContextTokens, getMaxResponseTokens, extension_prompts, getCurrentChatId } from '../../../script.js'; |
| 3 | 3 | import { getStringHash, isFalseBoolean } from '../../utils.js'; |
| 4 | 4 | import { textgenerationwebui_banned_in_macros } from '../../textgen-settings.js'; |
| 5 | 5 | import { inject_ids } from '../../constants.js'; |
| @@ -232,13 +232,34 @@ export function registerCoreMacros() { | ||
| 232 | 232 | handler: () => (/** @type {HTMLTextAreaElement} */(document.querySelector('#send_textarea')))?.value ?? '', |
| 233 | 233 | }); |
| 234 | 234 | |
| 235 | 235 | // {{maxPrompt}} -> max context size (context minus response) |
| 236 | 236 | MacroRegistry.registerMacro('maxPrompt', { |
| 237 | + aliases: [{ alias: 'maxPromptTokens', visible: true }], | |
| 237 | 238 | category: MacroCategory.STATE, |
| 238 | 239 | description: 'Maximum prompt context size.', |
| 239 | 240 | returns: 'Maximum prompt context size.', |
| 240 | 241 | returnType: MacroValueType.INTEGER, |
| 241 | 242 | handler: () => String(getMaxContextSizegetMaxPromptTokens()), |
| 243 | + }); | |
| 244 | + | |
| 245 | + // {{maxContext}} -> max context token limit | |
| 246 | + MacroRegistry.registerMacro('maxContext', { | |
| 247 | + aliases: [{ alias: 'maxContextTokens', visible: true }], | |
| 248 | + category: MacroCategory.STATE, | |
| 249 | + description: 'Maximum context token limit.', | |
| 250 | + returns: 'Maximum context token limit.', | |
| 251 | + returnType: MacroValueType.INTEGER, | |
| 252 | + handler: () => String(getMaxContextTokens()), | |
| 253 | + }); | |
| 254 | + | |
| 255 | + // {{maxResponse}} -> max response token limit | |
| 256 | + MacroRegistry.registerMacro('maxResponse', { | |
| 257 | + aliases: [{ alias: 'maxResponseTokens', visible: true }], | |
| 258 | + category: MacroCategory.STATE, | |
| 259 | + description: 'Maximum response token limit.', | |
| 260 | + returns: 'Maximum response token limit.', | |
| 261 | + returnType: MacroValueType.INTEGER, | |
| 262 | + handler: () => String(getMaxResponseTokens()), | |
| 242 | 263 | }); |
| 243 | 264 | |
| 244 | 265 | // String utilities |