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