@peopl-health/nexus 3.8.21 → 3.8.23
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.
|
@@ -3,7 +3,6 @@ const { v4: uuidv4 } = require('uuid');
|
|
|
3
3
|
const twilio = require('twilio');
|
|
4
4
|
|
|
5
5
|
const runtimeConfig = require('../config/runtimeConfig');
|
|
6
|
-
const { Symptoms_ID } = require('../config/airtableConfig');
|
|
7
6
|
const { generatePresignedUrl } = require('../config/awsConfig');
|
|
8
7
|
|
|
9
8
|
const { sanitizeMediaFilename } = require('../utils/sanitizerUtils');
|
|
@@ -18,8 +17,6 @@ const { uploadMediaToS3, getFileExtension } = require('../helpers/mediaHelper');
|
|
|
18
17
|
|
|
19
18
|
const { MessageProvider } = require('../adapters/MessageProvider');
|
|
20
19
|
|
|
21
|
-
const { updateRecordByFilter } = require('../services/airtableService');
|
|
22
|
-
|
|
23
20
|
class TwilioProvider extends MessageProvider {
|
|
24
21
|
constructor(config) {
|
|
25
22
|
super(config);
|
|
@@ -233,11 +230,6 @@ class TwilioProvider extends MessageProvider {
|
|
|
233
230
|
}
|
|
234
231
|
}
|
|
235
232
|
);
|
|
236
|
-
|
|
237
|
-
if (scheduledMessage.contentSid) {
|
|
238
|
-
updateRecordByFilter(Symptoms_ID, 'weekly_questionnaires', `{sid}="${scheduledMessage.contentSid}"`, { send_status: status })
|
|
239
|
-
.catch(err => logger.warn('[TwilioProvider] Failed to update weekly_questionnaires send_status', err?.message));
|
|
240
|
-
}
|
|
241
233
|
} catch (err) {
|
|
242
234
|
logger.warn('[TwilioProvider] Failed to update scheduled message status', err?.message);
|
|
243
235
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const moment = require('moment-timezone');
|
|
2
2
|
|
|
3
3
|
const runtimeConfig = require('../config/runtimeConfig');
|
|
4
|
-
const { Symptoms_ID } = require('../config/airtableConfig');
|
|
5
4
|
|
|
6
5
|
const { logger } = require('../utils/logger');
|
|
7
6
|
|
|
@@ -12,7 +11,7 @@ const FlowRouting = require('../models/flowRoutingModel.js');
|
|
|
12
11
|
const { ensureWhatsAppFormat } = require('../helpers/twilioHelper');
|
|
13
12
|
const { ensureFlowTokenInVariables } = require('../helpers/templateFlowControllerHelper');
|
|
14
13
|
|
|
15
|
-
const { getRecordByFilter: defaultGetRecordByFilter
|
|
14
|
+
const { getRecordByFilter: defaultGetRecordByFilter } = require('../services/airtableService');
|
|
16
15
|
|
|
17
16
|
const {
|
|
18
17
|
sendMessage: defaultSendMessage,
|
|
@@ -23,7 +22,6 @@ const {
|
|
|
23
22
|
const dependencies = {
|
|
24
23
|
ScheduledMessage: DefaultScheduledMessage,
|
|
25
24
|
getRecordByFilter: defaultGetRecordByFilter,
|
|
26
|
-
updateRecordByFilter: defaultUpdateRecordByFilter,
|
|
27
25
|
sendScheduledMessage: defaultSendScheduledMessage,
|
|
28
26
|
sendMessage: defaultSendMessage
|
|
29
27
|
};
|
|
@@ -62,11 +60,6 @@ const _pickMessageId = (result, fallback) =>
|
|
|
62
60
|
const _sendAndPersist = async (payload) => {
|
|
63
61
|
const saved = await dependencies.ScheduledMessage.create(payload);
|
|
64
62
|
|
|
65
|
-
if (saved.contentSid) {
|
|
66
|
-
dependencies.updateRecordByFilter(Symptoms_ID, 'weekly_questionnaires', `{sid}="${saved.contentSid}"`, { send_status: 'pending' })
|
|
67
|
-
.catch(err => logger.error('[messageController] Failed to update weekly_questionnaires send_status', { contentSid: saved.contentSid, error: err.message }));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
63
|
const result = dependencies.sendScheduledMessage
|
|
71
64
|
? await dependencies.sendScheduledMessage(saved)
|
|
72
65
|
: await dependencies.sendMessage({ ...payload, body: payload.message });
|
|
@@ -36,28 +36,6 @@ async function fetchBasePrompt(promptId) {
|
|
|
36
36
|
return record;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
async function fetchSnippets(promptId) {
|
|
40
|
-
const cacheKey = `snippets:${promptId}`;
|
|
41
|
-
const cached = snippetCache.get(cacheKey);
|
|
42
|
-
if (cached) return cached;
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const records = await getRecordByFilter(
|
|
46
|
-
Config_ID,
|
|
47
|
-
'context_snippets',
|
|
48
|
-
`FIND("${promptId}", ARRAYJOIN({prompts}))`,
|
|
49
|
-
);
|
|
50
|
-
const snippets = records || [];
|
|
51
|
-
snippetCache.set(cacheKey, snippets);
|
|
52
|
-
return snippets;
|
|
53
|
-
} catch (error) {
|
|
54
|
-
logger.error('[promptComposer] Failed to fetch snippets', {
|
|
55
|
-
promptId, error: error.message,
|
|
56
|
-
});
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
39
|
function sortSnippets(snippets) {
|
|
62
40
|
return [...snippets].sort((a, b) => {
|
|
63
41
|
const aIndex = SNIPPET_TYPE_ORDER.indexOf(a.type || '');
|
|
@@ -103,7 +81,10 @@ async function composePrompt({ presetId = null, promptId = null, variables = nul
|
|
|
103
81
|
const promptRecordId = preset.prompt?.[0];
|
|
104
82
|
if (promptRecordId) {
|
|
105
83
|
const promptRecords = await getRecordByFilter(Config_ID, 'responses', `RECORD_ID()="${promptRecordId}"`);
|
|
106
|
-
|
|
84
|
+
const presetPromptId = promptRecords?.[0]?.prompt_id;
|
|
85
|
+
if (presetPromptId) {
|
|
86
|
+
resolvedPromptId = presetPromptId;
|
|
87
|
+
}
|
|
107
88
|
}
|
|
108
89
|
} else {
|
|
109
90
|
logger.error('[promptComposer] Preset not found in Airtable', { presetId });
|
|
@@ -112,6 +93,18 @@ async function composePrompt({ presetId = null, promptId = null, variables = nul
|
|
|
112
93
|
|
|
113
94
|
const baseRecord = await fetchBasePrompt(resolvedPromptId);
|
|
114
95
|
|
|
96
|
+
// If no explicit preset was passed, check if the prompt defines one via preset_id field
|
|
97
|
+
if (!presetId && baseRecord?.preset_id) {
|
|
98
|
+
presetId = baseRecord.preset_id;
|
|
99
|
+
const preset = await fetchPreset(presetId);
|
|
100
|
+
if (preset) {
|
|
101
|
+
presetSnippetIds = preset.snippets || [];
|
|
102
|
+
presetToolIds = preset.tools || [];
|
|
103
|
+
} else {
|
|
104
|
+
logger.error('[promptComposer] Prompt-level preset not found in Airtable', { presetId, promptId: resolvedPromptId });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
115
108
|
if (!baseRecord) {
|
|
116
109
|
logger.error('[promptComposer] Base prompt not found in Airtable', { promptId: resolvedPromptId });
|
|
117
110
|
}
|
|
@@ -120,7 +113,7 @@ async function composePrompt({ presetId = null, promptId = null, variables = nul
|
|
|
120
113
|
|
|
121
114
|
const snippets = presetSnippetIds
|
|
122
115
|
? await fetchSnippetsByRecordIds(presetSnippetIds)
|
|
123
|
-
:
|
|
116
|
+
: [];
|
|
124
117
|
|
|
125
118
|
const activeSnippets = status
|
|
126
119
|
? snippets.filter(s => !s.status || s.status === status)
|
|
@@ -147,28 +140,6 @@ async function composePrompt({ presetId = null, promptId = null, variables = nul
|
|
|
147
140
|
return { resolvedPrompt, snippetIds, promptId: resolvedPromptId, presetToolIds };
|
|
148
141
|
}
|
|
149
142
|
|
|
150
|
-
async function fetchToolMapping(promptId) {
|
|
151
|
-
const cacheKey = `tools:${promptId}`;
|
|
152
|
-
const cached = toolCache.get(cacheKey);
|
|
153
|
-
if (cached) return cached;
|
|
154
|
-
|
|
155
|
-
try {
|
|
156
|
-
const records = await getRecordByFilter(
|
|
157
|
-
Config_ID,
|
|
158
|
-
'tools',
|
|
159
|
-
`FIND("${promptId}", ARRAYJOIN({prompts}))`,
|
|
160
|
-
);
|
|
161
|
-
const tools = records || [];
|
|
162
|
-
toolCache.set(cacheKey, tools);
|
|
163
|
-
return tools;
|
|
164
|
-
} catch (error) {
|
|
165
|
-
logger.warn('[promptComposer] Failed to fetch tool mapping, returning empty list', {
|
|
166
|
-
promptId, error: error.message,
|
|
167
|
-
});
|
|
168
|
-
return [];
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
143
|
async function fetchToolsByRecordIds(recordIds) {
|
|
173
144
|
if (!recordIds?.length) return [];
|
|
174
145
|
|
|
@@ -194,9 +165,9 @@ async function resolveTools({ promptId, assistant, presetToolIds = null, status
|
|
|
194
165
|
|
|
195
166
|
if (!hasRegistryTools && !hasAssistantTools) return { toolIds: [], filtered: false };
|
|
196
167
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
168
|
+
if (!presetToolIds) return { toolIds: [], filtered: false };
|
|
169
|
+
|
|
170
|
+
const mappedTools = await fetchToolsByRecordIds(presetToolIds);
|
|
200
171
|
if (!mappedTools.length) return { toolIds: [], filtered: false };
|
|
201
172
|
|
|
202
173
|
const activeTools = status
|