@xuda.io/ai_module 1.1.4650 → 1.1.4652

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 +520 -70
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -4205,84 +4205,89 @@ export const create_conversation = async function (req, job_id, headers) {
4205
4205
  const save_ret = await db_module.save_app_couch_doc(app_id, { ...conversation_doc, ...{ uid: recipient_uid, reference_id: recipient_contact_id } });
4206
4206
  }
4207
4207
 
4208
- setTimeout(async () => {
4209
- // Ask GPT for title
4210
- if (conversation_type !== 'email') {
4211
- if (prompt.split(' ').length > 10) {
4212
- const title = await submit_chat_gpt_prompt({ uid, prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`, model: 'gpt-5-nano', metadata: { conversation_id: conversation_doc._id, func: 'create_conversation' }, account_profile_info });
4208
+ // setTimeout(async () => {
4209
+ // // Ask GPT for title
4210
+ // if (conversation_type !== 'email') {
4211
+ // if (prompt.split(' ').length > 10) {
4212
+ // const title = await submit_chat_gpt_prompt({ uid, prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`, model: 'gpt-5-nano', metadata: { conversation_id: conversation_doc._id, func: 'create_conversation' }, account_profile_info });
4213
4213
 
4214
- conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4215
- conversation_doc.title = title.data;
4214
+ // conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4215
+ // conversation_doc.title = title.data;
4216
4216
 
4217
- await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4218
- }
4219
- }
4217
+ // await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4218
+ // }
4219
+ // }
4220
+ // /// categorize prompt
4221
+ // let category_info = {};
4222
+ // switch (conversation_type) {
4223
+ // case 'ai': {
4224
+ // category_info = await categorize_ai_prompt(uid, prompt, account_profile_info);
4225
+ // break;
4226
+ // }
4220
4227
 
4221
- let category_info = {};
4222
- switch (conversation_type) {
4223
- case 'ai': {
4224
- category_info = await categorize_ai_prompt(uid, prompt, account_profile_info);
4225
- break;
4226
- }
4228
+ // case 'email': {
4229
+ // category_info = await categorize_email_subject(uid, prompt, account_profile_info);
4230
+ // break;
4231
+ // }
4227
4232
 
4228
- case 'email': {
4229
- category_info = await categorize_email_subject(uid, prompt, account_profile_info);
4230
- break;
4231
- }
4233
+ // case 'chat': {
4234
+ // category_info = await categorize_text_message(uid, prompt, account_profile_info);
4235
+ // break;
4236
+ // }
4232
4237
 
4233
- case 'chat': {
4234
- category_info = await categorize_text_message(uid, prompt, account_profile_info);
4235
- break;
4236
- }
4238
+ // case 'note': {
4239
+ // category_info = await categorize_contact_note(uid, prompt, account_profile_info);
4240
+ // break;
4241
+ // }
4237
4242
 
4238
- default:
4239
- break;
4240
- }
4243
+ // default:
4244
+ // break;
4245
+ // }
4241
4246
 
4242
- conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4243
- contact_doc.category_info = category_info;
4244
- await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4247
+ // conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4248
+ // contact_doc.category_info = category_info;
4249
+ // await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4245
4250
 
4246
- if (perform_ai_execution) {
4247
- // await update_thumbnail('conversation', conversation_doc, account_profile_info.app_id, uid, job_id, headers, null, null, account_profile_info);
4248
- }
4249
- if (conversation_doc.reference_type === 'contacts') {
4250
- if (recipient_uid) {
4251
- // valid for chat conversation
4252
- // write conversation to host after thumbnail update
4253
- // get sender conversation
4254
-
4255
- const conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4256
-
4257
- const recipient_account_profile_info = await ac3180count_module.get_active_account_profile_info(recipient_uid);
4258
- let recipient_conversation_doc = await db_module.get_app_couch_doc_native(recipient_account_profile_info.app_id, conversation_doc._id);
4259
- recipient_conversation_doc.title = conversation_doc.title;
4260
-
4261
- recipient_conversation_doc.thumbnail_request_ts = conversation_doc.thumbnail_request_ts;
4262
- recipient_conversation_doc.chat_image = conversation_doc.chat_image;
4263
- await db_module.save_app_couch_doc_native(recipient_account_profile_info.app_id, recipient_conversation_doc);
4264
-
4265
- await update_conversation_mood_level(
4266
- uid,
4267
- [
4268
- { uid: account_profile_info.uid, contact_id: reference_id },
4269
- { uid: recipient_uid, contact_id: recipient_contact_id },
4270
- ],
4271
- conversation_doc._id,
4272
- prompt,
4273
- uid,
4274
- recipient_uid,
4275
- true,
4276
- account_profile_info,
4277
- );
4278
- } else {
4279
- // other cases rather then chat
4280
- if (perform_ai_execution) {
4281
- await update_conversation_mood_level(uid, [{ uid: account_profile_info.uid, contact_id: reference_id }], conversation_doc._id, prompt, null, contact_id, conversation_doc.reference_type === 'contacts', account_profile_info);
4282
- }
4283
- }
4284
- }
4285
- }, 1000);
4251
+ // if (perform_ai_execution) {
4252
+ // // await update_thumbnail('conversation', conversation_doc, account_profile_info.app_id, uid, job_id, headers, null, null, account_profile_info);
4253
+ // }
4254
+ // if (conversation_doc.reference_type === 'contacts') {
4255
+ // if (recipient_uid) {
4256
+ // // valid for chat conversation
4257
+ // // write conversation to host after thumbnail update
4258
+ // // get sender conversation
4259
+
4260
+ // const conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4261
+
4262
+ // const recipient_account_profile_info = await ac3180count_module.get_active_account_profile_info(recipient_uid);
4263
+ // let recipient_conversation_doc = await db_module.get_app_couch_doc_native(recipient_account_profile_info.app_id, conversation_doc._id);
4264
+ // recipient_conversation_doc.title = conversation_doc.title;
4265
+
4266
+ // recipient_conversation_doc.thumbnail_request_ts = conversation_doc.thumbnail_request_ts;
4267
+ // recipient_conversation_doc.chat_image = conversation_doc.chat_image;
4268
+ // await db_module.save_app_couch_doc_native(recipient_account_profile_info.app_id, recipient_conversation_doc);
4269
+
4270
+ // await update_conversation_mood_level(
4271
+ // uid,
4272
+ // [
4273
+ // { uid: account_profile_info.uid, contact_id: reference_id },
4274
+ // { uid: recipient_uid, contact_id: recipient_contact_id },
4275
+ // ],
4276
+ // conversation_doc._id,
4277
+ // prompt,
4278
+ // uid,
4279
+ // recipient_uid,
4280
+ // true,
4281
+ // account_profile_info,
4282
+ // );
4283
+ // } else {
4284
+ // // other cases rather then chat
4285
+ // if (perform_ai_execution) {
4286
+ // await update_conversation_mood_level(uid, [{ uid: account_profile_info.uid, contact_id: reference_id }], conversation_doc._id, prompt, null, contact_id, conversation_doc.reference_type === 'contacts', account_profile_info);
4287
+ // }
4288
+ // }
4289
+ // }
4290
+ // }, 1000);
4286
4291
 
