@peopl-health/nexus 1.1.4 → 1.1.6

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.
@@ -1,6 +1,12 @@
1
1
  const { Historial_Clinico_ID } = require('../config/airtableConfig.js');
2
- const { SALES_ASST, QUMIO_REMINDERS_ASST, DOCTOR_SCHEDULE_ASST, PATIENT_SCHEDULE_ASST } = require('../config/assistantConfig.js');
3
- const { openaiClient } = require('../config/llmConfig.js');
2
+
3
+ let llmProvider = null;
4
+ const configureLLMProvider = (provider) => {
5
+ llmProvider = provider;
6
+ };
7
+
8
+ let assistantConfig = null;
9
+ let assistantRegistry = {};
4
10
 
5
11
  const { Message, formatTimestamp } = require('../models/messageModel.js');
6
12
  const { Thread } = require('../models/threadModel.js');
@@ -9,26 +15,28 @@ const { checkRunStatus, getCurRow } = require('../helpers/assistantHelper.js');
9
15
  const { processMessage, getLastMessages } = require('../helpers/assistantHelper.js');
10
16
  const { delay } = require('../helpers/whatsappHelper.js');
11
17
 
12
- const { GeneralAssistant } = require('../assistants/generalAssistant.js');
13
- const { SalesAssistant } = require('../assistants/salesAssistant.js');
14
- const { QumioRemindersAssistant } = require('../assistants/qumioRemindersAssistant.js');
15
- const { DoctorScheduleAssistant } = require('../assistants/doctorScheduleAssistant.js');
16
- const { PatientScheduleAssistant } = require('../assistants/patientScheduleAssistant.js');
18
+ const configureAssistants = (config) => {
19
+ if (!config) {
20
+ throw new Error('Assistant configuration is required');
21
+ }
22
+ assistantConfig = config;
23
+ };
17
24
 
25
+ const registerAssistant = (assistantId, AssistantClass) => {
26
+ assistantRegistry[assistantId] = AssistantClass;
27
+ };
18
28
 
