@xuda.io/ai_module 1.1.4356 → 1.1.4358

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +198 -195
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -5290,8 +5290,8 @@ setTimeout(async () => {
5290
5290
  // },
5291
5291
  // });
5292
5292
 
5293
- // ret = await get_profile_image(uid, 'business', 'ioshka media', {}, account_profile_info);
5294
- // ret = await get_profile_image(
5293
+ // ret = await get_profile_picture(uid, 'business', 'ioshka media', {}, account_profile_info);
5294
+ // ret = await get_profile_picture(
5295
5295
  // uid,
5296
5296
  // 'personal',
5297
5297
  // 'Glenn Willett',
@@ -5679,72 +5679,74 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5679
5679
  const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
5680
5680
  const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`);
5681
5681
 
5682
- async function normalizeBase64To1024(base64Image) {
5683
- const inputBuffer = Buffer.from(base64Image, 'base64');
5682
+ const { url, uid, account_obj, prompt, is_profile_avatar, account_profile_info, docType = 'account', _id, metadata = {} } = req;
5684
5683
 
5685
- const normalizedBuffer = await sharp(inputBuffer)
5686
- .resize(1024, 1024, {
5687
- fit: 'contain', // Preserve aspect ratio, fit within 211x211
5688
- background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background for padding
5689
- })
5690
- .png({
5691
- quality: 100,
5692
- compressionLevel: 9,
5693
- force: true,
5694
- })
5695
- .toBuffer();
5684
+ // async function normalizeBase64To1024(base64Image) {
5685
+ // const inputBuffer = Buffer.from(base64Image, 'base64');
5696
5686
 
5697
- return normalizedBuffer.toString('base64'); // Return normalized base64 string
5698
- }
5687
+ // const normalizedBuffer = await sharp(inputBuffer)
5688
+ // .resize(1024, 1024, {
5689
+ // fit: 'contain', // Preserve aspect ratio, fit within 211x211
5690
+ // background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background for padding
5691
+ // })
5692
+ // .png({
5693
+ // quality: 100,
5694
+ // compressionLevel: 9,
5695
+ // force: true,
5696
+ // })
5697
+ // .toBuffer();
5699
5698
 
5700
- async function hasTransparentBackground(filePath) {
5701
- const image = sharp(filePath);
5702
- const metadata = await image.metadata();
5699
+ // return normalizedBuffer.toString('base64'); // Return normalized base64 string
5700
+ // }
5703
5701
 
5704
- // If the image doesn't have an alpha channel at all → no transparency possible
5705
- if (!metadata.hasAlpha) {
5706
- return false;
5707
- }
5702
+ // async function hasTransparentBackground(filePath) {
5703
+ // const image = sharp(filePath);
5704
+ // const metadata = await image.metadata();
5708
5705
 
5709
- // For images with alpha channel, check if any pixel actually has alpha < 255
5710
- const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
5706
+ // // If the image doesn't have an alpha channel at all → no transparency possible
5707
+ // if (!metadata.hasAlpha) {
5708
+ // return false;
5709
+ // }
5711
5710
 
5712
- // Determine position of alpha channel based on number of channels
5713
- const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
5714
- const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
5711
+ // // For images with alpha channel, check if any pixel actually has alpha < 255
5712
+ // const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
5715
5713
 
5716
- if (alphaOffset === -1) {
5717
- // Unusual channel count – be conservative and assume it might have transparency
5718
- return true;
5719
- }
5714
+ // // Determine position of alpha channel based on number of channels
5715
+ // const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
5716
+ // const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
5720
5717
 
5721
- for (let i = alphaOffset; i < data.length; i += channels) {
5722
- if (data[i] < 255) {
5723
- return true; // Found at least one transparent/semi-transparent pixel
5724
- }
5725
- }
5718
+ // if (alphaOffset === -1) {
5719
+ // // Unusual channel count – be conservative and assume it might have transparency
5720
+ // return true;
5721
+ // }
5726
5722
 
5727
- return false; // Has alpha channel but all pixels are fully opaque
5728
- }
5723
+ // for (let i = alphaOffset; i < data.length; i += channels) {
5724
+ // if (data[i] < 255) {
5725
+ // return true; // Found at least one transparent/semi-transparent pixel
5726
+ // }
5727
+ // }
5729
5728
 
5730
- async function imageToPngBlob(filePath) {
5731
- const ext = path.extname(filePath).toLowerCase();
5729
+ // return false; // Has alpha channel but all pixels are fully opaque
5730
+ // }
5732
5731
 
5733
- let buffer;
5732
+ // async function imageToPngBlob(filePath) {
5733
+ // const ext = path.extname(filePath).toLowerCase();
5734
5734
 
5735
- let is_transparent = false;
5736
- if (ext === '.png') {
5737
- buffer = await fs.promises.readFile(filePath);
5738
- is_transparent = await hasTransparentBackground(filePath);
5739
- } else {
5740
- console.log(`Converting ${path.basename(filePath)} to PNG...`);
5741
- buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
5742
- }
5735
+ // let buffer;
5743
5736
 
5744
- // Create a Blob with correct MIME type
5737
+ // let is_transparent = false;
5738
+ // if (ext === '.png') {
5739
+ // buffer = await fs.promises.readFile(filePath);
5740
+ // is_transparent = await hasTransparentBackground(filePath);
5741
+ // } else {
5742
+ // console.log(`Converting ${path.basename(filePath)} to PNG...`);
5743
+ // buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
5744
+ // }
5745
5745
 
5746
- return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
5747
- }
5746
+ // // Create a Blob with correct MIME type
5747
+
5748
+ // return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
5749
+ // }
5748
5750
 
5749
5751
  const detect_real_person_in_image = async function (base64) {
5750
5752
  const ret = await submit_chat_gpt_prompt({
@@ -5777,59 +5779,60 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5777
5779
  };
5778
5780
 
5779
5781
  // const drive_module = await import(`${module_path}/drive_module/index.mjs`);
5780
- const { url, uid, account_obj, prompt, is_profile_avatar, account_profile_info } = req;
5782
+
5781
5783
  if (!is_profile_avatar) {
5782
5784
  await update_profile_avatar_status(account_obj._id, 2);
5783
5785
  }
5784
5786
  try {
5785
- if (!url) {
5786
- throw new Error('No URL provided in request');
5787
- }
5787
+ // if (!url) {
5788
+ // throw new Error('No URL provided in request');
5789
+ // }
5788
5790
 
5789
5791
  // 3. Download the image to a Buffer
5790
- const res = await fetch(url);
5791
- if (!res.ok) {
5792
- throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
5793
- }
5792
+ // const res = await fetch(url);
5793
+ // if (!res.ok) {
5794
+ // throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
5795
+ // }
5794
5796
 
5795
- const arrayBuffer = await res.arrayBuffer();
5796
- const imageBuffer = Buffer.from(arrayBuffer);
5797
+ // const arrayBuffer = await res.arrayBuffer();
5798
+ // const imageBuffer = Buffer.from(arrayBuffer);
5797
5799
 
5798
- const tempDir = os.tmpdir();
5799
- const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
5800
+ // const tempDir = os.tmpdir();
5801
+ // const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
5800
5802
 
5801
- const inputExt = path.extname(url) || '.jpg';
5802
- const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
5803
- const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
5803
+ // const inputExt = path.extname(url) || '.jpg';
5804
+ // const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
5805
+ // const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
5804
5806
 
5805
5807
  // 5. Write the downloaded image to disk
5806
- fs.writeFileSync(tempInputPath, imageBuffer);
5808
+ // fs.writeFileSync(tempInputPath, imageBuffer);
5807
5809
  /////////////////////////////////
5808
5810
 
5809
- const imageFiles = [tempInputPath];
5811
+ // const imageFiles = [tempInputPath];
5810
5812
 
5811
- const images = await Promise.all(
5812
- imageFiles.map(async (filePath) => {
5813
- const img_ret = await imageToPngBlob(filePath);
5814
- const blob = img_ret.image_blob;
5813
+ // const images = await Promise.all(
5814
+ // imageFiles.map(async (filePath) => {
5815
+ // const img_ret = await imageToPngBlob(filePath);
5816
+ // const blob = img_ret.image_blob;
5815
5817
 
5816
- // OpenAI expects a filename for logging/debugging
5817
- const filename = path.basename(filePath, path.extname(filePath)) + '.png';
5818
- blob.name = filename; // Optional but helpful
5819
- // @ts-ignore – name is allowed in Node 20+
5820
- blob.lastModified = Date.now();
5818
+ // // OpenAI expects a filename for logging/debugging
5819
+ // const filename = path.basename(filePath, path.extname(filePath)) + '.png';
5820
+ // blob.name = filename; // Optional but helpful
5821
+ // // @ts-ignore – name is allowed in Node 20+
5822
+ // blob.lastModified = Date.now();
5821
5823
 
5822
- return { is_transparent: img_ret.is_transparent, image_blob: blob };
5823
- }),
5824
- );
5824
+ // return { is_transparent: img_ret.is_transparent, image_blob: blob };
5825
+ // }),
5826
+ // );
5825
5827
 
5826
5828
  let imageBase64;
5829
+ const image_blob_ret = await get_image_blob_from_downloaded_image(url);
5827
5830
  let avatar_source = '';
5828
5831
  if (prompt) {
5829
5832
  const model = 'chatgpt-image-latest';
5830
5833
  const ai_avatar_response = await client.images.edit({
5831
5834
  model, // 'gpt-image-1',
5832
- image: images[0].image_blob, //base photo
5835
+ image: image_blob_ret.image_blob, //base photo
5833
5836
  prompt,
5834
5837
  background: 'transparent',
5835
5838
  });
@@ -5837,13 +5840,13 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5837
5840
  record_chat_usage(uid, ai_avatar_response.usage.input_tokens, ai_avatar_response.usage.output_tokens, 'profile avatar', prompt, model, { url }, account_profile_info);
5838
5841
  } else {
5839
5842
  //////////////////
5840
- imageBase64 = Buffer.from(await images[0].image_blob.arrayBuffer()).toString('base64');
5843
+ imageBase64 = Buffer.from(await image_blob_ret.image_blob.arrayBuffer()).toString('base64');
5841
5844
  if (account_obj.account_info.account_type === 'business') {
5842
5845
  // create avatar from logo - BUSINESS
5843
5846
  const { bio, business_name, country, mainCategory, subCategory } = account_obj.account_info;
5844
5847
  // const ai_avatar_response = await client.images.edit({
5845
5848
  // model: 'chatgpt-image-latest',
5846
- // image: images[0].image_blob, // only one image allowed
5849
+ // image: image_blob_ret.image_blob, // only one image allowed
5847
5850
  // prompt: `Generate a realistic fictional portrait wearing a hat. The portrait should be centered, head-and-shoulders only, on a transparent background. Place the provided logo on the hat, and ensure the subject is large enough to fill most of the frame. Use the supplied name, country, and context to guide the character’s appearance.
5848
5851
  // Context: ${JSON.stringify({ bio, business_name, country, mainCategory, subCategory })}`,
5849
5852
  // background: 'transparent',
@@ -5851,7 +5854,7 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5851
5854
  ///////////////////
5852
5855
  // const ai_avatar_response = await client.images.edit({
5853
5856
  // model: 'chatgpt-image-latest',
5854
- // image: images[0].image_blob, //base photo
5857
+ // image: image_blob_ret.image_blob, //base photo
5855
5858
  // prompt: `Create a transparent PNG profile image for a business account featuring building branded as ${business_name}.
5856
5859
  // Display the attached logo clearly as prominent exterior signage.
5857
5860
  // The building’s architecture and overall atmosphere should reflect the nature of the business, aligning with ${mainCategory} and ${subCategory}.
@@ -5899,7 +5902,7 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5899
5902
  const model = 'chatgpt-image-latest';
5900
5903
  const ai_avatar_response = await client.images.edit({
5901
5904
  model,
5902
- image: images[0].image_blob, //logo
5905
+ image: image_blob_ret.image_blob, //logo
5903
5906
  prompt: `
5904
5907
  Create a transparent PNG profile image for a business account featuring building branded as ${business_name}.
5905
5908
  Display the attached logo clearly as prominent exterior signage.
@@ -5922,7 +5925,7 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5922
5925
  const model = 'chatgpt-image-latest';
5923
5926
  const ai_avatar_response = await client.images.edit({
5924
5927
  model,
5925
- image: images[0].image_blob,
5928
+ image: image_blob_ret.image_blob,
5926
5929
 
5927
5930
  prompt: `Completely remove the background, enhance and color-correct the subject, and return only a centered head-and-shoulders portrait facing the camera. Add extra top margin, include no labels or text, and export the result as a clean transparent PNG.
5928
5931
  Ensure the subject is large enough to fill most of the frame. Use the supplied name, country, and context to guide the character’s appearance.
@@ -5945,9 +5948,9 @@ export const create_profile_avatar = async function (req, job_id, headers) {
5945
5948
  // personal account
5946
5949
  const is_real_person_in_picture = await detect_real_person_in_image(imageBase64);
5947
5950
  if (is_real_person_in_picture) {
5948
- if (images[0].is_transparent) {
5951
+ if (image_blob_ret.is_transparent) {
5949
5952
  // keep the original
5950
- imageBase64 = Buffer.from(await images[0].image_blob.arrayBuffer()).toString('base64');
5953
+ imageBase64 = Buffer.from(await image_blob_ret.image_blob.arrayBuffer()).toString('base64');
5951
5954
  avatar_source = 'authentic profile';
5952
5955
  } else {
5953
5956
  // create avatar from profile picture
@@ -6198,72 +6201,72 @@ const create_ai_agent_image = async function (req, job_id, headers) {
6198
6201
  const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
6199
6202
  const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`);
6200
6203
 
6201
- async function normalizeBase64To1024(base64Image) {
6202
- const inputBuffer = Buffer.from(base64Image, 'base64');
6203
-
6204
- const normalizedBuffer = await sharp(inputBuffer)
6205
- .resize(1024, 1024, {
6206
- fit: 'contain', // Preserve aspect ratio, fit within 211x211
6207
- background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background for padding
6208
- })
6209
- .png({
6210
- quality: 100,
6211
- compressionLevel: 9,
6212
- force: true,
6213
- })
6214
- .toBuffer();
6215
-
6216
- return normalizedBuffer.toString('base64'); // Return normalized base64 string
6217
- }
6218
-
6219
- async function hasTransparentBackground(filePath) {
6220
- const image = sharp(filePath);
6221
- const metadata = await image.metadata();
6222
-
6223
- // If the image doesn't have an alpha channel at all → no transparency possible
6224
- if (!metadata.hasAlpha) {
6225
- return false;
6226
- }
6227
-
6228
- // For images with alpha channel, check if any pixel actually has alpha < 255
6229
- const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
6230
-
6231
- // Determine position of alpha channel based on number of channels
6232
- const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
6233
- const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
6234
-
6235
- if (alphaOffset === -1) {
6236
- // Unusual channel count – be conservative and assume it might have transparency
6237
- return true;
6238
- }
6239
-
6240
- for (let i = alphaOffset; i < data.length; i += channels) {
6241
- if (data[i] < 255) {
6242
- return true; // Found at least one transparent/semi-transparent pixel
6243
- }
6244
- }
6245
-
6246
- return false; // Has alpha channel but all pixels are fully opaque
6247
- }
6248
-
6249
- async function imageToPngBlob(filePath) {
6250
- const ext = path.extname(filePath).toLowerCase();
6251
-
6252
- let buffer;
6253
-
6254
- let is_transparent = false;
6255
- if (ext === '.png') {
6256
- buffer = await fs.promises.readFile(filePath);
6257
- is_transparent = await hasTransparentBackground(filePath);
6258
- } else {
6259
- console.log(`Converting ${path.basename(filePath)} to PNG...`);
6260
- buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
6261
- }
6262
-
6263
- // Create a Blob with correct MIME type
6264
-
6265
- return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
6266
- }
6204
+ // async function normalizeBase64To1024(base64Image) {
6205
+ // const inputBuffer = Buffer.from(base64Image, 'base64');
6206
+
6207
+ // const normalizedBuffer = await sharp(inputBuffer)
6208
+ // .resize(1024, 1024, {
6209
+ // fit: 'contain', // Preserve aspect ratio, fit within 211x211
6210
+ // background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background for padding
6211
+ // })
6212
+ // .png({
6213
+ // quality: 100,
6214
+ // compressionLevel: 9,
6215
+ // force: true,
6216
+ // })
6217
+ // .toBuffer();
6218
+
6219
+ // return normalizedBuffer.toString('base64'); // Return normalized base64 string
6220
+ // }
6221
+
6222
+ // async function hasTransparentBackground(filePath) {
6223
+ // const image = sharp(filePath);
6224
+ // const metadata = await image.metadata();
6225
+
6226
+ // // If the image doesn't have an alpha channel at all → no transparency possible
6227
+ // if (!metadata.hasAlpha) {
6228
+ // return false;
6229
+ // }
6230
+
6231
+ // // For images with alpha channel, check if any pixel actually has alpha < 255
6232
+ // const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
6233
+
6234
+ // // Determine position of alpha channel based on number of channels
6235
+ // const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
6236
+ // const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
6237
+
6238
+ // if (alphaOffset === -1) {
6239
+ // // Unusual channel count – be conservative and assume it might have transparency
6240
+ // return true;
6241
+ // }
6242
+
6243
+ // for (let i = alphaOffset; i < data.length; i += channels) {
6244
+ // if (data[i] < 255) {
6245
+ // return true; // Found at least one transparent/semi-transparent pixel
6246
+ // }
6247
+ // }
6248
+
6249
+ // return false; // Has alpha channel but all pixels are fully opaque
6250
+ // }
6251
+
6252
+ // async function imageToPngBlob(filePath) {
6253
+ // const ext = path.extname(filePath).toLowerCase();
6254
+
6255
+ // let buffer;
6256
+
6257
+ // let is_transparent = false;
6258
+ // if (ext === '.png') {
6259
+ // buffer = await fs.promises.readFile(filePath);
6260
+ // is_transparent = await hasTransparentBackground(filePath);
6261
+ // } else {
6262
+ // console.log(`Converting ${path.basename(filePath)} to PNG...`);
6263
+ // buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
6264
+ // }
6265
+
6266
+ // // Create a Blob with correct MIME type
6267
+
6268
+ // return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
6269
+ // }
6267
6270
 
6268
6271
  const { app_id, uid, ai_agent_id, tags, account_profile_info } = req;
6269
6272
 
@@ -6312,55 +6315,55 @@ const create_ai_agent_image = async function (req, job_id, headers) {
6312
6315
  let url = account_doc.account_info.profile_avatar;
6313
6316
 
6314
6317
  try {
6315
- if (!url) {
6316
- throw new Error('No URL provided in request');
6317
- }
6318
+ // if (!url) {
6319
+ // throw new Error('No URL provided in request');
6320
+ // }
6318
6321
 
6319
- // 3. Download the image to a Buffer
6320
- const res = await fetch(url);
6321
- if (!res.ok) {
6322
- throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
6323
- }
6322
+ // // 3. Download the image to a Buffer
6323
+ // const res = await fetch(url);
6324
+ // if (!res.ok) {
6325
+ // throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
6326
+ // }
6324
6327
 
6325
- const arrayBuffer = await res.arrayBuffer();
6326
- const imageBuffer = Buffer.from(arrayBuffer);
6328
+ // const arrayBuffer = await res.arrayBuffer();
6329
+ // const imageBuffer = Buffer.from(arrayBuffer);
6327
6330
 
6328
- const tempDir = os.tmpdir();
6329
- const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
6331
+ // const tempDir = os.tmpdir();
6332
+ // const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
6330
6333
 
6331
- const inputExt = path.extname(url) || '.jpg';
6332
- const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
6333
- const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
6334
+ // const inputExt = path.extname(url) || '.jpg';
6335
+ // const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
6336
+ // const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
6334
6337
 
6335
6338
  // 5. Write the downloaded image to disk
6336
- fs.writeFileSync(tempInputPath, imageBuffer);
6339
+ // fs.writeFileSync(tempInputPath, imageBuffer);
6337
6340
  /////////////////////////////////
6338
6341
 
6339
- const imageFiles = [tempInputPath];
6342
+ // const imageFiles = [tempInputPath];
6340
6343
 
6341
- const images = await Promise.all(
6342
- imageFiles.map(async (filePath) => {
6343
- const img_ret = await imageToPngBlob(filePath);
6344
- const blob = img_ret.image_blob;
6344
+ // const images = await Promise.all(
6345
+ // imageFiles.map(async (filePath) => {
6346
+ // const img_ret = await imageToPngBlob(filePath);
6347
+ // const blob = img_ret.image_blob;
6345
6348
 
6346
- // OpenAI expects a filename for logging/debugging
6347
- const filename = path.basename(filePath, path.extname(filePath)) + '.png';
6348
- blob.name = filename; // Optional but helpful
6349
- // @ts-ignore – name is allowed in Node 20+
6350
- blob.lastModified = Date.now();
6349
+ // // OpenAI expects a filename for logging/debugging
6350
+ // const filename = path.basename(filePath, path.extname(filePath)) + '.png';
6351
+ // blob.name = filename; // Optional but helpful
6352
+ // // @ts-ignore – name is allowed in Node 20+
6353
+ // blob.lastModified = Date.now();
6351
6354
 
6352
- return { is_transparent: img_ret.is_transparent, image_blob: blob };
6353
- }),
6354
- );
6355
+ // return { is_transparent: img_ret.is_transparent, image_blob: blob };
6356
+ // }),
6357
+ // );
6355
6358
 
6356
6359
  let imageBase64;
6357
-
6360
+ const image_blob_ret = await get_image_blob_from_downloaded_image(url);
6358
6361
  //////////////////
6359
- imageBase64 = Buffer.from(await images[0].image_blob.arrayBuffer()).toString('base64');
6362
+ imageBase64 = Buffer.from(await image_blob_ret.image_blob.arrayBuffer()).toString('base64');
6360
6363
  const model = 'chatgpt-image-latest';
6361
6364
  const ai_avatar_response = await client.images.edit({
6362
6365
  model,
6363
- image: images[0].image_blob,
6366
+ image: image_blob_ret.image_blob,
6364
6367
 
6365
6368
  prompt: `
6366
6369
  Create a futuristic, profile portrait with a transparent background.
@@ -6742,7 +6745,7 @@ export const is_business_contact = async function (uid, email, name, subject, bo
6742
6745
  } catch (error) {}
6743
6746
  };
6744
6747
 
6745
- const get_profile_image = async function (uid, account_type = 'business', name, facts = {}, account_profile_info, job_id, headers) {
6748
+ export const get_profile_picture = async function (uid, account_type = 'business', name, facts = {}, account_profile_info, job_id, headers) {
6746
6749
  const tempDir = os.tmpdir();
6747
6750
  const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
6748
6751
  const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`);
@@ -6756,7 +6759,7 @@ const get_profile_image = async function (uid, account_type = 'business', name,
6756
6759
  .replace(/^_+|_+$/g, ''); // trim leading/trailing underscores
6757
6760
  }
6758
6761
 
6759
- let prompt, factual_prompt, originalname, factual_image_mode, imageBase64, image_blob, file;
6762
+ let prompt, factual_prompt, originalname, factual_image_mode, imageBase64, image_blob_ret, file;
6760
6763
 
6761
6764
  switch (account_type) {
6762
6765
  case 'personal': {
@@ -6785,7 +6788,7 @@ const get_profile_image = async function (uid, account_type = 'business', name,
6785
6788
  uid,
6786
6789
  prompt,
6787
6790
  model: 'gpt-5-nano',
6788
- metadata: { func: 'get_profile_image' },
6791
+ metadata: { func: 'get_profile_picture' },
6789
6792
  account_profile_info,
6790
6793
  tools: [{ type: 'web_search_preview' }],
6791
6794
  });
@@ -6808,7 +6811,7 @@ const get_profile_image = async function (uid, account_type = 'business', name,
6808
6811
  // success
6809
6812
 
6810
6813
  try {
6811
- image_blob = await get_image_blob_from_downloaded_image(url);
6814
+ image_blob_ret = await get_image_blob_from_downloaded_image(url);
6812
6815
  } catch (err) {
6813
6816
  if (!err.message.includes('Failed to fetch image URL')) {
6814
6817
  console.error(err);
@@ -6827,7 +6830,7 @@ const get_profile_image = async function (uid, account_type = 'business', name,
6827
6830
  `;
6828
6831
  const image_response = await client.images.edit({
6829
6832
  model,
6830
- image: image_blob,
6833
+ image: image_blob_ret.image_blob,
6831
6834
  prompt,
6832
6835
  background: 'transparent',
6833
6836
  });
@@ -6968,5 +6971,5 @@ const get_image_blob_from_downloaded_image = async function (url) {
6968
6971
  }),
6969
6972
  );
6970
6973
 
6971
- return images[0].image_blob;
6974
+ return images[0];
6972
6975
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/ai_module",
3
- "version": "1.1.4356",
3
+ "version": "1.1.4358",
4
4
  "description": "Xuda AI Module",
5
5
  "main": "index.mjs",
6
6
  "type": "module",