@peopl-health/nexus 1.7.8 → 1.7.10
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/config/mongoAuthConfig.js +3 -3
- package/lib/core/NexusMessaging.js +15 -6
- package/lib/helpers/assistantHelper.js +9 -3
- package/lib/helpers/baileysHelper.js +6 -1
- package/lib/index.d.ts +14 -0
- package/lib/index.js +8 -0
- package/lib/services/assistantService.js +1 -11
- package/lib/services/preprocessingHooks.js +28 -0
- package/package.json +5 -5
|
@@ -100,7 +100,7 @@ async function useMongoDBAuthState(uri, dbName, sessionId) {
|
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
const creds = (await readData('creds')) ||
|
|
103
|
+
const creds = (await readData('creds')) || await initAuthCreds();
|
|
104
104
|
|
|
105
105
|
return {
|
|
106
106
|
state: {
|
|
@@ -110,8 +110,8 @@ async function useMongoDBAuthState(uri, dbName, sessionId) {
|
|
|
110
110
|
const data = {};
|
|
111
111
|
await Promise.all(ids.map(async (id) => {
|
|
112
112
|
let value = await readData(`${type}-${id}`);
|
|
113
|
-
if (type === 'app-state-sync-key') {
|
|
114
|
-
value = proto.Message.AppStateSyncKeyData.fromObject(
|
|
113
|
+
if (type === 'app-state-sync-key' && value) {
|
|
114
|
+
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
|
115
115
|
}
|
|
116
116
|
data[id] = value;
|
|
117
117
|
}));
|
|
@@ -2,6 +2,7 @@ const { airtable, getBase } = require('../config/airtableConfig');
|
|
|
2
2
|
const { replyAssistant } = require('../services/assistantService');
|
|
3
3
|
const { createProvider } = require('../adapters/registry');
|
|
4
4
|
const runtimeConfig = require('../config/runtimeConfig');
|
|
5
|
+
const { hasPreprocessingHandler, invokePreprocessingHandler } = require('../services/preprocessingHooks');
|
|
5
6
|
|
|
6
7
|
const mongoose = require('mongoose');
|
|
7
8
|
const OpenAI = require('openai');
|
|
@@ -324,7 +325,16 @@ class NexusMessaging {
|
|
|
324
325
|
}
|
|
325
326
|
|
|
326
327
|
const chatId = messageData.from || messageData.From;
|
|
327
|
-
|
|
328
|
+
|
|
329
|
+
if (chatId && hasPreprocessingHandler()) {
|
|
330
|
+
const stop = await invokePreprocessingHandler({
|
|
331
|
+
code: chatId,
|
|
332
|
+
context: 'incomingMessage',
|
|
333
|
+
message: messageData
|
|
334
|
+
});
|
|
335
|
+
if (stop) return;
|
|
336
|
+
}
|
|
337
|
+
|
|
328
338
|
// Handle immediate response messages (interactive, flows, etc.)
|
|
329
339
|
if (messageData.interactive) {
|
|
330
340
|
return await this.handleInteractive(messageData);
|
|
@@ -624,11 +634,10 @@ class NexusMessaging {
|
|
|
624
634
|
|
|
625
635
|
// Get assistant response
|
|
626
636
|
const botResponse = await replyAssistant(chatId);
|
|
627
|
-
if (botResponse
|
|
628
|
-
await this.
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
type: 'text',
|
|
637
|
+
if (botResponse) {
|
|
638
|
+
await this.sendMessage({
|
|
639
|
+
code: chatId,
|
|
640
|
+
message: botResponse,
|
|
632
641
|
processed: true
|
|
633
642
|
});
|
|
634
643
|
}
|
|
@@ -31,12 +31,18 @@ async function checkRunStatus(assistant, thread_id, run_id, retryCount = 0, maxR
|
|
|
31
31
|
return true;
|
|
32
32
|
} else if (run.status === 'requires_action') {
|
|
33
33
|
console.log('requires_action');
|
|
34
|
-
if (retryCount
|
|
34
|
+
if (retryCount >= maxRetries) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
await assistant.handleRequiresAction(run);
|
|
35
38
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
36
|
-
return checkRunStatus(assistant, thread_id, run_id,
|
|
39
|
+
return checkRunStatus(assistant, thread_id, run_id, retryCount + 1, maxRetries);
|
|
37
40
|
} else if (run.status !== 'completed') {
|
|
41
|
+
if (retryCount >= maxRetries) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
38
44
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
39
|
-
return checkRunStatus(assistant, thread_id, run_id);
|
|
45
|
+
return checkRunStatus(assistant, thread_id, run_id, retryCount + 1, maxRetries);
|
|
40
46
|
} else {
|
|
41
47
|
console.log('Run completed.');
|
|
42
48
|
return true;
|
|
@@ -6,7 +6,12 @@ const { downloadMediaMessage } = require('baileys');
|
|
|
6
6
|
async function processMessage(message, messageType) {
|
|
7
7
|
try {
|
|
8
8
|
const { content, reply } = extractMessageContent(message, messageType);
|
|
9
|
-
if (content
|
|
9
|
+
if (typeof content === 'string' && content.trim().length === 0) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (content == null) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
const values = getMessageValues(message, content, reply, false);
|
|
12
17
|
await insertMessage(values);
|
package/lib/index.d.ts
CHANGED
|
@@ -130,6 +130,13 @@ declare module '@peopl-health/nexus' {
|
|
|
130
130
|
setup?: (this: BaseAssistant, context: { assistantId: string; thread?: any; options?: any }) => void;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
export interface IncomingPreprocessingPayload {
|
|
134
|
+
code: string;
|
|
135
|
+
context?: string;
|
|
136
|
+
message: MessageData;
|
|
137
|
+
[key: string]: any;
|
|
138
|
+
}
|
|
139
|
+
|
|
133
140
|
export class BaseAssistant {
|
|
134
141
|
constructor(options?: {
|
|
135
142
|
assistantId?: string;
|
|
@@ -176,6 +183,13 @@ declare module '@peopl-health/nexus' {
|
|
|
176
183
|
export function configureAssistantsLLM(client: any): void;
|
|
177
184
|
export function overrideGetAssistantById(resolver: (assistantId: string, thread?: any) => any): void;
|
|
178
185
|
export function configureAssistants(config: any): void;
|
|
186
|
+
export function setPreprocessingHandler(
|
|
187
|
+
handler: (payload: IncomingPreprocessingPayload) => any | Promise<any>
|
|
188
|
+
): void;
|
|
189
|
+
export function hasPreprocessingHandler(): boolean;
|
|
190
|
+
export function invokePreprocessingHandler(
|
|
191
|
+
payload: IncomingPreprocessingPayload
|
|
192
|
+
): Promise<boolean>;
|
|
179
193
|
|
|
180
194
|
export class TwilioProvider extends MessageProvider {
|
|
181
195
|
constructor(config: TwilioConfig);
|
package/lib/index.js
CHANGED
|
@@ -17,6 +17,11 @@ const {
|
|
|
17
17
|
const { TwilioProvider } = require('./adapters/TwilioProvider');
|
|
18
18
|
const { BaileysProvider } = require('./adapters/BaileysProvider');
|
|
19
19
|
const { BaseAssistant: CoreBaseAssistant } = require('./assistants/BaseAssistant');
|
|
20
|
+
const {
|
|
21
|
+
setPreprocessingHandler,
|
|
22
|
+
hasPreprocessingHandler,
|
|
23
|
+
invokePreprocessingHandler
|
|
24
|
+
} = require('./services/preprocessingHooks');
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
27
|
* Main Nexus class that orchestrates all components
|
|
@@ -332,6 +337,9 @@ module.exports = {
|
|
|
332
337
|
configureAssistantsLLM,
|
|
333
338
|
overrideGetAssistantById,
|
|
334
339
|
configureAssistants: setAssistantsConfig,
|
|
340
|
+
setPreprocessingHandler,
|
|
341
|
+
hasPreprocessingHandler,
|
|
342
|
+
invokePreprocessingHandler,
|
|
335
343
|
routes,
|
|
336
344
|
setupDefaultRoutes: routes.setupDefaultRoutes,
|
|
337
345
|
createRouter: routes.createRouter,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const { Historial_Clinico_ID
|
|
1
|
+
const { Historial_Clinico_ID } = require('../config/airtableConfig.js');
|
|
2
2
|
const AWS = require('../config/awsConfig.js');
|
|
3
3
|
const { combineImagesToPDF, cleanupFiles } = require('../helpers/filesHelper.js');
|
|
4
|
-
const { addRecord } = require('../services/airtableService.js');
|
|
5
4
|
const runtimeConfig = require('../config/runtimeConfig');
|
|
6
5
|
const llmConfig = require('../config/llmConfig');
|
|
7
6
|
const { BaseAssistant } = require('../assistants/BaseAssistant');
|
|
@@ -389,15 +388,6 @@ const replyAssistant = async function (code, message_ = null, thread_ = null, ru
|
|
|
389
388
|
const bucket = runtimeConfig.get('AWS_S3_BUCKET_NAME');
|
|
390
389
|
if (bucket && pdfBuffer) {
|
|
391
390
|
await AWS.uploadBufferToS3(pdfBuffer, bucket, key, 'application/pdf');
|
|
392
|
-
const url = await AWS.generatePresignedUrl(bucket, key);
|
|
393
|
-
const curRow = await getCurRow(Monitoreo_ID, code);
|
|
394
|
-
const customer_id = curRow?.[0]?.recordID || curRow?.[0]?.record_id || curRow?.[0]?.id || null;
|
|
395
|
-
console.log('customer_id:', customer_id);
|
|
396
|
-
try {
|
|
397
|
-
await addRecord(Monitoreo_ID, 'estudios', [{ fields: { estudios: urls, combined_estudios: [{ url }], patient_id: customer_id ? [customer_id] : [] } }]);
|
|
398
|
-
} catch (e) {
|
|
399
|
-
console.warn('Failed to add Airtable estudios record:', e?.message || e);
|
|
400
|
-
}
|
|
401
391
|
}
|
|
402
392
|
if (processedFiles && processedFiles.length) {
|
|
403
393
|
await cleanupFiles(processedFiles);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let preprocessingHandler = null;
|
|
2
|
+
|
|
3
|
+
const setPreprocessingHandler = (handler) => {
|
|
4
|
+
if (typeof handler === 'function') {
|
|
5
|
+
preprocessingHandler = handler;
|
|
6
|
+
} else {
|
|
7
|
+
preprocessingHandler = null;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const hasPreprocessingHandler = () => typeof preprocessingHandler === 'function';
|
|
12
|
+
|
|
13
|
+
const invokePreprocessingHandler = async (payload) => {
|
|
14
|
+
if (!hasPreprocessingHandler()) return false;
|
|
15
|
+
try {
|
|
16
|
+
const result = await preprocessingHandler(payload);
|
|
17
|
+
return Boolean(result);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.warn('[PreprocessingHooks] Handler threw an error:', error?.message || error);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
setPreprocessingHandler,
|
|
26
|
+
hasPreprocessingHandler,
|
|
27
|
+
invokePreprocessingHandler
|
|
28
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peopl-health/nexus",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.10",
|
|
4
4
|
"description": "Core messaging and assistant library for WhatsApp communication platforms",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"whatsapp",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"mongoose": "^7.5.0",
|
|
79
79
|
"multer": "1.4.5-lts.1",
|
|
80
80
|
"pdf-lib": "1.17.1",
|
|
81
|
-
"pino": "
|
|
81
|
+
"pino": "10.0.0",
|
|
82
82
|
"pino-pretty": "^10.2.0",
|
|
83
83
|
"uuid": "^9.0.0"
|
|
84
84
|
},
|
|
@@ -90,11 +90,11 @@
|
|
|
90
90
|
"typescript": "^5.1.6"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
|
+
"@anthropic-ai/sdk": "^0.32.0",
|
|
93
94
|
"baileys": "^6.4.0",
|
|
94
95
|
"express": "4.21.2",
|
|
95
96
|
"openai": "^4.0.0",
|
|
96
|
-
"twilio": "5.6.0"
|
|
97
|
-
"@anthropic-ai/sdk": "^0.32.0"
|
|
97
|
+
"twilio": "5.6.0"
|
|
98
98
|
},
|
|
99
99
|
"engines": {
|
|
100
100
|
"node": ">=20.0.0"
|
|
@@ -102,4 +102,4 @@
|
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|
|
104
104
|
}
|
|
105
|
-
}
|
|
105
|
+
}
|