4287
4292
  return save_ret;
4288
4293
  } catch (err) {
@@ -4292,6 +4297,92 @@ export const create_conversation = async function (req, job_id, headers) {
4292
4297
  }
4293
4298
  };
4294
4299
 
4300
+ const process_conversation = async function (uid, conversation_id, account_profile_info, job_id, headers) {
4301
+ let conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4302
+
4303
+ // Ask GPT for title
4304
+ if (conversation_type !== 'email') {
4305
+ if (prompt.split(' ').length > 10) {
4306
+ const title = await submit_chat_gpt_prompt({ uid, prompt: `create title for the prompt return 5 words result maximum text only without options : ${prompt}`, model: 'gpt-5-nano', metadata: { conversation_id: conversation_doc._id, func: 'create_conversation' }, account_profile_info });
4307
+
4308
+ conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4309
+ conversation_doc.title = title.data;
4310
+
4311
+ await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4312
+ }
4313
+ }
4314
+ /// categorize prompt
4315
+ let category_info = {};
4316
+ switch (conversation_type) {
4317
+ case 'ai': {
4318
+ category_info = await categorize_ai_prompt(uid, prompt, account_profile_info);
4319
+ break;
4320
+ }
4321
+
4322
+ case 'email': {
4323
+ category_info = await categorize_email_subject(uid, prompt, account_profile_info);
4324
+ break;
4325
+ }
4326
+
4327
+ case 'chat': {
4328
+ category_info = await categorize_text_message(uid, prompt, account_profile_info);
4329
+ break;
4330
+ }
4331
+
4332
+ case 'note': {
4333
+ category_info = await categorize_contact_note(uid, prompt, account_profile_info);
4334
+ break;
4335
+ }
4336
+
4337
+ default:
4338
+ break;
4339
+ }
4340
+
4341
+ conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4342
+ contact_doc.category_info = category_info;
4343
+ await db_module.save_app_couch_doc_native(account_profile_info.app_id, conversation_doc);
4344
+
4345
+ if (perform_ai_execution) {
4346
+ // await update_thumbnail('conversation', conversation_doc, account_profile_info.app_id, uid, job_id, headers, null, null, account_profile_info);
4347
+ }
4348
+ if (conversation_doc.reference_type === 'contacts') {
4349
+ if (recipient_uid) {
4350
+ // valid for chat conversation
4351
+ // write conversation to host after thumbnail update
4352
+ // get sender conversation
4353
+
4354
+ const conversation_doc = await db_module.get_app_couch_doc_native(account_profile_info.app_id, conversation_doc._id);
4355
+
4356
+ const recipient_account_profile_info = await ac3180count_module.get_active_account_profile_info(recipient_uid);
4357
+ let recipient_conversation_doc = await db_module.get_app_couch_doc_native(recipient_account_profile_info.app_id, conversation_doc._id);
4358
+ recipient_conversation_doc.title = conversation_doc.title;
4359
+
4360
+ recipient_conversation_doc.thumbnail_request_ts = conversation_doc.thumbnail_request_ts;
4361
+ recipient_conversation_doc.chat_image = conversation_doc.chat_image;
4362
+ await db_module.save_app_couch_doc_native(recipient_account_profile_info.app_id, recipient_conversation_doc);
4363
+
4364
+ await update_conversation_mood_level(
4365
+ uid,
4366
+ [
4367
+ { uid: account_profile_info.uid, contact_id: reference_id },
4368
+ { uid: recipient_uid, contact_id: recipient_contact_id },
4369
+ ],
4370
+ conversation_doc._id,
4371
+ prompt,
4372
+ uid,
4373
+ recipient_uid,
4374
+ true,
4375
+ account_profile_info,
4376
+ );
4377
+ } else {
4378
+ // other cases rather then chat
4379
+ if (perform_ai_execution) {
4380
+ await update_conversation_mood_level(uid, [{ uid: account_profile_info.uid, contact_id: reference_id }], conversation_doc._id, prompt, null, contact_id, conversation_doc.reference_type === 'contacts', account_profile_info);
4381
+ }
4382
+ }
4383
+ }
4384
+ };
4385
+
4295
4386
  const contactGuardrailAgent = new Agent({
4296
4387
  name: 'Person Guardrail check',
4297
4388
  instructions: 'Check if the prompt about person.',
@@ -8121,3 +8212,362 @@ Category:`;
8121
8212
  };
8122
8213
  }
8123
8214
  };
8215
+
8216
+ export const categorize_contact_note = async function (uid, note_text, account_profile_info) {
8217
+ const note_categories = [
8218
+ // Personal & Relationship Notes (1-20)
8219
+ 'Personal Update',
8220
+ 'Life Milestone',
8221
+ 'Family News',
8222
+ 'Relationship Update',
8223
+ 'Romantic Expression',
8224
+ 'Friendship Note',
8225
+ 'Apology Letter',
8226
+ 'Thank You Note',
8227
+ 'Appreciation Message',
8228
+ 'Encouragement Note',
8229
+ 'Sympathy Message',
8230
+ 'Condolences',
8231
+ 'Congratulations',
8232
+ 'Birthday Wish',
8233
+ 'Anniversary Note',
8234
+ 'Holiday Greeting',
8235
+ 'Miss You Note',
8236
+ 'Thinking of You',
8237
+ 'Love Letter',
8238
+ 'Reconciliation Request',
8239
+
8240
+ // Professional & Work Notes (21-40)
8241
+ 'Work Update',
8242
+ 'Project Status',
8243
+ 'Meeting Follow-up',
8244
+ 'Professional Thank You',
8245
+ 'Colleague Recognition',
8246
+ 'Business Proposal',
8247
+ 'Partnership Interest',
8248
+ 'Networking Introduction',
8249
+ 'Reference Request',
8250
+ 'Recommendation Letter',
8251
+ 'Resignation Notice',
8252
+ 'Job Offer',
8253
+ 'Contract Discussion',
8254
+ 'Client Update',
8255
+ 'Team Announcement',
8256
+ 'Performance Feedback',
8257
+ 'Career Advice',
8258
+ 'Mentorship Request',
8259
+ 'Professional Inquiry',
8260
+ 'Business Idea Sharing',
8261
+
8262
+ // Informational & Educational (41-60)
8263
+ 'Knowledge Sharing',
8264
+ 'Research Findings',
8265
+ 'Article Summary',
8266
+ 'Book Recommendation',
8267
+ 'Educational Resource',
8268
+ 'Study Notes',
8269
+ 'Learning Insights',
8270
+ 'Tutorial Guide',
8271
+ 'How-to Instructions',
8272
+ 'Technical Explanation',
8273
+ 'Scientific Discovery',
8274
+ 'Historical Fact',
8275
+ 'Cultural Insight',
8276
+ 'Language Lesson',
8277
+ 'Skill Sharing',
8278
+ 'Workshop Notes',
8279
+ 'Conference Takeaways',
8280
+ 'Lecture Summary',
8281
+ 'Expert Advice',
8282
+ 'Field Report',
8283
+
8284
+ // Creative & Artistic (61-75)
8285
+ 'Creative Writing',
8286
+ 'Poetry Share',
8287
+ 'Story Excerpt',
8288
+ 'Script Draft',
8289
+ 'Song Lyrics',
8290
+ 'Art Description',
8291
+ 'Creative Idea',
8292
+ 'Inspiration Share',
8293
+ 'Design Concept',
8294
+ 'Photography Note',
8295
+ 'Craft Instructions',
8296
+ 'Recipe Share',
8297
+ 'Musical Composition',
8298
+ 'Art Critique',
8299
+ 'Creative Feedback',
8300
+
8301
+ // Planning & Organization (76-90)
8302
+ 'Event Planning',
8303
+ 'Travel Itinerary',
8304
+ 'Meeting Agenda',
8305
+ 'Project Plan',
8306
+ 'Task List',
8307
+ 'Schedule Coordination',
8308
+ 'Goal Setting',
8309
+ 'Budget Planning',
8310
+ 'Checklist Share',
8311
+ 'Timeline Update',
8312
+ 'Resource Planning',
8313
+ 'Strategy Outline',
8314
+ 'Action Plan',
8315
+ 'Roadmap Share',
8316
+ 'Calendar Coordination',
8317
+
8318
+ // Health & Wellness (91-100)
8319
+ 'Health Update',
8320
+ 'Medical Information',
8321
+ 'Wellness Tips',
8322
+ 'Fitness Progress',
8323
+ 'Diet Notes',
8324
+ 'Mental Health Share',
8325
+ 'Recovery Update',
8326
+ 'Self-care Reminder',
8327
+ 'Healthcare Advice',
8328
+ 'Medication Notes',
8329
+
8330
+ // Financial & Legal (101-110)
8331
+ 'Financial Update',
8332
+ 'Investment Advice',
8333
+ 'Budget Share',
8334
+ 'Expense Report',
8335
+ 'Tax Information',
8336
+ 'Legal Notice',
8337
+ 'Contract Review',
8338
+ 'Documentation',
8339
+ 'Compliance Note',
8340
+ 'Insurance Information',
8341
+
8342
+ // Household & Property (111-120)
8343
+ 'Home Update',
8344
+ 'Property Information',
8345
+ 'Maintenance Notes',
8346
+ 'Renovation Plans',
8347
+ 'Gardening Tips',
8348
+ 'Pet Care Notes',
8349
+ 'Childcare Update',
8350
+ 'Household Instructions',
8351
+ 'Neighborhood News',
8352
+ 'Community Update',
8353
+
8354
+ // Spiritual & Philosophical (121-130)
8355
+ 'Spiritual Reflection',
8356
+ 'Religious Teaching',
8357
+ 'Meditation Guide',
8358
+ 'Prayer Request',
8359
+ 'Philosophical Thought',
8360
+ 'Ethical Consideration',
8361
+ 'Life Philosophy',
8362
+ 'Moral Dilemma',
8363
+ 'Faith Journey',
8364
+ 'Enlightenment Share',
8365
+
8366
+ // Travel & Adventure (131-140)
8367
+ 'Travel Journal',
8368
+ 'Adventure Story',
8369
+ 'Destination Review',
8370
+ 'Travel Tips',
8371
+ 'Cultural Experience',
8372
+ 'Vacation Plans',
8373
+ 'Trip Report',
8374
+ 'Exploration Notes',
8375
+ 'Backpacking Guide',
8376
+ 'Souvenir Story',
8377
+
8378
+ // Technology & Digital (141-150)
8379
+ 'Tech Tips',
8380
+ 'Software Review',
8381
+ 'App Recommendation',
8382
+ 'Gadget Review',
8383
+ 'Coding Notes',
8384
+ 'Security Alert',
8385
+ 'Digital How-to',
8386
+ 'Online Resource',
8387
+ 'Website Review',
8388
+ 'Tech Support Note',
8389
+
8390
+ // Social & Community (151-160)
8391
+ 'Community News',
8392
+ 'Event Announcement',
8393
+ 'Volunteer Opportunity',
8394
+ 'Social Cause',
8395
+ 'Fundraising Update',
8396
+ 'Club News',
8397
+ 'Group Activity',
8398
+ 'Team Building',
8399
+ 'Social Gathering',
8400
+ 'Public Announcement',
8401
+
8402
+ // Memory & Reflection (161-170)
8403
+ 'Memory Share',
8404
+ 'Childhood Story',
8405
+ 'Life Reflection',
8406
+ 'Lessons Learned',
8407
+ 'Personal Growth',
8408
+ 'Turning Point',
8409
+ 'Nostalgic Memory',
8410
+ 'Historical Personal',
8411
+ 'Legacy Planning',
8412
+ 'Life Summary',
8413
+
8414
+ // Advice & Guidance (171-180)
8415
+ 'Personal Advice',
8416
+ 'Relationship Advice',
8417
+ 'Career Guidance',
8418
+ 'Parenting Tips',
8419
+ 'Financial Advice',
8420
+ 'Health Guidance',
8421
+ 'Educational Advice',
8422
+ 'Legal Counsel',
8423
+ 'Technical Advice',
8424
+ 'Life Coaching',
8425
+
8426
+ // Urgent & Important (181-190)
8427
+ 'Urgent Update',
8428
+ 'Emergency Information',
8429
+ 'Critical Notice',
8430
+ 'Important Announcement',
8431
+ 'Safety Alert',
8432
+ 'Time-sensitive Info',
8433
+ 'Immediate Action',
8434
+ 'Priority Message',
8435
+ 'Breaking News',
8436
+ 'Crisis Update',
8437
+
8438
+ // Miscellaneous (191-200)
8439
+ 'Random Thought',
8440
+ 'Interesting Fact',
8441
+ 'Question Posing',
8442
+ 'Hypothesis Share',
8443
+ 'Dream Description',
8444
+ 'Observation Note',
8445
+ 'Idea Brainstorm',
8446
+ 'Problem Statement',
8447
+ 'Solution Proposal',
8448
+ 'General Update',
8449
+ ];
8450
+ const prompt = `Categorize this note text into one of the 200 note categories based only on the note content.
8451
+
8452
+ Note Text: "${note_text}"
8453
+
8454
+ INSTRUCTIONS:
8455
+ 1. Analyze ONLY the note content - no external context
8456
+ 2. Choose ONE category that best fits the note's primary purpose
8457
+ 3. Consider: What type of information is being shared?
8458
+ 4. Return the exact category name from the list
8459
+ 5. If truly ambiguous, choose "General Update"
8460
+
8461
+ Think step by step:
8462
+ 1. What is the main purpose of this note? (Inform, update, request, share, etc.)
8463
+ 2. What domain does it belong to? (Personal, professional, creative, etc.)
8464
+ 3. What is the tone and formality level?
8465
+ 4. What kind of response or action might it expect?
8466
+
8467
+ Category:`;
8468
+
8469
+ try {
8470
+ const note_category_ret = await submit_chat_gpt_prompt({
8471
+ uid,
8472
+ prompt: prompt,
8473
+ model: 'gpt-4o-mini',
8474
+ response_format: z.object({
8475
+ note_category: z.enum(note_categories),
8476
+ confidence_score: z.number().min(0).max(100),
8477
+ primary_purpose: z.string(),
8478
+ tone: z.enum(['Formal', 'Semi-formal', 'Casual', 'Professional', 'Personal', 'Academic', 'Creative', 'Urgent']),
8479
+ note_type: z.enum(['Informational', 'Emotional', 'Transactional', 'Creative', 'Reflective', 'Instructional', 'Request-based', 'Update']),
8480
+ }),
8481
+ metadata: {
8482
+ func: 'categorize_contact_note',
8483
+ note_length: note_text.length,
8484
+ timestamp: new Date().toISOString(),
8485
+ },
8486
+ account_profile_info,
8487
+ });
8488
+
8489
+ if (note_category_ret && note_category_ret.code > -1) {
8490
+ const data = typeof note_category_ret.data === 'string' ? JSON.parse(note_category_ret.data) : note_category_ret.data;
8491
+
8492
+ // Local note analysis
8493
+ const note_analysis = {
8494
+ word_count: note_text.split(/\s+/).filter((w) => w.length > 0).length,
8495
+ paragraph_count: (note_text.match(/\n\s*\n/g) || []).length + 1,
8496
+ has_questions: /[?]|(what|how|why|when|where|who|can|could|would)/i.test(note_text),
8497
+ has_requests: /(please|request|ask|need|want|require)/i.test(note_text),
8498
+ has_dates: /\b(\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}|\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2})\b/.test(note_text),
8499
+ has_numbers: /\b\d+\b/.test(note_text),
8500
+ is_structured: /(\d+\.|•|- \[|\d{1,2}\/\d{1,2})/.test(note_text.substring(0, 100)),
8501
+ };
8502
+
8503
+ // Determine importance level based on category and tone
8504
+ let importance = 3; // Medium by default
8505
+ if (data.tone === 'Urgent' || data.note_category.includes('Urgent') || data.note_category.includes('Emergency')) {
8506
+ importance = 1;
8507
+ } else if (data.tone === 'Professional' || data.note_category.includes('Important') || data.note_category.includes('Critical')) {
8508
+ importance = 2;
8509
+ } else if (data.note_category.includes('Casual') || data.note_category.includes('Personal') || data.note_category.includes('Random')) {
8510
+ importance = 4;
8511
+ }
8512
+
8513
+ // Estimate reading time (average reading speed: 200-250 words per minute)
8514
+ const reading_time_minutes = Math.ceil(note_analysis.word_count / 225);
8515
+
8516
+ // Determine if note requires follow-up
8517
+ const requires_follow_up = note_analysis.has_questions || note_analysis.has_requests || data.note_type === 'Request-based' || data.note_type === 'Transactional';
8518
+
8519
+ return {
8520
+ success: true,
8521
+ category: data.note_category,
8522
+ confidence: data.confidence_score,
8523
+ primary_purpose: data.primary_purpose,
8524
+ tone: data.tone,
8525
+ note_type: data.note_type,
8526
+ importance: importance,
8527
+
8528
+ // Note analysis
8529
+ word_count: note_analysis.word_count,
8530
+ paragraph_count: note_analysis.paragraph_count,
8531
+ has_questions: note_analysis.has_questions,
8532
+ has_requests: note_analysis.has_requests,
8533
+ is_structured: note_analysis.is_structured,
8534
+
8535
+ // Practical info
8536
+ estimated_reading_time: `${reading_time_minutes} min`,
8537
+ requires_follow_up: requires_follow_up,
8538
+ is_formal: data.tone === 'Formal' || data.tone === 'Professional',
8539
+
8540
+ // Metadata
8541
+ timestamp: new Date().toISOString(),
8542
+ note_preview: note_text.substring(0, 150) + (note_text.length > 150 ? '...' : ''),
8543
+ };
8544
+ } else {
8545
+ return {
8546
+ success: false,
8547
+ category: 'General Update',
8548
+ confidence: 0,
8549
+ primary_purpose: 'Unknown',
8550
+ tone: 'Casual',
8551
+ note_type: 'Informational',
8552
+ importance: 3,
8553
+ note_preview: note_text.substring(0, 150),
8554
+ error: note_category_ret?.message || 'API call failed',
8555
+ timestamp: new Date().toISOString(),
8556
+ };
8557
+ }
8558
+ } catch (error) {
8559
+ console.error('Error in categorize_contact_note:', error);
8560
+ return {
8561
+ success: false,
8562
+ category: 'General Update',
8563
+ confidence: 0,
8564
+ primary_purpose: 'Error',
8565
+ tone: 'Casual',
8566
+ note_type: 'Informational',
8567
+ importance: 3,
8568
+ note_preview: note_text.substring(0, 150),
8569
+ error: error.message,
8570
+ timestamp: new Date().toISOString(),
8571
+ };
8572
+ }
8573
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/ai_module",
3
- "version": "1.1.4650",
3
+ "version": "1.1.4652",
4
4
  "description": "Xuda AI Module",
5
5
  "main": "index.mjs",
6
6
  "type": "module",