@peopl-health/nexus 2.0.13 → 2.0.15
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/TwilioProvider.js +1 -2
- package/lib/core/NexusMessaging.js +2 -1
- package/lib/helpers/assistantHelper.js +2 -3
- package/lib/helpers/llmsHelper.js +1 -1
- package/lib/models/messageModel.js +7 -6
- package/lib/services/assistantService.js +48 -17
- package/lib/storage/MongoStorage.js +8 -31
- package/package.json +1 -1
|
@@ -61,10 +61,9 @@ class TwilioProvider extends MessageProvider {
|
|
|
61
61
|
|
|
62
62
|
// Handle template messages
|
|
63
63
|
if (contentSid) {
|
|
64
|
-
// Render template and add to messageData for storage
|
|
65
64
|
const renderedMessage = await this.renderTemplate(contentSid, variables);
|
|
66
65
|
if (renderedMessage) {
|
|
67
|
-
messageData.body = renderedMessage;
|
|
66
|
+
messageData.body = renderedMessage;
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
messageParams.contentSid = contentSid;
|
|
@@ -16,7 +16,7 @@ const moment = require('moment-timezone');
|
|
|
16
16
|
const mode = process.env.NODE_ENV || 'dev';
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
async function checkRunStatus(assistant, thread_id, run_id, retryCount = 0, maxRetries =
|
|
19
|
+
async function checkRunStatus(assistant, thread_id, run_id, retryCount = 0, maxRetries = 10, actionHandled = false) {
|
|
20
20
|
try {
|
|
21
21
|
const provider = createProvider({ variant: process.env.VARIANT || 'assistants' });
|
|
22
22
|
const run = await provider.getRun({ threadId: thread_id, runId: run_id });
|
|
@@ -295,13 +295,12 @@ async function processIndividualMessage(code, reply, provider, thread) {
|
|
|
295
295
|
// ONLY add user messages to the thread
|
|
296
296
|
const threadId = process.env.VARIANT === 'responses' ? thread?.conversation_id : thread?.thread_id;
|
|
297
297
|
if (isNotAssistant) {
|
|
298
|
-
console.log('Adding user message to thread', thread);
|
|
299
298
|
await provider.addMessage({
|
|
300
299
|
threadId,
|
|
301
300
|
role: 'user',
|
|
302
301
|
content: messagesChat
|
|
303
302
|
});
|
|
304
|
-
console.log(
|
|
303
|
+
console.log(`[processIndividualMessage] User message added to thread ${threadId}`);
|
|
305
304
|
}
|
|
306
305
|
|
|
307
306
|
await Message.updateOne(
|
|
@@ -45,7 +45,7 @@ async function analyzeImage(imagePath) {
|
|
|
45
45
|
// Descrciption of the image
|
|
46
46
|
const imageDescription = 'Describe the image in detail.';
|
|
47
47
|
const messageDescription = await anthropicClient.messages.create({
|
|
48
|
-
model: 'claude-
|
|
48
|
+
model: 'claude-sonnet-4-5',
|
|
49
49
|
max_tokens: 1024,
|
|
50
50
|
messages: [
|
|
51
51
|
{
|
|
@@ -29,8 +29,8 @@ const messageSchema = new mongoose.Schema({
|
|
|
29
29
|
from_me: { type: Boolean, default: false },
|
|
30
30
|
origin: {
|
|
31
31
|
type: String,
|
|
32
|
-
enum: ['
|
|
33
|
-
default: '
|
|
32
|
+
enum: ['whatsapp_platform', 'assistant', 'patient'],
|
|
33
|
+
default: 'whatsapp_platform' },
|
|
34
34
|
media: {
|
|
35
35
|
contentType: { type: String, default: null },
|
|
36
36
|
bucketName: { type: String, default: null },
|
|
@@ -102,9 +102,10 @@ async function insertMessage(values) {
|
|
|
102
102
|
media: values.media ? values.media : null,
|
|
103
103
|
content_sid: values.content_sid || null,
|
|
104
104
|
clinical_context: clinical_context,
|
|
105
|
+
origin: values.origin,
|
|
105
106
|
raw: values.raw || null
|
|
106
107
|
};
|
|
107
|
-
console.log('Inserting message', messageData);
|
|
108
|
+
console.log('[MongoStorage] Inserting message', messageData);
|
|
108
109
|
|
|
109
110
|
await Message.findOneAndUpdate(
|
|
110
111
|
{ message_id: values.message_id, body: values.body },
|
|
@@ -112,9 +113,9 @@ async function insertMessage(values) {
|
|
|
112
113
|
{ upsert: true, new: true }
|
|
113
114
|
);
|
|
114
115
|
|
|
115
|
-
console.log('Message inserted or updated successfully');
|
|
116
|
+
console.log('[MongoStorage] Message inserted or updated successfully');
|
|
116
117
|
} catch (err) {
|
|
117
|
-
console.error('Error inserting message:', err);
|
|
118
|
+
console.error('[MongoStorage] Error inserting message:', err);
|
|
118
119
|
throw err;
|
|
119
120
|
}
|
|
120
121
|
}
|
|
@@ -166,7 +167,7 @@ async function getContactDisplayName(contactNumber) {
|
|
|
166
167
|
return contactNumber;
|
|
167
168
|
}
|
|
168
169
|
} catch (error) {
|
|
169
|
-
console.error(
|
|
170
|
+
console.error('[MongoStorage] Error fetching display name for ${contactNumber}:', error);
|
|
170
171
|
return contactNumber;
|
|
171
172
|
}
|
|
172
173
|
}
|
|
@@ -265,10 +265,20 @@ const addMsgAssistant = async (code, inMessages, reply = false) => {
|
|
|
265
265
|
|
|
266
266
|
if (!reply) return null;
|
|
267
267
|
|
|
268
|
+
let output, completed;
|
|
269
|
+
let retries = 0;
|
|
270
|
+
const maxRetries = 10;
|
|
268
271
|
const assistant = getAssistantById(thread?.prompt_id || thread?.assistant_id, thread);
|
|
269
|
-
|
|
270
|
-
|
|
272
|
+
do {
|
|
273
|
+
({ output, completed } = await runAssistantAndWait({ thread, assistant }));
|
|
274
|
+
console.log(`Attempt ${retries + 1}: completed=${completed}, output=${output || '(empty)'}`);
|
|
275
|
+
|
|
276
|
+
if (completed && output) break;
|
|
277
|
+
if (retries < maxRetries) await new Promise(resolve => setTimeout(resolve, 2000));
|
|
278
|
+
retries++;
|
|
279
|
+
} while (retries <= maxRetries && (!completed || !output));
|
|
271
280
|
|
|
281
|
+
console.log('THE ANS IS', output);
|
|
272
282
|
return output;
|
|
273
283
|
} catch (error) {
|
|
274
284
|
console.log(error);
|
|
@@ -282,17 +292,27 @@ const addInsAssistant = async (code, instruction) => {
|
|
|
282
292
|
console.log(thread);
|
|
283
293
|
if (thread === null) return null;
|
|
284
294
|
|
|
295
|
+
let output, completed;
|
|
296
|
+
let retries = 0;
|
|
297
|
+
const maxRetries = 10;
|
|
285
298
|
const assistant = getAssistantById(thread?.prompt_id || thread?.assistant_id, thread);
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
299
|
+
do {
|
|
300
|
+
({ output, completed } = await runAssistantAndWait({
|
|
301
|
+
thread,
|
|
302
|
+
assistant,
|
|
303
|
+
runConfig: {
|
|
304
|
+
additionalInstructions: instruction,
|
|
305
|
+
additionalMessages: [
|
|
306
|
+
{ role: 'user', content: instruction }
|
|
307
|
+
]
|
|
308
|
+
}
|
|
309
|
+
}));
|
|
310
|
+
console.log(`Attempt ${retries + 1}: completed=${completed}, output=${output || '(empty)'}`);
|
|
311
|
+
|
|
312
|
+
if (completed && output) break;
|
|
313
|
+
if (retries < maxRetries) await new Promise(resolve => setTimeout(resolve, 2000));
|
|
314
|
+
retries++;
|
|
315
|
+
} while (retries <= maxRetries && (!completed || !output));
|
|
296
316
|
console.log('RUN RESPONSE', output);
|
|
297
317
|
|
|
298
318
|
return output;
|
|
@@ -399,11 +419,22 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
|
|
|
399
419
|
const assistant = getAssistantById(process.env.VARIANT === 'responses' ? thread?.prompt_id : thread?.assistant_id, thread);
|
|
400
420
|
assistant.setReplies(patientReply);
|
|
401
421
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
422
|
+
let run, output, completed;
|
|
423
|
+
let retries = 0;
|
|
424
|
+
const maxRetries = 10;
|
|
425
|
+
do {
|
|
426
|
+
({ run, output, completed } = await runAssistantAndWait({
|
|
427
|
+
thread,
|
|
428
|
+
assistant,
|
|
429
|
+
runConfig: runOptions
|
|
430
|
+
}));
|
|
431
|
+
console.log(`Attempt ${retries + 1}: completed=${completed}, output=${output || '(empty)'}`);
|
|
432
|
+
|
|
433
|
+
if (completed && output) break;
|
|
434
|
+
if (retries < maxRetries) await new Promise(resolve => setTimeout(resolve, 2000));
|
|
435
|
+
retries++;
|
|
436
|
+
} while (retries <= maxRetries && (!completed || !output));
|
|
437
|
+
|
|
407
438
|
console.log('RUN LAST ERROR:', run?.last_error);
|
|
408
439
|
console.log('RUN STATUS', completed);
|
|
409
440
|
console.log(output);
|
|
@@ -18,32 +18,13 @@ class MongoStorage {
|
|
|
18
18
|
|
|
19
19
|
createSchemas() {
|
|
20
20
|
const { Message } = require('../models/messageModel');
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
numero: String,
|
|
24
|
-
interactive_type: String, // 'button', 'list', 'flow'
|
|
25
|
-
payload: mongoose.Schema.Types.Mixed,
|
|
26
|
-
timestamp: String,
|
|
27
|
-
createdAt: { type: Date, default: Date.now }
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const threadSchema = new mongoose.Schema({
|
|
31
|
-
code: String,
|
|
32
|
-
assistantId: String,
|
|
33
|
-
threadId: String,
|
|
34
|
-
patientId: String,
|
|
35
|
-
runId: String,
|
|
36
|
-
nombre: String,
|
|
37
|
-
active: { type: Boolean, default: true },
|
|
38
|
-
stopped: { type: Boolean, default: false },
|
|
39
|
-
nextSid: [String],
|
|
40
|
-
createdAt: { type: Date, default: Date.now }
|
|
41
|
-
});
|
|
21
|
+
const { Interaction } = require('../models/interactionModel');
|
|
22
|
+
const { Thread } = require('../models/threadModel');
|
|
42
23
|
|
|
43
24
|
return {
|
|
44
25
|
Message,
|
|
45
|
-
Interaction
|
|
46
|
-
Thread
|
|
26
|
+
Interaction,
|
|
27
|
+
Thread
|
|
47
28
|
};
|
|
48
29
|
}
|
|
49
30
|
|
|
@@ -61,18 +42,12 @@ class MongoStorage {
|
|
|
61
42
|
|
|
62
43
|
async saveMessage(messageData) {
|
|
63
44
|
try {
|
|
64
|
-
console.log('[MongoStorage] Saving message', messageData);
|
|
65
45
|
const enrichedMessage = await this._enrichTwilioMedia(messageData);
|
|
66
46
|
console.log('[MongoStorage] Enriched message', enrichedMessage);
|
|
67
47
|
const values = this.buildMessageValues(enrichedMessage);
|
|
68
48
|
const { insertMessage } = require('../models/messageModel');
|
|
69
49
|
await insertMessage(values);
|
|
70
|
-
console.log('[MongoStorage] Message stored'
|
|
71
|
-
messageId: values.message_id,
|
|
72
|
-
numero: values.numero,
|
|
73
|
-
isMedia: values.is_media,
|
|
74
|
-
hasMediaPayload: Boolean(values.media)
|
|
75
|
-
});
|
|
50
|
+
console.log('[MongoStorage] Message stored');
|
|
76
51
|
return values;
|
|
77
52
|
} catch (error) {
|
|
78
53
|
console.error('Error saving message:', error);
|
|
@@ -172,6 +147,7 @@ class MongoStorage {
|
|
|
172
147
|
const timestamp = now.toISOString();
|
|
173
148
|
const nombre = messageData.nombre_whatsapp || messageData.author || messageData.fromName || runtimeConfig.get('USER_DB_MONGO') || process.env.USER_DB_MONGO || 'Nexus';
|
|
174
149
|
const processed = messageData.processed || false;
|
|
150
|
+
const origin = messageData.origin || 'whatsapp_platform';
|
|
175
151
|
|
|
176
152
|
// Use message body directly (template rendering is now handled by the provider)
|
|
177
153
|
let textBody = messageData.body;
|
|
@@ -210,7 +186,8 @@ class MongoStorage {
|
|
|
210
186
|
media,
|
|
211
187
|
content_sid: messageData.contentSid || null,
|
|
212
188
|
template_variables: messageData.variables ? JSON.stringify(messageData.variables) : null,
|
|
213
|
-
raw: messageData.raw || null
|
|
189
|
+
raw: messageData.raw || null,
|
|
190
|
+
origin
|
|
214
191
|
};
|
|
215
192
|
}
|
|
216
193
|
|