@peopl-health/nexus 4.4.1 → 4.4.3
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/lib/adapters/messageAdapters/TwilioMessageAdapter.js +0 -1
- package/lib/controllers/bugReportController.js +1 -1
- package/lib/controllers/conversationController.js +1 -1
- package/lib/controllers/interactionController.js +1 -1
- package/lib/core/NexusMessaging.js +4 -3
- package/lib/helpers/filesHelper.js +0 -1
- package/lib/helpers/messageHelper.js +1 -1
- package/lib/helpers/messageStatusHelper.js +1 -1
- package/lib/index.d.ts +17 -1
- package/lib/index.js +2 -0
- package/lib/models/messageModel.js +1 -20
- package/lib/storage/MongoStorage.js +0 -8
- package/lib/utils/MapCache.js +3 -3
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@ async function logBugReportToAirtable(reportedBug) {
|
|
|
18
18
|
if (messages?.length) {
|
|
19
19
|
const msgs = await Message.find({ _id: { $in: messages } }).sort({ createdAt: 1 });
|
|
20
20
|
conversation = msgs.map(msg => {
|
|
21
|
-
const timestamp =
|
|
21
|
+
const timestamp = msg.createdAt.toISOString().slice(0, 16).replace('T', ' ');
|
|
22
22
|
const role = msg.from_me ? 'Assistant' : 'Patient';
|
|
23
23
|
return `[${timestamp}] ${role}: ${msg.body || '(media)'}`;
|
|
24
24
|
}).join('\n');
|
|
@@ -341,7 +341,7 @@ const getConversationsByNameController = async (req, res) => {
|
|
|
341
341
|
phoneNumber: conv._id,
|
|
342
342
|
name: conv.name,
|
|
343
343
|
lastMessage: conv.latestMessage.body,
|
|
344
|
-
lastMessageTime: conv.latestMessage.
|
|
344
|
+
lastMessageTime: conv.latestMessage.createdAt,
|
|
345
345
|
messageCount: conv.messageCount
|
|
346
346
|
})),
|
|
347
347
|
pagination: {
|
|
@@ -13,7 +13,7 @@ async function logInteractionToAirtable(messageIds, whatsapp_id, reporter, quali
|
|
|
13
13
|
const messageObjects = await Message.find({ _id: { $in: messageIds } }).sort({ createdAt: -1 });
|
|
14
14
|
|
|
15
15
|
const conversation = messageObjects.map(msg => {
|
|
16
|
-
const timestamp =
|
|
16
|
+
const timestamp = msg.createdAt.toISOString().slice(0, 16).replace('T', ' ');
|
|
17
17
|
const role = msg.from_me ? 'Assistant' : 'Patient';
|
|
18
18
|
return `[${timestamp}] ${role}: ${msg.body || '(media)'}`;
|
|
19
19
|
}).join('\n');
|
|
@@ -248,7 +248,7 @@ class NexusMessaging {
|
|
|
248
248
|
? await Message.findById(messageData.parentMessageId)
|
|
249
249
|
: await this.messageStorage.savePendingMessage({
|
|
250
250
|
...messageData,
|
|
251
|
-
provider: 'twilio',
|
|
251
|
+
provider: 'twilio', fromMe: true,
|
|
252
252
|
processed: messageData.processed ?? false
|
|
253
253
|
});
|
|
254
254
|
await triggerTemplateRecovery(parent, { source: 'preemptive' });
|
|
@@ -261,7 +261,7 @@ class NexusMessaging {
|
|
|
261
261
|
const pending = await this.messageStorage.savePendingMessage({
|
|
262
262
|
...messageData,
|
|
263
263
|
provider: 'twilio',
|
|
264
|
-
|
|
264
|
+
fromMe: true,
|
|
265
265
|
processed: messageData.processed ?? false
|
|
266
266
|
});
|
|
267
267
|
parentId = pending?._id || null;
|
|
@@ -281,7 +281,8 @@ class NexusMessaging {
|
|
|
281
281
|
...messageData,
|
|
282
282
|
messageId: result.messageId,
|
|
283
283
|
provider: result.provider,
|
|
284
|
-
|
|
284
|
+
fromMe: true,
|
|
285
|
+
processed: true
|
|
285
286
|
});
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -9,7 +9,7 @@ const storeProcessedContent = async (reply, thread, processedContent) => {
|
|
|
9
9
|
if (!processedContent || !reply.media) return;
|
|
10
10
|
|
|
11
11
|
await Message.updateOne(
|
|
12
|
-
{ message_id: reply.message_id
|
|
12
|
+
{ message_id: reply.message_id },
|
|
13
13
|
{ $set: {
|
|
14
14
|
assistant_id: thread.getAssistantId(),
|
|
15
15
|
thread_id: thread.getConversationId(),
|
|
@@ -54,7 +54,7 @@ async function updateMessageStatus(messageSid, status, errorCode = null, errorMe
|
|
|
54
54
|
whatsapp_id: updated.numero,
|
|
55
55
|
error_code: errorCode || null,
|
|
56
56
|
status,
|
|
57
|
-
date: updated.
|
|
57
|
+
date: updated.createdAt.toISOString(),
|
|
58
58
|
message_id: updated.message_id
|
|
59
59
|
},
|
|
60
60
|
{
|
package/lib/index.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ declare module '@peopl-health/nexus' {
|
|
|
9
9
|
fileType?: 'text' | 'image' | 'document' | 'audio' | 'video';
|
|
10
10
|
contentSid?: string;
|
|
11
11
|
variables?: Record<string, string>;
|
|
12
|
-
timestamp?: Date;
|
|
13
12
|
interactive?: InteractiveData;
|
|
14
13
|
media?: MediaData;
|
|
15
14
|
command?: CommandData;
|
|
@@ -446,6 +445,23 @@ declare module '@peopl-health/nexus' {
|
|
|
446
445
|
handlePendingFunctionCalls(assistant: any, conversationMessages: any[], toolMetadata?: any): Promise<{ outputs: any[]; toolsExecuted: any[] }>;
|
|
447
446
|
}
|
|
448
447
|
|
|
448
|
+
export interface MapCacheOptions {
|
|
449
|
+
maxSize?: number;
|
|
450
|
+
ttl?: number | null;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export class MapCache<V = any> {
|
|
454
|
+
constructor(options?: MapCacheOptions);
|
|
455
|
+
get(key: any): V | undefined;
|
|
456
|
+
getEntry(key: any): { value: V; timestamp: number } | null;
|
|
457
|
+
set(key: any, value: V): void;
|
|
458
|
+
has(key: any): boolean;
|
|
459
|
+
delete(key: any): void;
|
|
460
|
+
clear(): void;
|
|
461
|
+
readonly size: number;
|
|
462
|
+
entries(): Array<[string, V]>;
|
|
463
|
+
}
|
|
464
|
+
|
|
449
465
|
export interface SessionEndResult {
|
|
450
466
|
summary: any | null;
|
|
451
467
|
memoriesCreated: number;
|
package/lib/index.js
CHANGED
|
@@ -21,6 +21,7 @@ const { EvalProvider } = require('./eval/EvalProvider');
|
|
|
21
21
|
const { registerTool, hasTool, getToolSchemas, clearRegistry } = require('./services/toolRegistryService');
|
|
22
22
|
const { DefaultMemoryManager } = require('./memory/DefaultMemoryManager');
|
|
23
23
|
const { EnhancedMemoryManager } = require('./memory/EnhancedMemoryManager');
|
|
24
|
+
const MapCache = require('./utils/MapCache');
|
|
24
25
|
|
|
25
26
|
class Nexus {
|
|
26
27
|
constructor(config = {}) {
|
|
@@ -227,4 +228,5 @@ module.exports = {
|
|
|
227
228
|
clearRegistry,
|
|
228
229
|
DefaultMemoryManager,
|
|
229
230
|
EnhancedMemoryManager,
|
|
231
|
+
MapCache,
|
|
230
232
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const mongoose = require('mongoose');
|
|
2
|
-
const moment = require('moment-timezone');
|
|
3
2
|
|
|
4
3
|
const { Monitoreo_ID } = require('../config/airtableConfig');
|
|
5
4
|
|
|
@@ -19,7 +18,6 @@ const messageSchema = new mongoose.Schema({
|
|
|
19
18
|
body: { type: String, default: '' },
|
|
20
19
|
numero: { type: String, required: true },
|
|
21
20
|
nombre_whatsapp: { type: String, default: null },
|
|
22
|
-
timestamp: { type: String, required: true, default: Date.now },
|
|
23
21
|
message_id: { type: String, default: null},
|
|
24
22
|
interactive_type: {
|
|
25
23
|
type: String,
|
|
@@ -109,13 +107,6 @@ messageSchema.index({ message_id: 1 }, { name: 'message_id_idx', sparse: true })
|
|
|
109
107
|
|
|
110
108
|
messageSchema.index({ triggeredBy: 1, createdAt: -1 }, { name: 'triggered_by_idx', sparse: true });
|
|
111
109
|
|
|
112
|
-
messageSchema.pre('save', function (next) {
|
|
113
|
-
if (this.timestamp) {
|
|
114
|
-
this.timestamp = moment.tz(this.timestamp, 'America/Mexico_City').toDate();
|
|
115
|
-
}
|
|
116
|
-
next();
|
|
117
|
-
});
|
|
118
|
-
|
|
119
110
|
const Message = mongoose.model('Message', messageSchema);
|
|
120
111
|
|
|
121
112
|
async function insertMessage(values) {
|
|
@@ -168,7 +159,7 @@ async function insertMessage(values) {
|
|
|
168
159
|
|
|
169
160
|
updateRecordByFilter(Monitoreo_ID, 'message_monitor', `{whatsapp_id} = "${values.numero}"`, {
|
|
170
161
|
...(values.from_me ? { last_message_bot: values.body } : { last_message_patient: values.body, read: false }),
|
|
171
|
-
...(values.from_me ? { last_message_bot_time:
|
|
162
|
+
...(values.from_me ? { last_message_bot_time: doc.createdAt.toISOString() } : { last_message_patient_time: doc.createdAt.toISOString() })
|
|
172
163
|
}, values.numero).catch(err => logger.error('[MongoStorage] Failed to update message_monitor table', { numero: values.numero, error: err.message }));
|
|
173
164
|
|
|
174
165
|
logger.info('[MongoStorage] Message inserted or updated successfully');
|
|
@@ -179,20 +170,11 @@ async function insertMessage(values) {
|
|
|
179
170
|
}
|
|
180
171
|
}
|
|
181
172
|
|
|
182
|
-
function formatTimestamp(unixTimestamp) {
|
|
183
|
-
const date = new Date(unixTimestamp * 1000);
|
|
184
|
-
return date.toLocaleString('sv-MX', {
|
|
185
|
-
timeZone: 'America/Mexico_City',
|
|
186
|
-
hour12: false,
|
|
187
|
-
}).replace(' ', 'T').slice(0, 19);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
173
|
function getMessageValues(message, content) {
|
|
191
174
|
return {
|
|
192
175
|
nombre_whatsapp: message.pushName,
|
|
193
176
|
numero: message.key.participant || message.key.remoteJid,
|
|
194
177
|
body: content,
|
|
195
|
-
timestamp: formatTimestamp(message.messageTimestamp),
|
|
196
178
|
message_id: message.key.id,
|
|
197
179
|
group_id: message.key.remoteJid || null,
|
|
198
180
|
from_me: message.key.fromMe
|
|
@@ -223,6 +205,5 @@ module.exports = {
|
|
|
223
205
|
Message,
|
|
224
206
|
insertMessage,
|
|
225
207
|
getMessageValues,
|
|
226
|
-
formatTimestamp,
|
|
227
208
|
getContactDisplayName
|
|
228
209
|
};
|
|
@@ -97,7 +97,6 @@ class MongoStorage {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
buildMessageValues(messageData = {}) {
|
|
100
|
-
const now = new Date();
|
|
101
100
|
const messageId = messageData.messageId ?? null;
|
|
102
101
|
const fromMe = messageData.fromMe !== undefined ? messageData.fromMe : true;
|
|
103
102
|
|
|
@@ -105,7 +104,6 @@ class MongoStorage {
|
|
|
105
104
|
nombre_whatsapp: fromMe ? runtimeConfig.get('USER_DB_MONGO') : messageData.pushName,
|
|
106
105
|
numero: ensureWhatsAppFormat(messageData.code),
|
|
107
106
|
body: messageData.body || '',
|
|
108
|
-
timestamp: messageData.timestamp?.toISOString() || now.toISOString(),
|
|
109
107
|
processed: messageData.processed || false,
|
|
110
108
|
message_id: messageId,
|
|
111
109
|
interactive_type: messageData.interactive?.type || null,
|
|
@@ -172,12 +170,6 @@ class MongoStorage {
|
|
|
172
170
|
}
|
|
173
171
|
}
|
|
174
172
|
|
|
175
|
-
formatTimestamp(timestamp) {
|
|
176
|
-
const date = new Date(timestamp || Date.now());
|
|
177
|
-
const mexicoTime = new Date(date.getTime() - (6 * 60 * 60 * 1000));
|
|
178
|
-
return mexicoTime.toISOString().replace('T', ' ').slice(0, 19);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
173
|
async disconnect() {
|
|
182
174
|
await mongoDisconnect();
|
|
183
175
|
}
|
package/lib/utils/MapCache.js
CHANGED
|
@@ -8,17 +8,17 @@ class MapCache {
|
|
|
8
8
|
get(key) {
|
|
9
9
|
const k = String(key);
|
|
10
10
|
const entry = this._cache.get(k);
|
|
11
|
-
if (!entry) return
|
|
11
|
+
if (!entry) return undefined;
|
|
12
12
|
if (this._ttl && (Date.now() - entry.timestamp >= this._ttl)) {
|
|
13
13
|
this._cache.delete(k);
|
|
14
|
-
return
|
|
14
|
+
return undefined;
|
|
15
15
|
}
|
|
16
16
|
return entry.value;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
getEntry(key) {
|
|
20
20
|
const k = String(key);
|
|
21
|
-
return this._cache.get(k) ||
|
|
21
|
+
return this._cache.get(k) || undefined;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
set(key, value) {
|