@xuda.io/ai_module 1.1.4383 → 1.1.4385

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 +8 -142
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -5661,13 +5661,14 @@ const create_and_upload_image_to_drive = async function (drive_type, file_path,
5661
5661
  };
5662
5662
 
5663
5663
  export const create_account_profile_avatar = async function (req, job_id, headers) {
5664
- const { uid } = req;
5664
+ const { uid, url } = req;
5665
5665
  try {
5666
+ const account_profile_info = await get_active_account_profile_info(uid);
5666
5667
  req.account_profile_info = await account_module.get_active_account_profile_info(uid);
5667
- req.is_profile_avatar = true;
5668
+ // req.is_profile_avatar = true;
5668
5669
  req.account_obj = await db_module.get_couch_doc_native('xuda_accounts', uid);
5669
5670
 
5670
- return await get_profile_avatar(req, job_id, headers);
5671
+ return await get_profile_avatar(url, uid, null, account_profile_info, 'business', 'account_profile', job_id, headers);
5671
5672
  } catch (err) {
5672
5673
  return {
5673
5674
  code: -25,
@@ -5681,75 +5682,6 @@ export const get_profile_avatar = async function (profile_picture, uid, prompt,
5681
5682
  const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
5682
5683
  const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`);
5683
5684
 
5684
- // const { url, uid, prompt, account_profile_info, account_type, docType = 'account', _id, metadata = {}, profile_picture, business_size = 'unknown', name, email } = req;
5685
-
5686
- // async function normalizeBase64To1024(base64Image) {
5687
- // const inputBuffer = Buffer.from(base64Image, 'base64');
5688
-
5689
- // const normalizedBuffer = await sharp(inputBuffer)
5690
- // .resize(1024, 1024, {
5691
- // fit: 'contain', // Preserve aspect ratio, fit within 211x211
5692
- // background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background for padding
5693
- // })
5694
- // .png({
5695
- // quality: 100,
5696
- // compressionLevel: 9,
5697
- // force: true,
5698
- // })
5699
- // .toBuffer();
5700
-
5701
- // return normalizedBuffer.toString('base64'); // Return normalized base64 string
5702
- // }
5703
-
5704
- // async function hasTransparentBackground(filePath) {
5705
- // const image = sharp(filePath);
5706
- // const metadata = await image.metadata();
5707
-
5708
- // // If the image doesn't have an alpha channel at all → no transparency possible
5709
- // if (!metadata.hasAlpha) {
5710
- // return false;
5711
- // }
5712
-
5713
- // // For images with alpha channel, check if any pixel actually has alpha < 255
5714
- // const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
5715
-
5716
- // // Determine position of alpha channel based on number of channels
5717
- // const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
5718
- // const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
5719
-
5720
- // if (alphaOffset === -1) {
5721
- // // Unusual channel count – be conservative and assume it might have transparency
5722
- // return true;
5723
- // }
5724
-
5725
- // for (let i = alphaOffset; i < data.length; i += channels) {
5726
- // if (data[i] < 255) {
5727
- // return true; // Found at least one transparent/semi-transparent pixel
5728
- // }
5729
- // }
5730
-
5731
- // return false; // Has alpha channel but all pixels are fully opaque
5732
- // }
5733
-
5734
- // async function imageToPngBlob(filePath) {
5735
- // const ext = path.extname(filePath).toLowerCase();
5736
-
5737
- // let buffer;
5738
-
5739
- // let is_transparent = false;
5740
- // if (ext === '.png') {
5741
- // buffer = await fs.promises.readFile(filePath);
5742
- // is_transparent = await hasTransparentBackground(filePath);
5743
- // } else {
5744
- // console.log(`Converting ${path.basename(filePath)} to PNG...`);
5745
- // buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
5746
- // }
5747
-
5748
- // // Create a Blob with correct MIME type
5749
-
5750
- // return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
5751
- // }
5752
-
5753
5685
  const detect_real_person_in_image = async function (base64) {
5754
5686
  const ret = await submit_chat_gpt_prompt({
5755
5687
  uid,
@@ -5780,60 +5712,14 @@ export const get_profile_avatar = async function (profile_picture, uid, prompt,
5780
5712
  return res?.is_real_person_in_picture;
5781
5713
  };
5782
5714
 
5783
- // const drive_module = await import(`${module_path}/drive_module/index.mjs`);
5784
-
5785
- // if (!is_profile_avatar) {
5786
- // await update_profile_avatar_status(account_obj._id, 2);
5787
- // }
5788
5715
  try {
5789
- // if (!url) {
5790
- // throw new Error('No URL provided in request');
5791
- // }
5792
-
5793
- // 3. Download the image to a Buffer
5794
- // const res = await fetch(url);
5795
- // if (!res.ok) {
5796
- // throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
5797
- // }
5798
-
5799
- // const arrayBuffer = await res.arrayBuffer();
5800
- // const imageBuffer = Buffer.from(arrayBuffer);
5801
-
5802
- // const tempDir = os.tmpdir();
5803
- // const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
5804
-
5805
- // const inputExt = path.extname(url) || '.jpg';
5806
- // const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
5807
- // const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
5808
-
5809
- // 5. Write the downloaded image to disk
5810
- // fs.writeFileSync(tempInputPath, imageBuffer);
5811
- /////////////////////////////////
5812
-
5813
- // const imageFiles = [tempInputPath];
5814
-
5815
- // const images = await Promise.all(
5816
- // imageFiles.map(async (filePath) => {
5817
- // const img_ret = await imageToPngBlob(filePath);
5818
- // const blob = img_ret.image_blob;
5819
-
5820
- // // OpenAI expects a filename for logging/debugging
5821
- // const filename = path.basename(filePath, path.extname(filePath)) + '.png';
5822
- // blob.name = filename; // Optional but helpful
5823
- // // @ts-ignore – name is allowed in Node 20+
5824
- // blob.lastModified = Date.now();
5825
-
5826
- // return { is_transparent: img_ret.is_transparent, image_blob: blob };
5827
- // }),
5828
- // );
5829
-
5830
5716
  let imageBase64;
5831
5717
  const image_blob_ret = await get_image_blob_from_downloaded_image(profile_picture);
5832
5718
  let avatar_source = '';
5833
5719
  if (prompt) {
5834
5720
  const model = 'chatgpt-image-latest';
5835
5721
  const ai_avatar_response = await client.images.edit({
5836
- model, // 'gpt-image-1',
5722
+ model,
5837
5723
  image: image_blob_ret.image_blob, //base photo
5838
5724
  prompt,
5839
5725
  background: 'transparent',
@@ -5841,30 +5727,10 @@ export const get_profile_avatar = async function (profile_picture, uid, prompt,
5841
5727
  imageBase64 = ai_avatar_response.data[0].b64_json;
5842
5728
  record_chat_usage(uid, ai_avatar_response.usage.input_tokens, ai_avatar_response.usage.output_tokens, 'profile avatar', prompt, model, { profile_picture }, account_profile_info);
5843
5729
  } else {
5844
- //////////////////
5845
5730
  imageBase64 = Buffer.from(await image_blob_ret.image_blob.arrayBuffer()).toString('base64');
5846
5731
  if (account_type === 'business') {
5847
5732
  // create avatar from logo - BUSINESS
5848
5733
  const { bio, country, mainCategory, subCategory } = metadata;
5849
- // const ai_avatar_response = await client.images.edit({
5850
- // model: 'chatgpt-image-latest',
5851
- // image: image_blob_ret.image_blob, // only one image allowed
5852
- // 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.
5853
- // Context: ${JSON.stringify({ bio, business_name, country, mainCategory, subCategory })}`,
5854
- // background: 'transparent',
5855
- // });
5856
- ///////////////////
5857
- // const ai_avatar_response = await client.images.edit({
5858
- // model: 'chatgpt-image-latest',
5859
- // image: image_blob_ret.image_blob, //base photo
5860
- // prompt: `Create a transparent PNG profile image for a business account featuring building branded as ${business_name}.
5861
- // Display the attached logo clearly as prominent exterior signage.
5862
- // The building’s architecture and overall atmosphere should reflect the nature of the business, aligning with ${mainCategory} and ${subCategory}.
5863
- // Use the provided bio (${bio}) to understand the company’s focus and personality, and adapt the architectural style to match the ${country} country’s local design language. Select an appropriate building type for the specific business category, and present a contemporary,
5864
- // creative office environment with a strong, recognizable brand identity. The background should be fully removed, remove trees,clouds,sky or any landscape objects`,
5865
- // background: 'transparent',
5866
- // });
5867
- /////////////////
5868
5734
 
5869
5735
  // const obj = {
5870
5736
  // free: {
@@ -6129,11 +5995,11 @@ export const modify_profile_avatar = async function (req, job_id, headers) {
6129
5995
 
6130
5996
  for (const method of methods) {
6131
5997
  switch (method) {
6132
- case 'Bigger': {
6133
- prompt += `create the same person, pose, outfit, and logo in new picture with bigger avatar`;
5998
+ case 'Enlarge': {
5999
+ prompt += `create the same person, pose, outfit, and logo in new picture with enlarged avatar`;
6134
6000
  break;
6135
6001
  }
6136
- case 'Smaller': {
6002
+ case 'Shrink': {
6137
6003
  prompt += `create the same person, pose, outfit, and logo in new picture with smaller avatar`;
6138
6004
  break;
6139
6005
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/ai_module",
3
- "version": "1.1.4383",
3
+ "version": "1.1.4385",
4
4
  "description": "Xuda AI Module",
5
5
  "main": "index.mjs",
6
6
  "type": "module",