Blame Raw
Cohee · 51ad27fb · · 572 lines (10.8 KB)
3 contributors
1export const PUBLIC_DIRECTORIES = {
2 images: 'public/img/',
3 backups: 'backups/',
4 sounds: 'public/sounds',
5 extensions: 'public/scripts/extensions',
6 globalExtensions: 'public/scripts/extensions/third-party',
7};
8
9export const SETTINGS_FILE = 'settings.json';
10
11/**
12 * @type {import('./users.js').UserDirectoryList}
13 * @readonly
14 * @enum {string}
15 */
16export const USER_DIRECTORY_TEMPLATE = Object.freeze({
17 root: '',
18 thumbnails: 'thumbnails',
19 thumbnailsBg: 'thumbnails/bg',
20 thumbnailsAvatar: 'thumbnails/avatar',
21 thumbnailsPersona: 'thumbnails/persona',
22 worlds: 'worlds',
23 user: 'user',
24 avatars: 'User Avatars',
25 userImages: 'user/images',
26 groups: 'groups',
27 groupChats: 'group chats',
28 chats: 'chats',
29 characters: 'characters',
30 backgrounds: 'backgrounds',
31 novelAI_Settings: 'NovelAI Settings',
32 koboldAI_Settings: 'KoboldAI Settings',
33 openAI_Settings: 'OpenAI Settings',
34 textGen_Settings: 'TextGen Settings',
35 themes: 'themes',
36 movingUI: 'movingUI',
37 extensions: 'extensions',
38 instruct: 'instruct',
39 context: 'context',
40 quickreplies: 'QuickReplies',
41 assets: 'assets',
42 comfyWorkflows: 'user/workflows',
43 files: 'user/files',
44 vectors: 'vectors',
45 backups: 'backups',
46 sysprompt: 'sysprompt',
47 reasoning: 'reasoning',
48});
49
50/**
51 * @type {import('./users.js').User}
52 * @readonly
53 */
54export const DEFAULT_USER = Object.freeze({
55 handle: 'default-user',
56 name: 'User',
57 created: Date.now(),
58 password: '',
59 admin: true,
60 enabled: true,
61 salt: '',
62});
63
64export const UNSAFE_EXTENSIONS = [
65 '.php',
66 '.exe',
67 '.com',
68 '.dll',
69 '.pif',
70 '.application',
71 '.gadget',
72 '.msi',
73 '.jar',
74 '.cmd',
75 '.bat',
76 '.reg',
77 '.sh',
78 '.py',
79 '.js',
80 '.jse',
81 '.jsp',
82 '.pdf',
83 '.html',
84 '.htm',
85 '.hta',
86 '.vb',
87 '.vbs',
88 '.vbe',
89 '.cpl',
90 '.msc',
91 '.scr',
92 '.sql',
93 '.iso',
94 '.img',
95 '.dmg',
96 '.ps1',
97 '.ps1xml',
98 '.ps2',
99 '.ps2xml',
100 '.psc1',
101 '.psc2',
102 '.msh',
103 '.msh1',
104 '.msh2',
105 '.mshxml',
106 '.msh1xml',
107 '.msh2xml',
108 '.scf',
109 '.lnk',
110 '.inf',
111 '.reg',
112 '.doc',
113 '.docm',
114 '.docx',
115 '.dot',
116 '.dotm',
117 '.dotx',
118 '.xls',
119 '.xlsm',
120 '.xlsx',
121 '.xlt',
122 '.xltm',
123 '.xltx',
124 '.xlam',
125 '.ppt',
126 '.pptm',
127 '.pptx',
128 '.pot',
129 '.potm',
130 '.potx',
131 '.ppam',
132 '.ppsx',
133 '.ppsm',
134 '.pps',
135 '.ppam',
136 '.sldx',
137 '.sldm',
138 '.ws',
139];
140
141export const GEMINI_SAFETY = [
142 {
143 category: 'HARM_CATEGORY_HARASSMENT',
144 threshold: 'OFF',
145 },
146 {
147 category: 'HARM_CATEGORY_HATE_SPEECH',
148 threshold: 'OFF',
149 },
150 {
151 category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
152 threshold: 'OFF',
153 },
154 {
155 category: 'HARM_CATEGORY_DANGEROUS_CONTENT',
156 threshold: 'OFF',
157 },
158 {
159 category: 'HARM_CATEGORY_CIVIC_INTEGRITY',
160 threshold: 'OFF',
161 },
162];
163
164export const VERTEX_SAFETY = [
165 {
166 category: 'HARM_CATEGORY_IMAGE_HATE',
167 threshold: 'OFF',
168 },
169 {
170 category: 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT',
171 threshold: 'OFF',
172 },
173 {
174 category: 'HARM_CATEGORY_IMAGE_HARASSMENT',
175 threshold: 'OFF',
176 },
177 {
178 category: 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT',
179 threshold: 'OFF',
180 },
181 {
182 category: 'HARM_CATEGORY_JAILBREAK',
183 threshold: 'OFF',
184 },
185];
186
187export const CHAT_COMPLETION_SOURCES = {
188 OPENAI: 'openai',
189 CLAUDE: 'claude',
190 OPENROUTER: 'openrouter',
191 AI21: 'ai21',
192 MAKERSUITE: 'makersuite',
193 VERTEXAI: 'vertexai',
194 MISTRALAI: 'mistralai',
195 CUSTOM: 'custom',
196 COHERE: 'cohere',
197 PERPLEXITY: 'perplexity',
198 GROQ: 'groq',
199 CHUTES: 'chutes',
200 ELECTRONHUB: 'electronhub',
201 NANOGPT: 'nanogpt',
202 DEEPSEEK: 'deepseek',
203 AIMLAPI: 'aimlapi',
204 XAI: 'xai',
205 POLLINATIONS: 'pollinations',
206 MOONSHOT: 'moonshot',
207 FIREWORKS: 'fireworks',
208 COMETAPI: 'cometapi',
209 AZURE_OPENAI: 'azure_openai',
210 ZAI: 'zai',
211 SILICONFLOW: 'siliconflow',
212 MINIMAX: 'minimax',
213 WORKERS_AI: 'workers_ai',
214};
215
216/**
217 * Path to multer file uploads under the data root.
218 */
219export const UPLOADS_DIRECTORY = '_uploads';
220
221// TODO: this is copied from the client code; there should be a way to de-duplicate it eventually
222export const TEXTGEN_TYPES = {
223 OOBA: 'ooba',
224 MANCER: 'mancer',
225 VLLM: 'vllm',
226 APHRODITE: 'aphrodite',
227 TABBY: 'tabby',
228 KOBOLDCPP: 'koboldcpp',
229 TOGETHERAI: 'togetherai',
230 LLAMACPP: 'llamacpp',
231 OLLAMA: 'ollama',
232 INFERMATICAI: 'infermaticai',
233 DREAMGEN: 'dreamgen',
234 OPENROUTER: 'openrouter',
235 FEATHERLESS: 'featherless',
236 HUGGINGFACE: 'huggingface',
237 GENERIC: 'generic',
238};
239
240export const INFERMATICAI_KEYS = [
241 'model',
242 'prompt',
243 'max_tokens',
244 'temperature',
245 'top_p',
246 'top_k',
247 'repetition_penalty',
248 'stream',
249 'stop',
250 'presence_penalty',
251 'frequency_penalty',
252 'min_p',
253 'seed',
254 'ignore_eos',
255 'n',
256 'best_of',
257 'min_tokens',
258 'spaces_between_special_tokens',
259 'skip_special_tokens',
260 'logprobs',
261];
262
263export const FEATHERLESS_KEYS = [
264 'model',
265 'prompt',
266 'best_of',
267 'echo',
268 'frequency_penalty',
269 'logit_bias',
270 'logprobs',
271 'max_tokens',
272 'n',
273 'presence_penalty',
274 'seed',
275 'stop',
276 'stream',
277 'suffix',
278 'temperature',
279 'top_p',
280 'user',
281
282 'use_beam_search',
283 'top_k',
284 'min_p',
285 'repetition_penalty',
286 'length_penalty',
287 'early_stopping',
288 'stop_token_ids',
289 'ignore_eos',
290 'min_tokens',
291 'skip_special_tokens',
292 'spaces_between_special_tokens',
293 'truncate_prompt_tokens',
294
295 'include_stop_str_in_output',
296 'response_format',
297 'guided_json',
298 'guided_regex',
299 'guided_choice',
300 'guided_grammar',
301 'guided_decoding_backend',
302 'guided_whitespace_pattern',
303];
304
305// https://docs.together.ai/reference/completions
306export const TOGETHERAI_KEYS = [
307 'model',
308 'prompt',
309 'max_tokens',
310 'temperature',
311 'top_p',
312 'top_k',
313 'repetition_penalty',
314 'min_p',
315 'presence_penalty',
316 'frequency_penalty',
317 'stream',
318 'stop',
319];
320
321// https://github.com/ollama/ollama/blob/main/docs/api.md#request-8
322export const OLLAMA_KEYS = [
323 'num_predict',
324 'num_ctx',
325 'num_batch',
326 'stop',
327 'temperature',
328 'repeat_penalty',
329 'presence_penalty',
330 'frequency_penalty',
331 'top_k',
332 'top_p',
333 'tfs_z',
334 'typical_p',
335 'seed',
336 'repeat_last_n',
337 'min_p',
338];
339
340// https://platform.openai.com/docs/api-reference/completions
341export const OPENAI_KEYS = [
342 'model',
343 'prompt',
344 'stream',
345 'temperature',
346 'top_p',
347 'frequency_penalty',
348 'presence_penalty',
349 'stop',
350 'seed',
351 'logit_bias',
352 'logprobs',
353 'max_tokens',
354 'n',
355 'best_of',
356];
357
358export const AVATAR_WIDTH = 512;
359export const AVATAR_HEIGHT = 768;
360export const DEFAULT_AVATAR_PATH = './public/img/ai4.png';
361
362export const OPENROUTER_HEADERS = {
363 'HTTP-Referer': 'https://sillytavern.app',
364 'X-Title': 'SillyTavern',
365};
366
367export const AIMLAPI_HEADERS = {
368 'HTTP-Referer': 'https://sillytavern.app',
369 'X-Title': 'SillyTavern',
370};
371
372export const FEATHERLESS_HEADERS = {
373 'HTTP-Referer': 'https://sillytavern.app',
374 'X-Title': 'SillyTavern',
375};
376
377export const OPENROUTER_KEYS = [
378 'max_tokens',
379 'temperature',
380 'top_k',
381 'top_p',
382 'presence_penalty',
383 'frequency_penalty',
384 'repetition_penalty',
385 'min_p',
386 'top_a',
387 'seed',
388 'logit_bias',
389 'model',
390 'stream',
391 'prompt',
392 'stop',
393 'provider',
394 'include_reasoning',
395];
396
397// https://github.com/vllm-project/vllm/blob/0f8a91401c89ac0a8018def3756829611b57727f/vllm/entrypoints/openai/protocol.py#L220
398export const VLLM_KEYS = [
399 'model',
400 'prompt',
401 'best_of',
402 'echo',
403 'frequency_penalty',
404 'logit_bias',
405 'logprobs',
406 'max_tokens',
407 'n',
408 'presence_penalty',
409 'seed',
410 'stop',
411 'stream',
412 'suffix',
413 'temperature',
414 'top_p',
415 'user',
416
417 'use_beam_search',
418 'top_k',
419 'min_p',
420 'repetition_penalty',
421 'length_penalty',
422 'early_stopping',
423 'stop_token_ids',
424 'ignore_eos',
425 'min_tokens',
426 'skip_special_tokens',
427 'spaces_between_special_tokens',
428 'truncate_prompt_tokens',
429
430 'include_stop_str_in_output',
431 'response_format',
432 'guided_json',
433 'guided_regex',
434 'guided_choice',
435 'guided_grammar',
436 'guided_decoding_backend',
437 'guided_whitespace_pattern',
438];
439
440export const AZURE_OPENAI_KEYS = [
441 'messages',
442 'temperature',
443 'frequency_penalty',
444 'presence_penalty',
445 'top_p',
446 'max_tokens',
447 'max_completion_tokens',
448 'stream',
449 'logit_bias',
450 'stop',
451 'n',
452 'logprobs',
453 'seed',
454 'tools',
455 'tool_choice',
456 'reasoning_effort',
457];
458
459export const OPENAI_VERBOSITY_MODELS = /^gpt-5/;
460
461export const OPENAI_REASONING_EFFORT_MODELS = [
462 'o1',
463 'o3-mini',
464 'o3-mini-2025-01-31',
465 'o4-mini',
466 'o4-mini-2025-04-16',
467 'o3',
468 'o3-2025-04-16',
469 'gpt-5',
470 'gpt-5-2025-08-07',
471 'gpt-5-mini',
472 'gpt-5-mini-2025-08-07',
473 'gpt-5-nano',
474 'gpt-5-nano-2025-08-07',
475 'gpt-5.1',
476 'gpt-5.1-2025-11-13',
477 'gpt-5.1-chat-latest',
478 'gpt-5.2',
479 'gpt-5.2-2025-12-11',
480 'gpt-5.2-chat-latest',
481 'gpt-5.3-chat-latest',
482 'gpt-5.4',
483 'gpt-5.4-2026-03-05',
484 'gpt-5.4-mini',
485 'gpt-5.4-mini-2026-03-17',
486 'gpt-5.4-nano',
487 'gpt-5.4-nano-2026-03-17',
488 'gpt-5.5',
489 'gpt-5.5-2026-04-23',
490];
491
492export const OPENAI_REASONING_EFFORT_MAP = {
493 min: 'minimal',
494};
495
496/**
497 * Models that only accept a single fixed reasoning effort value.
498 * @type {Record<string, string>}
499 */
500export const OPENAI_FIXED_REASONING_EFFORT = {
501 'gpt-5.3-chat-latest': 'medium',
502};
503
504export const NANOGPT_REASONING_EFFORT_MAP = {
505 min: 'none',
506 low: 'minimal',
507 medium: 'low',
508 high: 'medium',
509 max: 'high',
510};
511
512export const LOG_LEVELS = {
513 DEBUG: 0,
514 INFO: 1,
515 WARN: 2,
516 ERROR: 3,
517};
518
519/**
520 * An array of supported media file extensions.
521 * This is used to validate file uploads and ensure that only supported media types are processed.
522 */
523export const MEDIA_EXTENSIONS = [
524 'bmp',
525 'png',
526 'jpg',
527 'webp',
528 'jpeg',
529 'jfif',
530 'gif',
531 'mp4',
532 'avi',
533 'mov',
534 'wmv',
535 'flv',
536 'webm',
537 '3gp',
538 'mkv',
539 'mpg',
540 'mp3',
541 'wav',
542 'ogg',
543 'flac',
544 'aac',
545 'm4a',
546 'aiff',
547];
548
549/**
550 * Bitwise flag-style media request types.
551 */
552export const MEDIA_REQUEST_TYPE = {
553 IMAGE: 0b001,
554 VIDEO: 0b010,
555 AUDIO: 0b100,
556};
557
558
559export const ZAI_ENDPOINT = {
560 COMMON: 'common',
561 CODING: 'coding',
562};
563
564export const SILICONFLOW_ENDPOINT = {
565 GLOBAL: 'global',
566 CN: 'cn',
567};
568
569export const MINIMAX_ENDPOINT = {
570 GLOBAL: 'global',
571 CN: 'cn',
572};