19
29
  const getAssistantById = (assistant_id, thread) => {
20
- switch (assistant_id) {
21
- case SALES_ASST:
22
- return new SalesAssistant(thread);
23
- case QUMIO_REMINDERS_ASST:
24
- return new QumioRemindersAssistant(thread);
25
- case DOCTOR_SCHEDULE_ASST:
26
- return new DoctorScheduleAssistant(thread);
27
- case PATIENT_SCHEDULE_ASST:
28
- return new PatientScheduleAssistant(thread);
29
- default:
30
- return new GeneralAssistant(thread);
30
+ if (!assistantConfig) {
31
+ throw new Error('Assistants not configured. Call configureAssistants() first.');
32
+ }
33
+
34
+ const AssistantClass = assistantRegistry[assistant_id];
35
+ if (!AssistantClass) {
36
+ throw new Error(`Assistant '${assistant_id}' not found. Available assistants: ${Object.keys(assistantRegistry).join(', ')}`);
31
37
  }
38
+
39
+ return new AssistantClass(thread);
32
40
  };
33
41
 
34
42
 
@@ -50,7 +58,7 @@ const createAssistant = async (code, assistant_id, messages=[], prevThread=null)
50
58
 
51
59
  // Add new messages to memory
52
60
  for (const message of messages) {
53
- await openaiClient.beta.threads.messages.create(
61
+ await llmProvider.beta.threads.messages.create(
54
62
  initialThread.id, { role: 'assistant', content: message }
55
63
  );
56
64
  }
@@ -73,7 +81,7 @@ const createAssistant = async (code, assistant_id, messages=[], prevThread=null)
73
81
 
74
82
  // Delete previous thread
75
83
  if (prevThread) {
76
- await openaiClient.beta.threads.del(prevThread.thread_id);
84
+ await llmProvider.beta.threads.del(prevThread.thread_id);
77
85
  }
78
86
 
79
87
  return thread;
@@ -87,7 +95,7 @@ const addMsgAssistant = async (code, inMessages, reply = false) => {
87
95
 
88
96
  for (const message of inMessages) {
89
97
  console.log(message);
90
- await openaiClient.beta.threads.messages.create(
98
+ await llmProvider.beta.threads.messages.create(
91
99
  thread.thread_id, { role: 'assistant', content: message }
92
100
  );
93
101
  }
@@ -95,7 +103,7 @@ const addMsgAssistant = async (code, inMessages, reply = false) => {
95
103
  if (!reply) return null;
96
104
 
97
105
  const assistant = getAssistantById(thread.assistant_id, thread);
98
- const run = await openaiClient.beta.threads.runs.create(
106
+ const run = await llmProvider.beta.threads.runs.create(
99
107
  thread.thread_id,
100
108
  {
101
109
  assistant_id: thread.assistant_id
@@ -106,7 +114,7 @@ const addMsgAssistant = async (code, inMessages, reply = false) => {
106
114
  await checkRunStatus(assistant, run.thread_id, run.id);
107
115
  await Thread.updateOne({ code: thread.code, active: true }, { $set: { run_id: null } });
108
116
 
109
- const messages = await openaiClient.beta.threads.messages.list(run.thread_id, { run_id: run.id });
117
+ const messages = await llmProvider.beta.threads.messages.list(run.thread_id, { run_id: run.id });
110
118
  const ans = messages.data[0].content[0].text.value;
111
119
  console.log('THE ANS IS', ans);
112
120
 
@@ -124,7 +132,7 @@ const addInsAssistant = async (code, instruction) => {
124
132
  if (thread === null) return null;
125
133
 
126
134
  const assistant = getAssistantById(thread.assistant_id, thread);
127
- const run = await openaiClient.beta.threads.runs.create(
135
+ const run = await llmProvider.beta.threads.runs.create(
128
136
  thread.thread_id, {
129
137
  assistant_id: thread.assistant_id,
130
138
  additional_instructions: instruction,
@@ -138,7 +146,7 @@ const addInsAssistant = async (code, instruction) => {
138
146
  await checkRunStatus(assistant, run.thread_id, run.id);
139
147
  await Thread.updateOne({ code: thread.code, active: true }, { $set: { run_id: null } });
140
148
 
141
- const messages = await openaiClient.beta.threads.messages.list(run.thread_id, { run_id: run.id });
149
+ const messages = await llmProvider.beta.threads.messages.list(run.thread_id, { run_id: run.id });
142
150
  console.log(messages.data[0].content);
143
151
  const ans = messages.data[0].content[0].text.value;
144
152
 
@@ -166,7 +174,7 @@ const getThread = async (code, message = null) => {
166
174
 
167
175
  while (thread && thread.run_id) {
168
176
  console.log(`Wait for ${thread.run_id} to be executed`);
169
- const run = await openaiClient.beta.threads.runs.retrieve(thread.thread_id, thread.run_id);
177
+ const run = await llmProvider.beta.threads.runs.retrieve(thread.thread_id, thread.run_id);
170
178
  if (run.status === 'cancelled' || run.status === 'expired' || run.status === 'completed') {
171
179
  await Thread.updateOne({ code: code }, { $set: { run_id: null } });
172
180
  }
@@ -204,11 +212,11 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
204
212
  return null;
205
213
  }
206
214
 
207
- let activeRuns = await openaiClient.beta.threads.runs.list(thread.thread_id);
215
+ let activeRuns = await llmProvider.beta.threads.runs.list(thread.thread_id);
208
216
  console.log('ACTIVE RUNS:', activeRuns.length);
209
217
  while (activeRuns.length > 0) {
210
218
  console.log(`ACTIVE RUNS ${thread.thread_id}`);
211
- activeRuns = await openaiClient.beta.threads.runs.list(thread.thread_id);
219
+ activeRuns = await llmProvider.beta.threads.runs.list(thread.thread_id);
212
220
  await delay(5000);
213
221
  }
214
222
 
@@ -223,21 +231,6 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
223
231
 
224
232
  if (urls.length > 0) {
225
233
  console.log('urls', urls);
226
- /*for (const url of urls) {
227
- console.log("url", url);
228
- await addRecord(Monitoreo_ID, 'estudios', [{"fields": {"estudios": urls,
229
- "combined_estudios": [ { "url": url} ], "patient_id": [thread.patient_id]}}]);
230
- }
231
- const { pdfBuffer, processedFiles } = await combineImagesToPDF(code);
232
- console.log("AFTER COMBINED IN BUFFER", processedFiles);
233
- const key = `${code}-${Date.now()}-combined.pdf`;
234
- await AWS.uploadBufferToS3(pdfBuffer, bucketName, key, "application/pdf");
235
- const url = await AWS.generatePresignedUrl(bucketName, key);
236
- console.log("New record", {"estudios": urls, "combined_estudios":
237
- [ { "url": url} ], "patient_id": [thread.patient_id]});
238
- await addRecord(Monitoreo_ID, 'estudios', [{"fields": {"estudios": urls,
239
- "combined_estudios": [ { "url": url} ], "patient_id": [thread.patient_id]}}]);
240
- await cleanupFiles(processedFiles);*/
241
234
  }
242
235
 
243
236
  thread = await getThread(code);
@@ -245,7 +238,7 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
245
238
  if (!patientMsg || !thread || thread?.stopped) return null;
246
239
 
247
240
  const assistant = getAssistantById(thread.assistant_id, thread);
248
- const run = await openaiClient.beta.threads.runs.create(
241
+ const run = await llmProvider.beta.threads.runs.create(
249
242
  thread.thread_id,
250
243
  {
251
244
  assistant_id: thread.assistant_id,
@@ -261,7 +254,7 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
261
254
  console.log('RUN STATUS', runStatus);
262
255
  await Thread.updateOne({ code: thread.code, active: true }, { $set: { run_id: null } });
263
256
 
264
- const messages = await openaiClient.beta.threads.messages.list(run.thread_id, { run_id: run.id });
257
+ const messages = await llmProvider.beta.threads.messages.list(run.thread_id, { run_id: run.id });
265
258
  const reply = messages.data?.[0]?.content?.[0]?.text?.value || '';
266
259
  console.log(reply);
267
260
 
@@ -292,5 +285,8 @@ module.exports = {
292
285
  replyAssistant,
293
286
  addMsgAssistant,
294
287
  addInsAssistant,
295
- switchAssistant
288
+ switchAssistant,
289
+ configureAssistants,
290
+ registerAssistant,
291
+ configureLLMProvider
296
292
  };
@@ -54,9 +54,9 @@ class MongoStorage {
54
54
  });
55
55
 
56
56
  return {
57
- Message: mongoose.model('Message', messageSchema),
58
- Interaction: mongoose.model('Interaction', interactionSchema),
59
- Thread: mongoose.model('Thread', threadSchema)
57
+ Message: mongoose.models.Message || mongoose.model('Message', messageSchema),
58
+ Interaction: mongoose.models.Interaction || mongoose.model('Interaction', interactionSchema),
59
+ Thread: mongoose.models.Thread || mongoose.model('Thread', threadSchema)
60
60
  };
61
61
  }
62
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -51,10 +51,12 @@
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
53
  "airtable": "^0.12.2",
54
+ "aws-sdk": "2.1674.0",
54
55
  "axios": "^1.5.0",
55
56
  "dotenv": "^16.4.7",
56
57
  "moment-timezone": "^0.5.43",
57
58
  "mongoose": "^7.5.0",
59
+ "pdf-lib": "1.17.1",
58
60
  "pino": "^8.15.0",
59
61
  "pino-pretty": "^10.2.0",
60
62
  "uuid": "^9.0.0"
@@ -69,6 +71,7 @@
69
71
  "@types/node": "^20.5.0",
70
72
  "eslint": "^8.47.0",
71
73
  "jest": "^29.6.2",
74
+ "sharp": "0.32.6",
72
75
  "typescript": "^5.1.6"
73
76
  },
74
77
  "engines": {
@@ -1,23 +0,0 @@
1
- let sendMessage;
2
- let sendScheduledMessage;
3
- if (process.env.MESSAGING_PROVIDER === 'baileys') {
4
- const baileyAdapter = require('../adapters/baileys');
5
- console.log('Baileys adapter:', baileyAdapter);
6
- console.log('Has sendMessage?', 'sendMessage' in baileyAdapter);
7
- sendMessage = baileyAdapter.sendMessage;
8
- sendScheduledMessage = baileyAdapter.sendScheduledMessage;
9
- } else if (process.env.MESSAGING_PROVIDER === 'twilio') {
10
- const { sendMessage: twilioSendMessage } = require('../messaging/messageService');
11
- const { sendScheduledMessage: twilioSendScheduledMessage } = require('../messaging/scheduledMessageService');
12
- const twilioAdapter = require('../adapters/twilio');
13
- const twilioClient = twilioAdapter.twilioClient;
14
- sendMessage = (messageData) => twilioSendMessage(twilioClient, messageData);
15
- sendScheduledMessage = (messageData) => twilioSendScheduledMessage(twilioClient, messageData);
16
- } else {
17
- throw new Error('Unsupported MESSAGING_PROVIDER specified');
18
- }
19
-
20
- module.exports = {
21
- sendMessage,
22
- sendScheduledMessage
23
- };