@peopl-health/nexus 1.6.6 → 1.7.1
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.
- package/CHANGELOG.md +0 -0
- package/LICENSE +0 -0
- package/MIGRATION_GUIDE.md +0 -0
- package/README.md +0 -0
- package/examples/.env.example +0 -0
- package/examples/assistants/BaseAssistant.js +0 -0
- package/examples/assistants/DoctorScheduleAssistant.js +0 -0
- package/examples/assistants/ExampleAssistant.js +0 -0
- package/examples/assistants/index.js +0 -0
- package/examples/basic-usage.js +0 -0
- package/examples/consumer-server.js +0 -0
- package/lib/adapters/BaileysProvider.js +0 -0
- package/lib/adapters/TwilioProvider.js +0 -0
- package/lib/adapters/index.js +0 -0
- package/lib/adapters/registry.js +0 -0
- package/lib/assistants/BaseAssistant.js +0 -0
- package/lib/assistants/index.js +0 -0
- package/lib/config/airtableConfig.js +0 -0
- package/lib/config/awsConfig.js +0 -0
- package/lib/config/configLoader.js +0 -0
- package/lib/config/llmConfig.js +0 -0
- package/lib/config/mongoAuthConfig.js +0 -0
- package/lib/config/runtimeConfig.js +0 -0
- package/lib/controllers/assistantController.js +0 -0
- package/lib/controllers/conversationController.js +0 -0
- package/lib/controllers/mediaController.js +0 -0
- package/lib/controllers/messageController.js +0 -0
- package/lib/controllers/templateController.js +0 -0
- package/lib/controllers/templateFlowController.js +0 -0
- package/lib/controllers/uploadController.js +0 -0
- package/lib/core/MessageProvider.js +0 -0
- package/lib/core/NexusMessaging.js +89 -4
- package/lib/core/index.js +0 -0
- package/lib/helpers/assistantHelper.js +2 -2
- package/lib/helpers/baileysHelper.js +0 -0
- package/lib/helpers/filesHelper.js +0 -0
- package/lib/helpers/llmsHelper.js +0 -0
- package/lib/helpers/mediaHelper.js +0 -0
- package/lib/helpers/mongoHelper.js +0 -0
- package/lib/helpers/qrHelper.js +0 -0
- package/lib/helpers/twilioHelper.js +0 -0
- package/lib/helpers/twilioMediaProcessor.js +0 -0
- package/lib/helpers/whatsappHelper.js +0 -0
- package/lib/index.d.ts +0 -0
- package/lib/index.js +0 -0
- package/lib/interactive/index.js +0 -0
- package/lib/interactive/registry.js +0 -0
- package/lib/interactive/twilioMapper.js +0 -0
- package/lib/models/agendaMessageModel.js +0 -0
- package/lib/models/index.js +0 -0
- package/lib/models/messageModel.js +0 -0
- package/lib/models/templateModel.js +0 -0
- package/lib/models/threadModel.js +0 -0
- package/lib/providers/OpenAIProvider.js +0 -0
- package/lib/routes/index.js +0 -0
- package/lib/services/airtableService.js +0 -0
- package/lib/services/assistantService.js +2 -2
- package/lib/services/conversationService.js +0 -0
- package/lib/services/twilioService.js +0 -0
- package/lib/storage/MongoStorage.js +0 -0
- package/lib/storage/NoopStorage.js +0 -0
- package/lib/storage/index.js +0 -0
- package/lib/storage/registry.js +0 -0
- package/lib/templates/predefinedTemplates.js +0 -0
- package/lib/templates/templateStructure.js +0 -0
- package/lib/utils/dateUtils.js +0 -0
- package/lib/utils/defaultLLMProvider.js +0 -0
- package/lib/utils/errorHandler.js +0 -0
- package/lib/utils/index.js +0 -0
- package/lib/utils/logger.js +0 -0
- package/lib/utils/mediaValidator.js +0 -0
- package/lib/utils/messageParser.js +0 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
File without changes
|
package/LICENSE
CHANGED
|
File without changes
|
package/MIGRATION_GUIDE.md
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/examples/.env.example
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/examples/basic-usage.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/adapters/index.js
CHANGED
|
File without changes
|
package/lib/adapters/registry.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/assistants/index.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/config/awsConfig.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/config/llmConfig.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -36,6 +36,13 @@ class NexusMessaging {
|
|
|
36
36
|
keyword: [],
|
|
37
37
|
flow: []
|
|
38
38
|
};
|
|
39
|
+
// Message batching
|
|
40
|
+
this.pendingResponses = new Map();
|
|
41
|
+
this.batchingConfig = {
|
|
42
|
+
enabled: config.messageBatching?.enabled ?? true,
|
|
43
|
+
baseWaitTime: config.messageBatching?.baseWaitTime ?? 15000,
|
|
44
|
+
randomVariation: config.messageBatching?.randomVariation ?? 5000
|
|
45
|
+
};
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
/**
|
|
@@ -316,7 +323,9 @@ class NexusMessaging {
|
|
|
316
323
|
});
|
|
317
324
|
}
|
|
318
325
|
|
|
319
|
-
|
|
326
|
+
const chatId = messageData.from || messageData.From;
|
|
327
|
+
|
|
328
|
+
// Handle immediate response messages (interactive, flows, etc.)
|
|
320
329
|
if (messageData.interactive) {
|
|
321
330
|
return await this.handleInteractive(messageData);
|
|
322
331
|
} else if (messageData.media) {
|
|
@@ -328,7 +337,12 @@ class NexusMessaging {
|
|
|
328
337
|
} else if (messageData.flow) {
|
|
329
338
|
return await this.handleFlow(messageData);
|
|
330
339
|
} else {
|
|
331
|
-
|
|
340
|
+
// For regular messages, use batching if enabled
|
|
341
|
+
if (this.batchingConfig.enabled && chatId) {
|
|
342
|
+
return await this._handleWithBatching(messageData, chatId);
|
|
343
|
+
} else {
|
|
344
|
+
return await this.handleMessage(messageData);
|
|
345
|
+
}
|
|
332
346
|
}
|
|
333
347
|
}
|
|
334
348
|
|
|
@@ -548,15 +562,86 @@ class NexusMessaging {
|
|
|
548
562
|
await this.provider.disconnect();
|
|
549
563
|
}
|
|
550
564
|
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Handle message with batching - waits for additional messages before processing
|
|
568
|
+
*/
|
|
569
|
+
async _handleWithBatching(messageData, chatId) {
|
|
570
|
+
// Clear existing timeout if there is one
|
|
571
|
+
if (this.pendingResponses.has(chatId)) {
|
|
572
|
+
clearTimeout(this.pendingResponses.get(chatId));
|
|
573
|
+
console.log(`Received additional message from ${chatId}, resetting wait timer`);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Calculate wait time with random variation
|
|
577
|
+
const waitTime = this.batchingConfig.baseWaitTime +
|
|
578
|
+
Math.floor(Math.random() * this.batchingConfig.randomVariation);
|
|
579
|
+
|
|
580
|
+
// Set new timeout
|
|
581
|
+
const timeoutId = setTimeout(async () => {
|
|
582
|
+
try {
|
|
583
|
+
this.pendingResponses.delete(chatId);
|
|
584
|
+
await this._handleBatchedMessages(chatId);
|
|
585
|
+
} catch (error) {
|
|
586
|
+
console.error(`Error handling batched messages for ${chatId}:`, error);
|
|
587
|
+
}
|
|
588
|
+
}, waitTime);
|
|
589
|
+
|
|
590
|
+
this.pendingResponses.set(chatId, timeoutId);
|
|
591
|
+
console.log(`Waiting ${Math.round(waitTime/1000)} seconds for more messages from ${chatId}`);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Process all batched messages for a chat
|
|
596
|
+
*/
|
|
597
|
+
async _handleBatchedMessages(chatId) {
|
|
598
|
+
try {
|
|
599
|
+
console.log(`Processing batched messages from ${chatId}`);
|
|
600
|
+
|
|
601
|
+
const botResponse = await replyAssistant(chatId);
|
|
602
|
+
if (botResponse && this.provider) {
|
|
603
|
+
await this.sendMessage({
|
|
604
|
+
code: chatId,
|
|
605
|
+
message: botResponse
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
this.events.emit('messages:batched', { chatId, response: botResponse });
|
|
610
|
+
|
|
611
|
+
} catch (error) {
|
|
612
|
+
console.error('Error in batched message handling:', error);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Clear pending response for a chat (useful for cleanup)
|
|
618
|
+
*/
|
|
619
|
+
clearPendingResponse(chatId) {
|
|
620
|
+
if (this.pendingResponses.has(chatId)) {
|
|
621
|
+
clearTimeout(this.pendingResponses.get(chatId));
|
|
622
|
+
this.pendingResponses.delete(chatId);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Get batching status for a chat
|
|
628
|
+
*/
|
|
629
|
+
hasPendingResponse(chatId) {
|
|
630
|
+
return this.pendingResponses.has(chatId);
|
|
631
|
+
}
|
|
551
632
|
}
|
|
552
633
|
|
|
553
|
-
|
|
634
|
+
// Global instance management
|
|
635
|
+
let defaultInstance = null;
|
|
554
636
|
|
|
555
637
|
const setDefaultInstance = (instance) => {
|
|
556
638
|
if (!instance) {
|
|
557
639
|
throw new Error('setDefaultInstance requires a NexusMessaging instance');
|
|
558
640
|
}
|
|
559
|
-
|
|
641
|
+
if (defaultInstance) {
|
|
642
|
+
throw new Error('setDefaultInstance called multiple times');
|
|
643
|
+
}
|
|
644
|
+
|
|
560
645
|
const isCompatible = typeof instance.sendMessage === 'function' &&
|
|
561
646
|
typeof instance.sendScheduledMessage === 'function' &&
|
|
562
647
|
typeof instance.processIncomingMessage === 'function';
|
package/lib/core/index.js
CHANGED
|
File without changes
|
|
@@ -185,7 +185,7 @@ async function downloadMediaAndCreateFile(code, reply) {
|
|
|
185
185
|
return fileNames;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
async function
|
|
188
|
+
async function processIndividualMessage(code, reply, thread) {
|
|
189
189
|
try {
|
|
190
190
|
const provider = llmConfig.requireOpenAIProvider();
|
|
191
191
|
const formattedMessage = formatMessage(reply);
|
|
@@ -299,5 +299,5 @@ module.exports = {
|
|
|
299
299
|
getCurRow,
|
|
300
300
|
formatMessage,
|
|
301
301
|
downloadMediaAndCreateFile,
|
|
302
|
-
|
|
302
|
+
processIndividualMessage
|
|
303
303
|
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/helpers/qrHelper.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/index.d.ts
CHANGED
|
File without changes
|
package/lib/index.js
CHANGED
|
File without changes
|
package/lib/interactive/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/models/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/routes/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -30,7 +30,7 @@ const { Message, formatTimestamp } = require('../models/messageModel.js');
|
|
|
30
30
|
const { Thread } = require('../models/threadModel.js');
|
|
31
31
|
|
|
32
32
|
const { checkRunStatus, getCurRow } = require('../helpers/assistantHelper.js');
|
|
33
|
-
const {
|
|
33
|
+
const { processIndividualMessage, getLastMessages } = require('../helpers/assistantHelper.js');
|
|
34
34
|
const { delay } = require('../helpers/whatsappHelper.js');
|
|
35
35
|
|
|
36
36
|
const configureAssistants = (config) => {
|
|
@@ -375,7 +375,7 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
|
|
|
375
375
|
let patientMsg = false;
|
|
376
376
|
let urls = [];
|
|
377
377
|
for (const reply of patientReply) {
|
|
378
|
-
const { isNotAssistant, url } = await
|
|
378
|
+
const { isNotAssistant, url } = await processIndividualMessage(code, reply, thread);
|
|
379
379
|
console.log(`isNotAssistant ${isNotAssistant} ${url}`);
|
|
380
380
|
patientMsg = patientMsg || isNotAssistant;
|
|
381
381
|
if (url) urls.push({ 'url': url });
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/storage/index.js
CHANGED
|
File without changes
|
package/lib/storage/registry.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/utils/dateUtils.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/utils/index.js
CHANGED
|
File without changes
|
package/lib/utils/logger.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|