| 1 | /** |
| 2 | * Common debounce timeout values to use with `debounce` calls. |
| 3 | * @readonly |
| 4 | * @enum {number} |
| 5 | */ |
| 6 | export const debounce_timeout = { |
| 7 | /** [100 ms] For ultra-fast responses, typically for keypresses or executions that might happen multiple times in a loop or recursion. */ |
| 8 | quick: 100, |
| 9 | /** [200 ms] Slightly slower than quick, but still very responsive. */ |
| 10 | short: 200, |
| 11 | /** [300 ms] Default time for general use, good balance between responsiveness and performance. */ |
| 12 | standard: 300, |
| 13 | /** [1.000 ms] For situations where the function triggers more intensive tasks. */ |
| 14 | relaxed: 1000, |
| 15 | /** [5 sec] For delayed tasks, like auto-saving or completing batch operations that need a significant pause. */ |
| 16 | extended: 5000, |
| 17 | }; |
| 18 | |
| 19 | /** |
| 20 | * Used as an ephemeral key in message extra metadata. |
| 21 | * When set, the message will be excluded from generation |
| 22 | * prompts without affecting the number of chat messages, |
| 23 | * which is needed to preserve world info timed effects. |
| 24 | */ |
| 25 | export const IGNORE_SYMBOL = Symbol.for('ignore'); |
| 26 | |
| 27 | /** |
| 28 | * Common video file extensions. Should be the same as supported by Gemini. |
| 29 | * https://ai.google.dev/gemini-api/docs/video-understanding#supported-formats |
| 30 | */ |
| 31 | export const VIDEO_EXTENSIONS = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', '3gp', 'mkv', 'mpg']; |
| 32 | |
| 33 | /** |
| 34 | * Known generation triggers that can be passed to Generate function. |
| 35 | */ |
| 36 | export const GENERATION_TYPE_TRIGGERS = [ |
| 37 | 'normal', |
| 38 | 'continue', |
| 39 | 'impersonate', |
| 40 | 'swipe', |
| 41 | 'regenerate', |
| 42 | 'quiet', |
| 43 | ]; |
| 44 | |
| 45 | /** |
| 46 | * Known injection IDs and helper functions for system extensions handling. |
| 47 | */ |
| 48 | export const inject_ids = { |
| 49 | STORY_STRING: '__STORY_STRING__', |
| 50 | QUIET_PROMPT: 'QUIET_PROMPT', |
| 51 | DEPTH_PROMPT: 'DEPTH_PROMPT', |
| 52 | DEPTH_PROMPT_INDEX: (index) => `DEPTH_PROMPT_${index}`, |
| 53 | CUSTOM_WI_DEPTH: 'customDepthWI', |
| 54 | CUSTOM_WI_DEPTH_ROLE: (depth, role) => `customDepthWI_${depth}_${role}`, |
| 55 | CUSTOM_WI_OUTLET: (key) => `customWIOutlet_${key}`, |
| 56 | }; |
| 57 | |
| 58 | export const COMETAPI_IGNORE_PATTERNS = [ |
| 59 | // Image generation models |
| 60 | 'dall-e', 'dalle', 'midjourney', 'mj_', 'stable-diffusion', 'sd-', |
| 61 | 'flux-', 'playground-v', 'ideogram', 'recraft-', 'black-forest-labs', |
| 62 | '/recraft-v3', 'recraftv3', 'stability-ai/', 'sdxl', |
| 63 | // Audio generation models |
| 64 | 'suno_', 'tts', 'whisper', |
| 65 | // Video generation models |
| 66 | 'runway', 'luma_', 'luma-', 'veo', 'kling_', 'minimax_video', 'hunyuan-t1', |
| 67 | // Utility models |
| 68 | 'embedding', 'search-gpts', 'files_retrieve', 'moderation', |
| 69 | ]; |
| 70 | |
| 71 | /** |
| 72 | * @readonly |
| 73 | * @enum {string} |
| 74 | */ |
| 75 | export const MEDIA_SOURCE = { |
| 76 | API: 'api', |
| 77 | UPLOAD: 'upload', |
| 78 | GENERATED: 'generated', |
| 79 | CAPTIONED: 'captioned', |
| 80 | }; |
| 81 | |
| 82 | /** |
| 83 | * @readonly |
| 84 | * @enum {string} |
| 85 | */ |
| 86 | export const MEDIA_DISPLAY = { |
| 87 | LIST: 'list', |
| 88 | GALLERY: 'gallery', |
| 89 | }; |
| 90 | |
| 91 | /** |
| 92 | * @readonly |
| 93 | * @enum {string} |
| 94 | */ |
| 95 | export const IMAGE_OVERSWIPE = { |
| 96 | GENERATE: 'generate', |
| 97 | ROLLOVER: 'rollover', |
| 98 | }; |
| 99 | |
| 100 | /** |
| 101 | * @readonly |
| 102 | */ |
| 103 | export const MEDIA_TYPE = { |
| 104 | getFromMime: (/** @type {string} */ mimeType) => { |
| 105 | if (mimeType.startsWith('image/')) { |
| 106 | return MEDIA_TYPE.IMAGE; |
| 107 | } |
| 108 | if (mimeType.startsWith('video/')) { |
| 109 | return MEDIA_TYPE.VIDEO; |
| 110 | } |
| 111 | if (mimeType.startsWith('audio/')) { |
| 112 | return MEDIA_TYPE.AUDIO; |
| 113 | } |
| 114 | return null; |
| 115 | }, |
| 116 | IMAGE: 'image', |
| 117 | VIDEO: 'video', |
| 118 | AUDIO: 'audio', |
| 119 | }; |
| 120 | |
| 121 | /** |
| 122 | * Bitwise flag-style media request types. |
| 123 | * @readonly |
| 124 | * @enum {number} |
| 125 | */ |
| 126 | export const MEDIA_REQUEST_TYPE = { |
| 127 | IMAGE: 0b001, |
| 128 | VIDEO: 0b010, |
| 129 | AUDIO: 0b100, |
| 130 | }; |
| 131 | |
| 132 | /** |
| 133 | * Scroll behavior options when appending media to messages. |
| 134 | * @readonly |
| 135 | * @enum {string} |
| 136 | */ |
| 137 | export const SCROLL_BEHAVIOR = { |
| 138 | NONE: 'none', |
| 139 | KEEP: 'keep', |
| 140 | ADJUST: 'adjust', |
| 141 | }; |
| 142 | |
| 143 | /** |
| 144 | * @readonly |
| 145 | * @enum {string} |
| 146 | */ |
| 147 | export const OVERSWIPE_BEHAVIOR = { |
| 148 | /** The overswipe right chevron will not be displayed. */ |
| 149 | NONE: 'none', |
| 150 | /** An overswipe will loop to the first swipe. */ |
| 151 | LOOP: 'loop', |
| 152 | /** Pristine greetings will loop, and chevrons will always be shown: https://github.com/SillyTavern/SillyTavern/pull/4712#issuecomment-3557893373 */ |
| 153 | PRISTINE_GREETING: 'pristine_greeting', |
| 154 | /** If chat tree is enabled, then an overswipe will allow the user to edit the message before starting a new generation. */ |
| 155 | EDIT_GENERATE: 'edit_generate', |
| 156 | /** This is the default behavior on character messages. */ |
| 157 | REGENERATE: 'regenerate', |
| 158 | }; |
| 159 | |
| 160 | /** |
| 161 | * @readonly |
| 162 | * @enum {string} |
| 163 | */ |
| 164 | export const SWIPE_DIRECTION = { |
| 165 | LEFT: 'left', |
| 166 | RIGHT: 'right', |
| 167 | }; |
| 168 | |
| 169 | /** |
| 170 | * @readonly |
| 171 | * @enum {string} |
| 172 | */ |
| 173 | export const SWIPE_SOURCE = { |
| 174 | DELETE: 'delete', |
| 175 | KEYBOARD: 'keyboard', |
| 176 | BACK: 'back', |
| 177 | AUTO_SWIPE: 'auto_swipe', |
| 178 | SLASH_COMMAND: 'slash_command', |
| 179 | SWIPE_PICKER: 'swipe_picker', |
| 180 | }; |
| 181 | |
| 182 | /** |
| 183 | * @readonly |
| 184 | * @enum {string} |
| 185 | */ |
| 186 | export const SWIPE_STATE = { |
| 187 | NONE: 'none', |
| 188 | SWIPING: 'swiping', |
| 189 | EDITING: 'editing', |
| 190 | }; |