[chore] Fix type errors

4fcad0752f6e03d4796cda9838f96604298e02e9

Cohee <18619528+Cohee1207@users.noreply.github.com>

25 files changed, +78 -44Ignore whitespace
package-lock.json+0 -1
@@ -71,7 +71,6 @@
71 "@types/lodash": "^4.17.10",71 "@types/lodash": "^4.17.10",
72 "@types/mime-types": "^2.1.4",72 "@types/mime-types": "^2.1.4",
73 "@types/multer": "^1.4.12",73 "@types/multer": "^1.4.12",
74 "@types/node-fetch": "^2.6.11",
75 "@types/node-persist": "^3.1.8",74 "@types/node-persist": "^3.1.8",
76 "@types/png-chunk-text": "^1.0.3",75 "@types/png-chunk-text": "^1.0.3",
77 "@types/png-chunks-encode": "^1.0.2",76 "@types/png-chunks-encode": "^1.0.2",
package.json+0 -1
@@ -97,7 +97,6 @@
97 "@types/lodash": "^4.17.10",97 "@types/lodash": "^4.17.10",
98 "@types/mime-types": "^2.1.4",98 "@types/mime-types": "^2.1.4",
99 "@types/multer": "^1.4.12",99 "@types/multer": "^1.4.12",
100 "@types/node-fetch": "^2.6.11",
101 "@types/node-persist": "^3.1.8",100 "@types/node-persist": "^3.1.8",
102 "@types/png-chunk-text": "^1.0.3",101 "@types/png-chunk-text": "^1.0.3",
103 "@types/png-chunks-encode": "^1.0.2",102 "@types/png-chunks-encode": "^1.0.2",
src/character-card-parser.js+2 -2
@@ -13,7 +13,7 @@ import PNGtext from 'png-chunk-text';
13 * @returns {Buffer} PNG image buffer with metadata13 * @returns {Buffer} PNG image buffer with metadata
14 */14 */
15export const write = (image, data) => {15export const write = (image, data) => {
16 const chunks = extract(image);16 const chunks = extract(new Uint8Array(image));
17 const tEXtChunks = chunks.filter(chunk => chunk.name === 'tEXt');17 const tEXtChunks = chunks.filter(chunk => chunk.name === 'tEXt');
1818
19 // Remove existing tEXt chunks19 // Remove existing tEXt chunks
@@ -52,7 +52,7 @@ export const write = (image, data) => {
52 * @returns {string} Character data52 * @returns {string} Character data
53 */53 */
54export const read = (image) => {54export const read = (image) => {
55 const chunks = extract(image);55 const chunks = extract(new Uint8Array(image));
5656
57 const textChunks = chunks.filter((chunk) => chunk.name === 'tEXt').map((chunk) => PNGtext.decode(chunk.data));57 const textChunks = chunks.filter((chunk) => chunk.name === 'tEXt').map((chunk) => PNGtext.decode(chunk.data));
5858
src/endpoints/anthropic.js+1 -1
@@ -42,7 +42,6 @@ router.post('/caption-image', jsonParser, async (request, response) => {
42 'anthropic-version': '2023-06-01',42 'anthropic-version': '2023-06-01',
43 'x-api-key': request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.CLAUDE),43 'x-api-key': request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.CLAUDE),
44 },44 },
45 timeout: 0,
46 });45 });
4746
48 if (!result.ok) {47 if (!result.ok) {
@@ -51,6 +50,7 @@ router.post('/caption-image', jsonParser, async (request, response) => {
51 return response.status(result.status).send({ error: true });50 return response.status(result.status).send({ error: true });
52 }51 }
5352
53 /** @type {any} */
54 const generateResponseJson = await result.json();54 const generateResponseJson = await result.json();
55 const caption = generateResponseJson.content[0].text;55 const caption = generateResponseJson.content[0].text;
56 console.log('Claude response:', generateResponseJson);56 console.log('Claude response:', generateResponseJson);
src/endpoints/backends/chat-completions.js+5 -4
@@ -152,7 +152,6 @@ async function sendClaudeRequest(request, response) {
152 'x-api-key': apiKey,152 'x-api-key': apiKey,
153 ...additionalHeaders,153 ...additionalHeaders,
154 },154 },
155 timeout: 0,
156 });155 });
157156
158 if (request.body.stream) {157 if (request.body.stream) {
@@ -165,6 +164,7 @@ async function sendClaudeRequest(request, response) {
165 return response.status(generateResponse.status).send({ error: true });164 return response.status(generateResponse.status).send({ error: true });
166 }165 }
167166
167 /** @type {any} */
168 const generateResponseJson = await generateResponse.json();168 const generateResponseJson = await generateResponse.json();
169 const responseText = generateResponseJson?.content?.[0]?.text || '';169 const responseText = generateResponseJson?.content?.[0]?.text || '';
170 console.log('Claude response:', generateResponseJson);170 console.log('Claude response:', generateResponseJson);
@@ -212,7 +212,6 @@ async function sendScaleRequest(request, response) {
212 'Content-Type': 'application/json',212 'Content-Type': 'application/json',
213 'Authorization': `Basic ${apiKey}`,213 'Authorization': `Basic ${apiKey}`,
214 },214 },
215 timeout: 0,
216 });215 });
217216
218 if (!generateResponse.ok) {217 if (!generateResponse.ok) {
@@ -220,6 +219,7 @@ async function sendScaleRequest(request, response) {
220 return response.status(500).send({ error: true });219 return response.status(500).send({ error: true });
221 }220 }
222221
222 /** @type {any} */
223 const generateResponseJson = await generateResponse.json();223 const generateResponseJson = await generateResponse.json();
224 console.log('Scale response:', generateResponseJson);224 console.log('Scale response:', generateResponseJson);
225225
@@ -335,7 +335,6 @@ async function sendMakerSuiteRequest(request, response) {
335 'Content-Type': 'application/json',335 'Content-Type': 'application/json',
336 },336 },
337 signal: controller.signal,337 signal: controller.signal,
338 timeout: 0,
339 });338 });
340 // have to do this because of their busted ass streaming endpoint339 // have to do this because of their busted ass streaming endpoint
341 if (stream) {340 if (stream) {
@@ -354,6 +353,7 @@ async function sendMakerSuiteRequest(request, response) {
354 return response.status(generateResponse.status).send({ error: true });353 return response.status(generateResponse.status).send({ error: true });
355 }354 }
356355
356 /** @type {any} */
357 const generateResponseJson = await generateResponse.json();357 const generateResponseJson = await generateResponse.json();
358358
359 const candidates = generateResponseJson?.candidates;359 const candidates = generateResponseJson?.candidates;
@@ -676,6 +676,7 @@ router.post('/status', jsonParser, async function (request, response_getstatus_o
676 });676 });
677677
678 if (response.ok) {678 if (response.ok) {
679 /** @type {any} */
679 const data = await response.json();680 const data = await response.json();
680 response_getstatus_openai.send(data);681 response_getstatus_openai.send(data);
681682
@@ -979,7 +980,6 @@ router.post('/generate', jsonParser, function (request, response) {
979 },980 },
980 body: JSON.stringify(requestBody),981 body: JSON.stringify(requestBody),
981 signal: controller.signal,982 signal: controller.signal,
982 timeout: 0,
983 };983 };
984984
985 console.log(requestBody);985 console.log(requestBody);
@@ -1005,6 +1005,7 @@ router.post('/generate', jsonParser, function (request, response) {
1005 }1005 }
10061006
1007 if (fetchResponse.ok) {1007 if (fetchResponse.ok) {
1008 /** @type {any} */
1008 let json = await fetchResponse.json();1009 let json = await fetchResponse.json();
1009 response.send(json);1010 response.send(json);
1010 console.log(json);1011 console.log(json);
src/endpoints/backends/kobold.js+2 -1
@@ -96,7 +96,7 @@ router.post('/generate', jsonParser, async function (request, response_generate)
96 for (let i = 0; i < MAX_RETRIES; i++) {96 for (let i = 0; i < MAX_RETRIES; i++) {
97 try {97 try {
98 const url = request.body.streaming ? `${request.body.api_server}/extra/generate/stream` : `${request.body.api_server}/v1/generate`;98 const url = request.body.streaming ? `${request.body.api_server}/extra/generate/stream` : `${request.body.api_server}/v1/generate`;
99 const response = await fetch(url, { method: 'POST', timeout: 0, ...args });99 const response = await fetch(url, { method: 'POST', ...args });
100100
101 if (request.body.streaming) {101 if (request.body.streaming) {
102 // Pipe remote SSE stream to Express response102 // Pipe remote SSE stream to Express response
@@ -156,6 +156,7 @@ router.post('/status', jsonParser, async function (request, response) {
156156
157 const result = {};157 const result = {};
158158
159 /** @type {any} */
159 const [koboldUnitedResponse, koboldExtraResponse, koboldModelResponse] = await Promise.all([160 const [koboldUnitedResponse, koboldExtraResponse, koboldModelResponse] = await Promise.all([
160 // We catch errors both from the response not having a successful HTTP status and from JSON parsing failing161 // We catch errors both from the response not having a successful HTTP status and from JSON parsing failing
161162
src/endpoints/backends/scale-alt.js+1 -1
@@ -70,7 +70,6 @@ router.post('/generate', jsonParser, async function (request, response) {
70 'Content-Type': 'application/json',70 'Content-Type': 'application/json',
71 'cookie': `_jwt=${cookie}`,71 'cookie': `_jwt=${cookie}`,
72 },72 },
73 timeout: 0,
74 body: JSON.stringify(body),73 body: JSON.stringify(body),
75 });74 });
7675
@@ -80,6 +79,7 @@ router.post('/generate', jsonParser, async function (request, response) {
80 return response.status(500).send({ error: { message: result.statusText } });79 return response.status(500).send({ error: { message: result.statusText } });
81 }80 }
8281
82 /** @type {any} */
83 const data = await result.json();83 const data = await result.json();
84 const output = data?.result?.data?.json?.outputs?.[0] || '';84 const output = data?.result?.data?.json?.outputs?.[0] || '';
8585
src/endpoints/backends/text-completions.js+11 -6
@@ -28,6 +28,10 @@ export const router = express.Router();
28 */28 */
29async function parseOllamaStream(jsonStream, request, response) {29async function parseOllamaStream(jsonStream, request, response) {
30 try {30 try {
31 if (!jsonStream.body) {
32 throw new Error('No body in the response');
33 }
34
31 let partialData = '';35 let partialData = '';
32 jsonStream.body.on('data', (data) => {36 jsonStream.body.on('data', (data) => {
33 const chunk = data.toString();37 const chunk = data.toString();
@@ -153,6 +157,7 @@ router.post('/status', jsonParser, async function (request, response) {
153 return response.status(400);157 return response.status(400);
154 }158 }
155159
160 /** @type {any} */
156 let data = await modelsReply.json();161 let data = await modelsReply.json();
157162
158 if (request.body.legacy_api) {163 if (request.body.legacy_api) {
@@ -190,6 +195,7 @@ router.post('/status', jsonParser, async function (request, response) {
190 const modelInfoReply = await fetch(modelInfoUrl, args);195 const modelInfoReply = await fetch(modelInfoUrl, args);
191196
192 if (modelInfoReply.ok) {197 if (modelInfoReply.ok) {
198 /** @type {any} */
193 const modelInfo = await modelInfoReply.json();199 const modelInfo = await modelInfoReply.json();
194 console.log('Ooba model info:', modelInfo);200 console.log('Ooba model info:', modelInfo);
195201
@@ -206,6 +212,7 @@ router.post('/status', jsonParser, async function (request, response) {
206 const modelInfoReply = await fetch(modelInfoUrl, args);212 const modelInfoReply = await fetch(modelInfoUrl, args);
207213
208 if (modelInfoReply.ok) {214 if (modelInfoReply.ok) {
215 /** @type {any} */
209 const modelInfo = await modelInfoReply.json();216 const modelInfo = await modelInfoReply.json();
210 console.log('Tabby model info:', modelInfo);217 console.log('Tabby model info:', modelInfo);
211218
@@ -359,6 +366,7 @@ router.post('/generate', jsonParser, async function (request, response) {
359 const completionsReply = await fetch(url, args);366 const completionsReply = await fetch(url, args);
360367
361 if (completionsReply.ok) {368 if (completionsReply.ok) {
369 /** @type {any} */
362 const data = await completionsReply.json();370 const data = await completionsReply.json();
363 console.log('Endpoint response:', data);371 console.log('Endpoint response:', data);
364372
@@ -415,7 +423,6 @@ ollama.post('/download', jsonParser, async function (request, response) {
415 name: name,423 name: name,
416 stream: false,424 stream: false,
417 }),425 }),
418 timeout: 0,
419 });426 });
420427
421 if (!fetchResponse.ok) {428 if (!fetchResponse.ok) {
@@ -448,7 +455,6 @@ ollama.post('/caption-image', jsonParser, async function (request, response) {
448 images: [request.body.image],455 images: [request.body.image],
449 stream: false,456 stream: false,
450 }),457 }),
451 timeout: 0,
452 });458 });
453459
454 if (!fetchResponse.ok) {460 if (!fetchResponse.ok) {
@@ -456,6 +462,7 @@ ollama.post('/caption-image', jsonParser, async function (request, response) {
456 return response.status(500).send({ error: true });462 return response.status(500).send({ error: true });
457 }463 }
458464
465 /** @type {any} */
459 const data = await fetchResponse.json();466 const data = await fetchResponse.json();
460 console.log('Ollama caption response:', data);467 console.log('Ollama caption response:', data);
461468
@@ -487,7 +494,6 @@ llamacpp.post('/caption-image', jsonParser, async function (request, response) {
487 const fetchResponse = await fetch(`${baseUrl}/completion`, {494 const fetchResponse = await fetch(`${baseUrl}/completion`, {
488 method: 'POST',495 method: 'POST',
489 headers: { 'Content-Type': 'application/json' },496 headers: { 'Content-Type': 'application/json' },
490 timeout: 0,
491 body: JSON.stringify({497 body: JSON.stringify({
492 prompt: `USER:[img-1]${String(request.body.prompt).trim()}\nASSISTANT:`,498 prompt: `USER:[img-1]${String(request.body.prompt).trim()}\nASSISTANT:`,
493 image_data: [{ data: request.body.image, id: 1 }],499 image_data: [{ data: request.body.image, id: 1 }],
@@ -502,6 +508,7 @@ llamacpp.post('/caption-image', jsonParser, async function (request, response) {
502 return response.status(500).send({ error: true });508 return response.status(500).send({ error: true });
503 }509 }
504510
511 /** @type {any} */
505 const data = await fetchResponse.json();512 const data = await fetchResponse.json();
506 console.log('LlamaCpp caption response:', data);513 console.log('LlamaCpp caption response:', data);
507514
@@ -531,7 +538,6 @@ llamacpp.post('/props', jsonParser, async function (request, response) {
531538
532 const fetchResponse = await fetch(`${baseUrl}/props`, {539 const fetchResponse = await fetch(`${baseUrl}/props`, {
533 method: 'GET',540 method: 'GET',
534 timeout: 0,
535 });541 });
536542
537 if (!fetchResponse.ok) {543 if (!fetchResponse.ok) {
@@ -566,7 +572,6 @@ llamacpp.post('/slots', jsonParser, async function (request, response) {
566 if (request.body.action === 'info') {572 if (request.body.action === 'info') {
567 fetchResponse = await fetch(`${baseUrl}/slots`, {573 fetchResponse = await fetch(`${baseUrl}/slots`, {
568 method: 'GET',574 method: 'GET',
569 timeout: 0,
570 });575 });
571 } else {576 } else {
572 if (!/^\d+$/.test(request.body.id_slot)) {577 if (!/^\d+$/.test(request.body.id_slot)) {
@@ -579,7 +584,6 @@ llamacpp.post('/slots', jsonParser, async function (request, response) {
579 fetchResponse = await fetch(`${baseUrl}/slots/${request.body.id_slot}?action=${request.body.action}`, {584 fetchResponse = await fetch(`${baseUrl}/slots/${request.body.id_slot}?action=${request.body.action}`, {
580 method: 'POST',585 method: 'POST',
581 headers: { 'Content-Type': 'application/json' },586 headers: { 'Content-Type': 'application/json' },
582 timeout: 0,
583 body: JSON.stringify({587 body: JSON.stringify({
584 filename: request.body.action !== 'erase' ? `${request.body.filename}` : undefined,588 filename: request.body.action !== 'erase' ? `${request.body.filename}` : undefined,
585 }),589 }),
@@ -623,6 +627,7 @@ tabby.post('/download', jsonParser, async function (request, response) {
623 });627 });
624628
625 if (permissionResponse.ok) {629 if (permissionResponse.ok) {
630 /** @type {any} */
626 const permissionJson = await permissionResponse.json();631 const permissionJson = await permissionResponse.json();
627632
628 if (permissionJson['permission'] !== 'admin') {633 if (permissionJson['permission'] !== 'admin') {
src/endpoints/content-manager.js+2 -0
@@ -380,6 +380,7 @@ async function downloadPygmalionCharacter(id) {
380 throw new Error('Failed to download character');380 throw new Error('Failed to download character');
381 }381 }
382382
383 /** @type {any} */
383 const jsonData = await result.json();384 const jsonData = await result.json();
384 const characterData = jsonData?.character;385 const characterData = jsonData?.character;
385386
@@ -472,6 +473,7 @@ async function downloadJannyCharacter(uuid) {
472 });473 });
473474
474 if (result.ok) {475 if (result.ok) {
476 /** @type {any} */
475 const downloadResult = await result.json();477 const downloadResult = await result.json();
476 if (downloadResult.status === 'ok') {478 if (downloadResult.status === 'ok') {
477 const imageResult = await fetch(downloadResult.downloadUrl);479 const imageResult = await fetch(downloadResult.downloadUrl);
src/endpoints/google.js+1 -1
@@ -40,7 +40,6 @@ router.post('/caption-image', jsonParser, async (request, response) => {
40 headers: {40 headers: {
41 'Content-Type': 'application/json',41 'Content-Type': 'application/json',
42 },42 },
43 timeout: 0,
44 });43 });
4544
46 if (!result.ok) {45 if (!result.ok) {
@@ -49,6 +48,7 @@ router.post('/caption-image', jsonParser, async (request, response) => {
49 return response.status(result.status).send({ error: true });48 return response.status(result.status).send({ error: true });
50 }49 }
5150
51 /** @type {any} */
52 const data = await result.json();52 const data = await result.json();
53 console.log('Multimodal captioning response', data);53 console.log('Multimodal captioning response', data);
5454
src/endpoints/images.js+1 -1
@@ -68,7 +68,7 @@ router.post('/upload', jsonParser, async (request, response) => {
6868
69 ensureDirectoryExistence(pathToNewFile);69 ensureDirectoryExistence(pathToNewFile);
70 const imageBuffer = Buffer.from(base64Data, 'base64');70 const imageBuffer = Buffer.from(base64Data, 'base64');
71 await fs.promises.writeFile(pathToNewFile, imageBuffer);71 await fs.promises.writeFile(pathToNewFile, new Uint8Array(imageBuffer));
72 response.send({ path: clientRelativePath(request.user.directories.root, pathToNewFile) });72 response.send({ path: clientRelativePath(request.user.directories.root, pathToNewFile) });
73 } catch (error) {73 } catch (error) {
74 console.log(error);74 console.log(error);
src/endpoints/novelai.js+3 -3
@@ -252,7 +252,7 @@ router.post('/generate', jsonParser, async function (req, res) {
252 try {252 try {
253 const baseURL = (req.body.model.includes('kayra') || req.body.model.includes('erato')) ? TEXT_NOVELAI : API_NOVELAI;253 const baseURL = (req.body.model.includes('kayra') || req.body.model.includes('erato')) ? TEXT_NOVELAI : API_NOVELAI;
254 const url = req.body.streaming ? `${baseURL}/ai/generate-stream` : `${baseURL}/ai/generate`;254 const url = req.body.streaming ? `${baseURL}/ai/generate-stream` : `${baseURL}/ai/generate`;
255 const response = await fetch(url, { method: 'POST', timeout: 0, ...args });255 const response = await fetch(url, { method: 'POST', ...args });
256256
257 if (req.body.streaming) {257 if (req.body.streaming) {
258 // Pipe remote SSE stream to Express response258 // Pipe remote SSE stream to Express response
@@ -274,6 +274,7 @@ router.post('/generate', jsonParser, async function (req, res) {
274 return res.status(response.status).send({ error: { message } });274 return res.status(response.status).send({ error: { message } });
275 }275 }
276276
277 /** @type {any} */
277 const data = await response.json();278 const data = await response.json();
278 console.log('NovelAI Output', data?.output);279 console.log('NovelAI Output', data?.output);
279 return res.send(data);280 return res.send(data);
@@ -416,7 +417,6 @@ router.post('/generate-voice', jsonParser, async (request, response) => {
416 'Authorization': `Bearer ${token}`,417 'Authorization': `Bearer ${token}`,
417 'Accept': 'audio/mpeg',418 'Accept': 'audio/mpeg',
418 },419 },
419 timeout: 0,
420 });420 });
421421
422 if (!result.ok) {422 if (!result.ok) {
@@ -426,7 +426,7 @@ router.post('/generate-voice', jsonParser, async (request, response) => {
426 }426 }
427427
428 const chunks = await readAllChunks(result.body);428 const chunks = await readAllChunks(result.body);
429 const buffer = Buffer.concat(chunks);429 const buffer = Buffer.concat(chunks.map(chunk => new Uint8Array(chunk)));
430 response.setHeader('Content-Type', 'audio/mpeg');430 response.setHeader('Content-Type', 'audio/mpeg');
431 return response.send(buffer);431 return response.send(buffer);
432 }432 }
src/endpoints/openai.js+1 -2
@@ -154,7 +154,6 @@ router.post('/caption-image', jsonParser, async (request, response) => {
154 ...headers,154 ...headers,
155 },155 },
156 body: JSON.stringify(body),156 body: JSON.stringify(body),
157 timeout: 0,
158 });157 });
159158
160 if (!result.ok) {159 if (!result.ok) {
@@ -163,6 +162,7 @@ router.post('/caption-image', jsonParser, async (request, response) => {
163 return response.status(500).send(text);162 return response.status(500).send(text);
164 }163 }
165164
165 /** @type {any} */
166 const data = await result.json();166 const data = await result.json();
167 console.log('Multimodal captioning response', data);167 console.log('Multimodal captioning response', data);
168 const caption = data?.choices[0]?.message?.content;168 const caption = data?.choices[0]?.message?.content;
@@ -284,7 +284,6 @@ router.post('/generate-image', jsonParser, async (request, response) => {
284 Authorization: `Bearer ${key}`,284 Authorization: `Bearer ${key}`,
285 },285 },
286 body: JSON.stringify(request.body),286 body: JSON.stringify(request.body),
287 timeout: 0,
288 });287 });
289288
290 if (!result.ok) {289 if (!result.ok) {
src/endpoints/stable-diffusion.js+20 -6
@@ -65,6 +65,7 @@ router.post('/upscalers', jsonParser, async (request, response) => {
65 throw new Error('SD WebUI returned an error.');65 throw new Error('SD WebUI returned an error.');
66 }66 }
6767
68 /** @type {any} */
68 const data = await result.json();69 const data = await result.json();
69 const names = data.map(x => x.name);70 const names = data.map(x => x.name);
70 return names;71 return names;
@@ -85,6 +86,7 @@ router.post('/upscalers', jsonParser, async (request, response) => {
85 throw new Error('SD WebUI returned an error.');86 throw new Error('SD WebUI returned an error.');
86 }87 }
8788
89 /** @type {any} */
88 const data = await result.json();90 const data = await result.json();
89 const names = data.map(x => x.name);91 const names = data.map(x => x.name);
90 return names;92 return names;
@@ -118,6 +120,7 @@ router.post('/vaes', jsonParser, async (request, response) => {
118 throw new Error('SD WebUI returned an error.');120 throw new Error('SD WebUI returned an error.');
119 }121 }
120122
123 /** @type {any} */
121 const data = await result.json();124 const data = await result.json();
122 const names = data.map(x => x.model_name);125 const names = data.map(x => x.model_name);
123 return response.send(names);126 return response.send(names);
@@ -143,6 +146,7 @@ router.post('/samplers', jsonParser, async (request, response) => {
143 throw new Error('SD WebUI returned an error.');146 throw new Error('SD WebUI returned an error.');
144 }147 }
145148
149 /** @type {any} */
146 const data = await result.json();150 const data = await result.json();
147 const names = data.map(x => x.name);151 const names = data.map(x => x.name);
148 return response.send(names);152 return response.send(names);
@@ -169,6 +173,7 @@ router.post('/schedulers', jsonParser, async (request, response) => {
169 throw new Error('SD WebUI returned an error.');173 throw new Error('SD WebUI returned an error.');
170 }174 }
171175
176 /** @type {any} */
172 const data = await result.json();177 const data = await result.json();
173 const names = data.map(x => x.name);178 const names = data.map(x => x.name);
174 return response.send(names);179 return response.send(names);
@@ -194,6 +199,7 @@ router.post('/models', jsonParser, async (request, response) => {
194 throw new Error('SD WebUI returned an error.');199 throw new Error('SD WebUI returned an error.');
195 }200 }
196201
202 /** @type {any} */
197 const data = await result.json();203 const data = await result.json();
198 const models = data.map(x => ({ value: x.title, text: x.title }));204 const models = data.map(x => ({ value: x.title, text: x.title }));
199 return response.send(models);205 return response.send(models);
@@ -214,6 +220,7 @@ router.post('/get-model', jsonParser, async (request, response) => {
214 'Authorization': getBasicAuthHeader(request.body.auth),220 'Authorization': getBasicAuthHeader(request.body.auth),
215 },221 },
216 });222 });
223 /** @type {any} */
217 const data = await result.json();224 const data = await result.json();
218 return response.send(data['sd_model_checkpoint']);225 return response.send(data['sd_model_checkpoint']);
219 } catch (error) {226 } catch (error) {
@@ -233,7 +240,6 @@ router.post('/set-model', jsonParser, async (request, response) => {
233 headers: {240 headers: {
234 'Authorization': getBasicAuthHeader(request.body.auth),241 'Authorization': getBasicAuthHeader(request.body.auth),
235 },242 },
236 timeout: 0,
237 });243 });
238 const data = await result.json();244 const data = await result.json();
239 return data;245 return data;
@@ -253,7 +259,6 @@ router.post('/set-model', jsonParser, async (request, response) => {
253 'Content-Type': 'application/json',259 'Content-Type': 'application/json',
254 'Authorization': getBasicAuthHeader(request.body.auth),260 'Authorization': getBasicAuthHeader(request.body.auth),
255 },261 },
256 timeout: 0,
257 });262 });
258263
259 if (!result.ok) {264 if (!result.ok) {
@@ -264,6 +269,7 @@ router.post('/set-model', jsonParser, async (request, response) => {
264 const CHECK_INTERVAL = 2000;269 const CHECK_INTERVAL = 2000;
265270
266 for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {271 for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
272 /** @type {any} */
267 const progressState = await getProgress();273 const progressState = await getProgress();
268274
269 const progress = progressState['progress'];275 const progress = progressState['progress'];
@@ -308,8 +314,6 @@ router.post('/generate', jsonParser, async (request, response) => {
308 'Content-Type': 'application/json',314 'Content-Type': 'application/json',
309 'Authorization': getBasicAuthHeader(request.body.auth),315 'Authorization': getBasicAuthHeader(request.body.auth),
310 },316 },
311 timeout: 0,
312 // @ts-ignore
313 signal: controller.signal,317 signal: controller.signal,
314 });318 });
315319
@@ -345,6 +349,7 @@ router.post('/sd-next/upscalers', jsonParser, async (request, response) => {
345 // Vlad doesn't provide Latent Upscalers in the API, so we have to hardcode them here349 // Vlad doesn't provide Latent Upscalers in the API, so we have to hardcode them here
346 const latentUpscalers = ['Latent', 'Latent (antialiased)', 'Latent (bicubic)', 'Latent (bicubic antialiased)', 'Latent (nearest)', 'Latent (nearest-exact)'];350 const latentUpscalers = ['Latent', 'Latent (antialiased)', 'Latent (bicubic)', 'Latent (bicubic antialiased)', 'Latent (nearest)', 'Latent (nearest-exact)'];
347351
352 /** @type {any} */
348 const data = await result.json();353 const data = await result.json();
349 const names = data.map(x => x.name);354 const names = data.map(x => x.name);
350355
@@ -387,6 +392,7 @@ comfy.post('/samplers', jsonParser, async (request, response) => {
387 throw new Error('ComfyUI returned an error.');392 throw new Error('ComfyUI returned an error.');
388 }393 }
389394
395 /** @type {any} */
390 const data = await result.json();396 const data = await result.json();
391 return response.send(data.KSampler.input.required.sampler_name[0]);397 return response.send(data.KSampler.input.required.sampler_name[0]);
392 } catch (error) {398 } catch (error) {
@@ -404,6 +410,7 @@ comfy.post('/models', jsonParser, async (request, response) => {
404 if (!result.ok) {410 if (!result.ok) {
405 throw new Error('ComfyUI returned an error.');411 throw new Error('ComfyUI returned an error.');
406 }412 }
413 /** @type {any} */
407 const data = await result.json();414 const data = await result.json();
408 return response.send(data.CheckpointLoaderSimple.input.required.ckpt_name[0].map(it => ({ value: it, text: it })));415 return response.send(data.CheckpointLoaderSimple.input.required.ckpt_name[0].map(it => ({ value: it, text: it })));
409 } catch (error) {416 } catch (error) {
@@ -422,6 +429,7 @@ comfy.post('/schedulers', jsonParser, async (request, response) => {
422 throw new Error('ComfyUI returned an error.');429 throw new Error('ComfyUI returned an error.');
423 }430 }
424431
432 /** @type {any} */
425 const data = await result.json();433 const data = await result.json();
426 return response.send(data.KSampler.input.required.scheduler[0]);434 return response.send(data.KSampler.input.required.scheduler[0]);
427 } catch (error) {435 } catch (error) {
@@ -440,6 +448,7 @@ comfy.post('/vaes', jsonParser, async (request, response) => {
440 throw new Error('ComfyUI returned an error.');448 throw new Error('ComfyUI returned an error.');
441 }449 }
442450
451 /** @type {any} */
443 const data = await result.json();452 const data = await result.json();
444 return response.send(data.VAELoader.input.required.vae_name[0]);453 return response.send(data.VAELoader.input.required.vae_name[0]);
445 } catch (error) {454 } catch (error) {
@@ -521,6 +530,7 @@ comfy.post('/generate', jsonParser, async (request, response) => {
521 throw new Error('ComfyUI returned an error.');530 throw new Error('ComfyUI returned an error.');
522 }531 }
523532
533 /** @type {any} */
524 const data = await promptResult.json();534 const data = await promptResult.json();
525 const id = data.prompt_id;535 const id = data.prompt_id;
526 let item;536 let item;
@@ -531,6 +541,7 @@ comfy.post('/generate', jsonParser, async (request, response) => {
531 if (!result.ok) {541 if (!result.ok) {
532 throw new Error('ComfyUI returned an error.');542 throw new Error('ComfyUI returned an error.');
533 }543 }
544 /** @type {any} */
534 const history = await result.json();545 const history = await result.json();
535 item = history[id];546 item = history[id];
536 if (item) {547 if (item) {
@@ -633,6 +644,7 @@ together.post('/generate', jsonParser, async (request, response) => {
633 return response.sendStatus(500);644 return response.sendStatus(500);
634 }645 }
635646
647 /** @type {any} */
636 const data = await result.json();648 const data = await result.json();
637 console.log('TogetherAI response:', data);649 console.log('TogetherAI response:', data);
638650
@@ -681,6 +693,8 @@ drawthings.post('/get-model', jsonParser, async (request, response) => {
681 const result = await fetch(url, {693 const result = await fetch(url, {
682 method: 'GET',694 method: 'GET',
683 });695 });
696
697 /** @type {any} */
684 const data = await result.json();698 const data = await result.json();
685699
686 return response.send(data['model']);700 return response.send(data['model']);
@@ -698,6 +712,8 @@ drawthings.post('/get-upscaler', jsonParser, async (request, response) => {
698 const result = await fetch(url, {712 const result = await fetch(url, {
699 method: 'GET',713 method: 'GET',
700 });714 });
715
716 /** @type {any} */
701 const data = await result.json();717 const data = await result.json();
702718
703 return response.send(data['upscaler']);719 return response.send(data['upscaler']);
@@ -726,7 +742,6 @@ drawthings.post('/generate', jsonParser, async (request, response) => {
726 'Content-Type': 'application/json',742 'Content-Type': 'application/json',
727 'Authorization': auth,743 'Authorization': auth,
728 },744 },
729 timeout: 0,
730 });745 });
731746
732 if (!result.ok) {747 if (!result.ok) {
@@ -848,7 +863,6 @@ stability.post('/generate', jsonParser, async (request, response) => {
848 'Accept': 'image/*',863 'Accept': 'image/*',
849 },864 },
850 body: formData,865 body: formData,
851 timeout: 0,
852 });866 });
853867
854 if (!result.ok) {868 if (!result.ok) {
src/endpoints/translate.js+5 -4
@@ -78,6 +78,7 @@ router.post('/libre', jsonParser, async (request, response) => {
78 return response.sendStatus(result.status);78 return response.sendStatus(result.status);
79 }79 }
8080
81 /** @type {any} */
81 const json = await result.json();82 const json = await result.json();
82 console.log('Translated text: ' + json.translatedText);83 console.log('Translated text: ' + json.translatedText);
8384
@@ -158,7 +159,6 @@ router.post('/yandex', jsonParser, async (request, response) => {
158 headers: {159 headers: {
159 'Content-Type': 'application/x-www-form-urlencoded',160 'Content-Type': 'application/x-www-form-urlencoded',
160 },161 },
161 timeout: 0,
162 });162 });
163163
164 if (!result.ok) {164 if (!result.ok) {
@@ -167,6 +167,7 @@ router.post('/yandex', jsonParser, async (request, response) => {
167 return response.sendStatus(500);167 return response.sendStatus(500);
168 }168 }
169169
170 /** @type {any} */
170 const json = await result.json();171 const json = await result.json();
171 const translated = json.text.join();172 const translated = json.text.join();
172 console.log('Translated text: ' + translated);173 console.log('Translated text: ' + translated);
@@ -264,7 +265,6 @@ router.post('/deepl', jsonParser, async (request, response) => {
264 'Authorization': `DeepL-Auth-Key ${key}`,265 'Authorization': `DeepL-Auth-Key ${key}`,
265 'Content-Type': 'application/x-www-form-urlencoded',266 'Content-Type': 'application/x-www-form-urlencoded',
266 },267 },
267 timeout: 0,
268 });268 });
269269
270 if (!result.ok) {270 if (!result.ok) {
@@ -273,6 +273,7 @@ router.post('/deepl', jsonParser, async (request, response) => {
273 return response.sendStatus(result.status);273 return response.sendStatus(result.status);
274 }274 }
275275
276 /** @type {any} */
276 const json = await result.json();277 const json = await result.json();
277 console.log('Translated text: ' + json.translations[0].text);278 console.log('Translated text: ' + json.translations[0].text);
278279
@@ -317,7 +318,6 @@ router.post('/onering', jsonParser, async (request, response) => {
317318
318 const result = await fetch(fetchUrl, {319 const result = await fetch(fetchUrl, {
319 method: 'GET',320 method: 'GET',
320 timeout: 0,
321 });321 });
322322
323 if (!result.ok) {323 if (!result.ok) {
@@ -326,6 +326,7 @@ router.post('/onering', jsonParser, async (request, response) => {
326 return response.sendStatus(result.status);326 return response.sendStatus(result.status);
327 }327 }
328328
329 /** @type {any} */
329 const data = await result.json();330 const data = await result.json();
330 console.log('Translated text: ' + data.result);331 console.log('Translated text: ' + data.result);
331332
@@ -373,7 +374,6 @@ router.post('/deeplx', jsonParser, async (request, response) => {
373 'Accept': 'application/json',374 'Accept': 'application/json',
374 'Content-Type': 'application/json',375 'Content-Type': 'application/json',
375 },376 },
376 timeout: 0,
377 });377 });
378378
379 if (!result.ok) {379 if (!result.ok) {
@@ -382,6 +382,7 @@ router.post('/deeplx', jsonParser, async (request, response) => {
382 return response.sendStatus(result.status);382 return response.sendStatus(result.status);
383 }383 }
384384
385 /** @type {any} */
385 const json = await result.json();386 const json = await result.json();
386 console.log('Translated text: ' + json.data);387 console.log('Translated text: ' + json.data);
387388
src/transformers.mjs+3 -2
@@ -3,7 +3,7 @@ import fs from 'node:fs';
3import process from 'node:process';3import process from 'node:process';
4import { Buffer } from 'node:buffer';4import { Buffer } from 'node:buffer';
55
6import { pipeline, env, RawImage, Pipeline } from 'sillytavern-transformers';6import { pipeline, env, RawImage } from 'sillytavern-transformers';
7import { getConfigValue } from './util.js';7import { getConfigValue } from './util.js';
88
9configureTransformers();9configureTransformers();
@@ -117,7 +117,7 @@ async function migrateCacheToDataDir() {
117 * Gets the transformers.js pipeline for a given task.117 * Gets the transformers.js pipeline for a given task.
118 * @param {import('sillytavern-transformers').PipelineType} task The task to get the pipeline for118 * @param {import('sillytavern-transformers').PipelineType} task The task to get the pipeline for
119 * @param {string} forceModel The model to use for the pipeline, if any119 * @param {string} forceModel The model to use for the pipeline, if any
120 * @returns {Promise<Pipeline>} Pipeline for the task120 * @returns {Promise<import('sillytavern-transformers').Pipeline>} The transformers.js pipeline
121 */121 */
122export async function getPipeline(task, forceModel = '') {122export async function getPipeline(task, forceModel = '') {
123 await migrateCacheToDataDir();123 await migrateCacheToDataDir();
@@ -137,6 +137,7 @@ export async function getPipeline(task, forceModel = '') {
137 const instance = await pipeline(task, model, { cache_dir: cacheDir, quantized: tasks[task].quantized ?? true, local_files_only: localOnly });137 const instance = await pipeline(task, model, { cache_dir: cacheDir, quantized: tasks[task].quantized ?? true, local_files_only: localOnly });
138 tasks[task].pipeline = instance;138 tasks[task].pipeline = instance;
139 tasks[task].currentModel = model;139 tasks[task].currentModel = model;
140 // @ts-ignore
140 return instance;141 return instance;
141}142}
142143
src/util.js+12 -8
@@ -441,17 +441,21 @@ export function forwardFetchResponse(from, to) {
441 to.statusCode = statusCode;441 to.statusCode = statusCode;
442 to.statusMessage = statusText;442 to.statusMessage = statusText;
443443
444 from.body.pipe(to);444 if (from.body && to.socket) {
445 from.body.pipe(to);
445446
446 to.socket.on('close', function () {447 to.socket.on('close', function () {
447 if (from.body instanceof Readable) from.body.destroy(); // Close the remote stream448 if (from.body instanceof Readable) from.body.destroy(); // Close the remote stream
448 to.end(); // End the Express response449 to.end(); // End the Express response
449 });450 });
450451
451 from.body.on('end', function () {452 from.body.on('end', function () {
452 console.log('Streaming request finished');453 console.log('Streaming request finished');
454 to.end();
455 });
456 } else {
453 to.end();457 to.end();
454 });458 }
455}459}
456460
457/**461/**
src/vectors/cohere-vectors.js+1 -0
@@ -38,6 +38,7 @@ export async function getCohereBatchVector(texts, isQuery, directories, model) {
38 throw new Error('API request failed');38 throw new Error('API request failed');
39 }39 }
4040
41 /** @type {any} */
41 const data = await response.json();42 const data = await response.json();
42 if (!Array.isArray(data?.embeddings?.float)) {43 if (!Array.isArray(data?.embeddings?.float)) {
43 console.log('API response was not an array');44 console.log('API response was not an array');
src/vectors/extras-vectors.js+1 -0
@@ -66,6 +66,7 @@ async function getExtrasVectorImpl(text, apiUrl, apiKey) {
66 throw new Error('Extras request failed');66 throw new Error('Extras request failed');
67 }67 }
6868
69 /** @type {any} */
69 const data = await response.json();70 const data = await response.json();
70 const vector = data.embedding; // `embedding`: number[] (one text item), or number[][] (multiple text items).71 const vector = data.embedding; // `embedding`: number[] (one text item), or number[][] (multiple text items).
7172
src/vectors/llamacpp-vectors.js+1 -0
@@ -30,6 +30,7 @@ export async function getLlamaCppBatchVector(texts, apiUrl, directories) {
30 throw new Error(`LlamaCpp: Failed to get vector for text: ${response.statusText} ${responseText}`);30 throw new Error(`LlamaCpp: Failed to get vector for text: ${response.statusText} ${responseText}`);
31 }31 }
3232
33 /** @type {any} */
33 const data = await response.json();34 const data = await response.json();
3435
35 if (!Array.isArray(data?.data)) {36 if (!Array.isArray(data?.data)) {
src/vectors/makersuite-vectors.js+1 -0
@@ -52,6 +52,7 @@ export async function getMakerSuiteVector(text, directories) {
52 throw new Error('Google AI Studio request failed');52 throw new Error('Google AI Studio request failed');
53 }53 }
5454
55 /** @type {any} */
55 const data = await response.json();56 const data = await response.json();
56 // noinspection JSValidateTypes57 // noinspection JSValidateTypes
57 return data['embedding']['values'];58 return data['embedding']['values'];
src/vectors/nomicai-vectors.js+1 -0
@@ -51,6 +51,7 @@ export async function getNomicAIBatchVector(texts, source, directories) {
51 throw new Error('API request failed');51 throw new Error('API request failed');
52 }52 }
5353
54 /** @type {any} */
54 const data = await response.json();55 const data = await response.json();
55 if (!Array.isArray(data?.embeddings)) {56 if (!Array.isArray(data?.embeddings)) {
56 console.log('API response was not an array');57 console.log('API response was not an array');
src/vectors/ollama-vectors.js+1 -0
@@ -54,6 +54,7 @@ export async function getOllamaVector(text, apiUrl, model, keep, directories) {
54 throw new Error(`Ollama: Failed to get vector for text: ${response.statusText} ${responseText}`);54 throw new Error(`Ollama: Failed to get vector for text: ${response.statusText} ${responseText}`);
55 }55 }
5656
57 /** @type {any} */
57 const data = await response.json();58 const data = await response.json();
5859
59 if (!Array.isArray(data?.embedding)) {60 if (!Array.isArray(data?.embedding)) {
src/vectors/openai-vectors.js+1 -0
@@ -61,6 +61,7 @@ export async function getOpenAIBatchVector(texts, source, directories, model = '
61 throw new Error('API request failed');61 throw new Error('API request failed');
62 }62 }
6363
64 /** @type {any} */
64 const data = await response.json();65 const data = await response.json();
6566
66 if (!Array.isArray(data?.data)) {67 if (!Array.isArray(data?.data)) {
src/vectors/vllm-vectors.js+1 -0
@@ -31,6 +31,7 @@ export async function getVllmBatchVector(texts, apiUrl, model, directories) {
31 throw new Error(`VLLM: Failed to get vector for text: ${response.statusText} ${responseText}`);31 throw new Error(`VLLM: Failed to get vector for text: ${response.statusText} ${responseText}`);
32 }32 }
3333
34 /** @type {any} */
34 const data = await response.json();35 const data = await response.json();
3536
36 if (!Array.isArray(data?.data)) {37 if (!Array.isArray(data?.data)) {