| 382 | 382 | |
| 383 | 383 | /** @type {any} */ |
| 384 | 384 | const metadata = await result.json(); |
| 385 | 385 | const downloadUrl{ definition, topics } = metadata.node?.max_res_url; |
| 386 | + |
| 387 | + /** @type {TavernCardV2} */ |
| 388 | + const characterCard = { |
| 389 | + data: { |
| 390 | + name: definition.name, |
| 391 | + description: definition.personality, |
| 392 | + personality: definition.tavern_personality, |
| 393 | + scenario: definition.scenario, |
| 394 | + first_mes: definition.first_message, |
| 395 | + mes_example: definition.example_dialogs, |
| 396 | + creator_notes: definition.description, |
| 397 | + system_prompt: definition.system_prompt, |
| 398 | + post_history_instructions: definition.post_history_instructions, |
| 399 | + alternate_greetings: definition.alternate_greetings, |
| 400 | + tags: topics, |
| 401 | + creator: creatorName, |
| 402 | + character_version: '', |
| 403 | + character_book: definition.embedded_lorebook, |
| 404 | + extensions: definition.extensions, |
| 405 | + }, |
| 406 | + spec: 'chara_card_v2', |
| 407 | + spec_version: '2.0', |
| 408 | + }; |
| 386 | 409 | |
| 387 | | - if (!downloadUrl) { |
| 410 | + const defaultAvatarPath = path.join(serverDirectory, DEFAULT_AVATAR_PATH); |
| 388 | | - throw new Error('Download URL not found in character metadata'); |
| 411 | + const defaultAvatarBuffer = fs.readFileSync(defaultAvatarPath); |
| 389 | | - } |
| 390 | 412 | |
| 391 | 413 | constlet downloadResultimageBuffer = await fetch(downloadUrl)defaultAvatarBuffer; |
| 392 | 414 | |
| 393 | | - if (!downloadResult.ok) { |
| 415 | + const imageUrl = metadata.node?.max_res_url; |
| 394 | | - const text = await downloadResult.text(); |
| 416 | + |
| 395 | | - console.error('Chub returned error', downloadResult.statusText, text); |
| 417 | + if (imageUrl) { |
| 396 | | - throw new Error('Failed to download character'); |
| 418 | + const downloadResult = await fetch(imageUrl); |
| 419 | + if (downloadResult.ok) { |
| 420 | + imageBuffer = Buffer.from(await downloadResult.arrayBuffer()); |
| 421 | + } |
| 397 | 422 | } |
| 398 | 423 | |
| 399 | 424 | const buffer = Buffer.fromwrite(awaitimageBuffer, downloadResultJSON.arrayBufferstringify(characterCard)); |
| 400 | | - const fileName = |
| 425 | + const fileName = `${sanitize(characterCard.data.name)}.png`; |
| 401 | | - downloadResult.headers.get('content-disposition')?.split('filename=')[1]?.replace(/["']/g, '') || |
| 426 | + const fileType = 'image/png'; |
| 402 | | - `${sanitize(projectName)}.png`; |
| 403 | | - const fileType = downloadResult.headers.get('content-type'); |
| 404 | 427 | |
| 405 | 428 | return { buffer, fileName, fileType }; |
| 406 | 429 | } |