@awell-health/awell-extensions 2.0.211 → 2.0.213

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.
Files changed (31) hide show
  1. package/dist/extensions/awell/v1/actions/updatePatient/config/getTimezones.js +37 -4
  2. package/dist/extensions/awell/v1/actions/updatePatient/config/getTimezones.js.map +1 -1
  3. package/dist/extensions/mailgun/settings.d.ts +2 -2
  4. package/dist/extensions/math/v1/actions/generateRandomNumber/config/fields.d.ts +2 -2
  5. package/dist/extensions/shelly/actions/summarizeForm/summarizeForm.js +13 -17
  6. package/dist/extensions/shelly/actions/summarizeForm/summarizeForm.js.map +1 -1
  7. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/prompt.d.ts +1 -1
  8. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/prompt.js +98 -48
  9. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/prompt.js.map +1 -1
  10. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/summarizeTrackOutcomeWithLLM.evaluate.d.ts +1 -0
  11. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/summarizeTrackOutcomeWithLLM.evaluate.js +151 -0
  12. package/dist/extensions/shelly/actions/summarizeTrackOutcome/lib/summarizeTrackOutcomeWithLLM/summarizeTrackOutcomeWithLLM.evaluate.js.map +1 -0
  13. package/dist/extensions/shelly/actions/summarizeTrackOutcome/summarizeTrackOutcome.js +14 -19
  14. package/dist/extensions/shelly/actions/summarizeTrackOutcome/summarizeTrackOutcome.js.map +1 -1
  15. package/dist/extensions/shelly/lib/getCareFlowDetails/getCareFlowDetails.d.ts +15 -0
  16. package/dist/extensions/shelly/lib/getCareFlowDetails/getCareFlowDetails.js +98 -0
  17. package/dist/extensions/shelly/lib/getCareFlowDetails/getCareFlowDetails.js.map +1 -0
  18. package/dist/extensions/shelly/lib/getCareFlowDetails/index.d.ts +1 -0
  19. package/dist/extensions/shelly/lib/getCareFlowDetails/index.js +18 -0
  20. package/dist/extensions/shelly/lib/getCareFlowDetails/index.js.map +1 -0
  21. package/dist/extensions/shelly/lib/getTrackData/getTrackData.d.ts +6 -53
  22. package/dist/extensions/shelly/lib/getTrackData/getTrackData.js +557 -372
  23. package/dist/extensions/shelly/lib/getTrackData/getTrackData.js.map +1 -1
  24. package/dist/extensions/shelly/lib/getTrackData/index.d.ts +1 -1
  25. package/dist/extensions/shelly/lib/getTrackData/index.js +15 -3
  26. package/dist/extensions/shelly/lib/getTrackData/index.js.map +1 -1
  27. package/dist/extensions/shelly/lib/getTrackData/types.d.ts +193 -0
  28. package/dist/extensions/shelly/lib/getTrackData/types.js +3 -0
  29. package/dist/extensions/shelly/lib/getTrackData/types.js.map +1 -0
  30. package/dist/extensions/talkDesk/settings.d.ts +2 -2
  31. package/package.json +2 -1
@@ -1,408 +1,593 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTrackData = void 0;
4
- const cleanDataForLLM = async (data, awellSdk, pathwayId) => {
5
- var _a;
4
+ const lodash_1 = require("lodash");
5
+ /**
6
+ * Fetch and process track data from Awell SDK
7
+ * @param params Input parameters for fetching track data
8
+ * @returns Processed track data with steps and activities
9
+ */
10
+ const getTrackData = async ({ awellSdk, pathwayId, trackId, currentActivityId, }) => {
11
+ var _a, _b, _c, _d, _e, _f, _g;
12
+ // Validate input parameters
13
+ if ((0, lodash_1.isNil)(awellSdk))
14
+ throw new Error('AwellSdk is required');
15
+ if ((0, lodash_1.isEmpty)(pathwayId))
16
+ throw new Error('PathwayId is required');
17
+ if ((0, lodash_1.isEmpty)(trackId))
18
+ throw new Error('TrackId is required');
19
+ if ((0, lodash_1.isEmpty)(currentActivityId))
20
+ throw new Error('CurrentActivityId is required');
21
+ // 1. Make a single combined query for all data
22
+ const combinedQuery = await fetchAllTrackData(awellSdk, pathwayId);
23
+ // 2. Find current activity cutoff date
24
+ const activities = (_b = (_a = combinedQuery.pathwayActivities) === null || _a === void 0 ? void 0 : _a.activities) !== null && _b !== void 0 ? _b : [];
25
+ const currentActivity = activities.find(activity => activity.id === currentActivityId);
26
+ const currentActivityDate = (_c = currentActivity === null || currentActivity === void 0 ? void 0 : currentActivity.date) !== null && _c !== void 0 ? _c : '';
27
+ // 3. Filter activities for this track
28
+ const trackActivities = filterTrackActivities(activities, trackId, currentActivityDate);
29
+ // 4. Get and process steps for this track
30
+ const elements = (_e = (_d = combinedQuery.pathwayElements) === null || _d === void 0 ? void 0 : _d.elements) !== null && _e !== void 0 ? _e : [];
31
+ const trackSteps = filterTrackSteps(elements, trackId);
32
+ // 5. Process data points for activities
33
+ const dataPoints = (_g = (_f = combinedQuery.pathwayDataPoints) === null || _f === void 0 ? void 0 : _f.dataPoints) !== null && _g !== void 0 ? _g : [];
34
+ const activityDataPointsMap = createDataPointsMap(dataPoints);
35
+ // 6. Extract activities with forms for processing
36
+ const activitiesWithForms = extractActivitiesWithForms(trackActivities);
37
+ // 7. Process form definitions and responses
38
+ const { formDefinitionsMap, formResponsesMap } = await processFormDefinitionsAndResponses(awellSdk, pathwayId, activitiesWithForms);
39
+ // 8. Try to extract message activities and fetch message content, but continue if it fails
40
+ let messageContentsMap = new Map();
41
+ try {
42
+ const messageActivities = extractMessageActivities(trackActivities);
43
+ messageContentsMap = await fetchMessageContents(awellSdk, messageActivities);
44
+ }
45
+ catch (error) {
46
+ // Continue without message data
47
+ }
48
+ // 9. Process steps with activities
49
+ const processedSteps = trackSteps.map(step => processStep(step, trackActivities, activityDataPointsMap, formDefinitionsMap, formResponsesMap, messageContentsMap));
6
50
  return {
7
- track: {
8
- title: (_a = data.track.title) !== null && _a !== void 0 ? _a : 'Untitled Track',
9
- },
10
- steps: await Promise.all(data.steps.map(async (step) => {
11
- var _a;
12
- const stepActivities = data.activities.filter(activity => { var _a; return ((_a = activity.context) === null || _a === void 0 ? void 0 : _a.step_id) === step.id; });
13
- return {
14
- name: step.name,
15
- label: step.label,
16
- status: step.status,
17
- start_date: step.start_date,
18
- end_date: step.end_date,
19
- stakeholders: (_a = step.stakeholders) === null || _a === void 0 ? void 0 : _a.map(s => ({
20
- name: s.name
21
- })),
22
- activities: await Promise.all(stepActivities.map(async (activity) => {
23
- var _a, _b, _c, _d, _e, _f, _g;
24
- const baseActivity = {
25
- date: activity.date,
26
- action: activity.action,
27
- status: activity.status,
28
- subject: {
29
- type: activity.subject.type,
30
- name: activity.subject.name
31
- },
32
- object: {
33
- type: activity.object.type,
34
- name: activity.object.name
35
- }
36
- };
37
- if (((_a = activity.indirect_object) === null || _a === void 0 ? void 0 : _a.type) !== undefined && ((_b = activity.indirect_object) === null || _b === void 0 ? void 0 : _b.name) !== undefined) {
38
- baseActivity.indirect_object = {
39
- type: activity.indirect_object.type,
40
- name: activity.indirect_object.name
41
- };
42
- }
43
- // Process form data if available
44
- const formId = (_c = activity.form) === null || _c === void 0 ? void 0 : _c.id;
45
- const formTitle = (_d = activity.form) === null || _d === void 0 ? void 0 : _d.title;
46
- if (formId !== undefined &&
47
- formId !== '' &&
48
- formTitle !== undefined &&
49
- formTitle !== '') {
50
- try {
51
- // Get form definition using SDK
52
- const formDefinitionResponse = await awellSdk.orchestration.query({
53
- form: {
54
- __args: {
55
- id: formId,
56
- pathway_id: pathwayId,
57
- },
58
- form: {
59
- id: true,
60
- title: true,
61
- key: true,
62
- definition_id: true,
63
- release_id: true,
64
- questions: {
65
- id: true,
66
- key: true,
67
- title: true,
68
- userQuestionType: true,
69
- options: {
70
- label: true,
71
- value: true,
72
- value_string: true,
73
- },
74
- },
75
- },
76
- },
77
- });
78
- // Get form response using SDK
79
- const formResponseData = await awellSdk.orchestration.query({
80
- formResponse: {
81
- __args: {
82
- pathway_id: pathwayId,
83
- activity_id: activity.id,
84
- },
85
- response: {
86
- answers: {
87
- question_id: true,
88
- value: true,
89
- label: true,
90
- value_type: true,
91
- },
92
- },
93
- },
94
- });
95
- const formDefinition = (_e = formDefinitionResponse.form) === null || _e === void 0 ? void 0 : _e.form;
96
- const formResponse = (_f = formResponseData.formResponse) === null || _f === void 0 ? void 0 : _f.response;
97
- if (formDefinition !== null && formResponse !== null) {
98
- // Map questions to their answers
99
- const formattedResponses = formDefinition.questions.map(question => {
100
- var _a, _b, _c;
101
- const answer = formResponse.answers.find(a => a.question_id === question.id);
102
- let responseText = (_a = answer === null || answer === void 0 ? void 0 : answer.value) !== null && _a !== void 0 ? _a : 'No response';
103
- // Handle different question types
104
- if (question.userQuestionType === 'YES_NO') {
105
- responseText = responseText === '1' ? 'Yes' : responseText === '0' ? 'No' : 'No response';
106
- }
107
- else if (question.userQuestionType === 'MULTIPLE_CHOICE' && answer !== null) {
108
- const option = (_b = question.options) === null || _b === void 0 ? void 0 : _b.find(opt => opt.value_string === (answer === null || answer === void 0 ? void 0 : answer.value));
109
- responseText = (_c = option === null || option === void 0 ? void 0 : option.label) !== null && _c !== void 0 ? _c : responseText;
110
- }
111
- return {
112
- title: question.title,
113
- response: responseText
114
- };
115
- });
116
- baseActivity.form = {
117
- title: formTitle,
118
- questions: formattedResponses
119
- };
120
- }
121
- }
122
- catch (error) {
123
- // Fallback to basic form data if form questions exist
124
- const questions = (_g = activity.form) === null || _g === void 0 ? void 0 : _g.questions;
125
- if (Array.isArray(questions)) {
126
- baseActivity.form = {
127
- title: formTitle,
128
- questions: questions.map(q => ({
129
- title: q.title,
130
- response: 'No response'
131
- }))
132
- };
133
- }
134
- }
135
- }
136
- // Handle standalone data points
137
- else if (Array.isArray(activity.dataPoints) && activity.dataPoints.length > 0) {
138
- baseActivity.data_points = activity.dataPoints.map(dp => ({
139
- value: dp.serialized_value,
140
- date: dp.date,
141
- title: dp.definitionTitle
142
- }));
143
- }
144
- return baseActivity;
145
- }))
146
- };
147
- }))
51
+ steps: processedSteps
148
52
  };
149
53
  };
150
- const getTrackData = async ({ awellSdk, pathwayId, trackId, currentActivityId, }) => {
151
- var _a, _b, _c, _d, _e;
152
- // 1. Query pathway to get track information
153
- const pathwayQuery = await awellSdk.orchestration.query({
154
- pathway: {
155
- __args: {
156
- id: pathwayId,
157
- },
158
- code: true,
159
- success: true,
54
+ exports.getTrackData = getTrackData;
55
+ /**
56
+ * Fetch all track data in a single combined query
57
+ */
58
+ async function fetchAllTrackData(awellSdk, pathwayId) {
59
+ try {
60
+ return await awellSdk.orchestration.query({
160
61
  pathway: {
161
- id: true,
162
- title: true,
163
- pathway_definition_id: true,
164
- tracks: {
165
- id: true,
166
- title: true,
167
- release_id: true,
168
- can_trigger_manually: true,
169
- },
170
- },
171
- },
172
- });
173
- // 2. Get pathway elements (steps)
174
- const elementsQuery = (await awellSdk.orchestration.query({
175
- pathwayElements: {
176
- __args: {
177
- pathway_id: pathwayId,
178
- },
179
- code: true,
180
- success: true,
181
- elements: {
182
- id: true,
183
- parent_id: true,
184
- name: true,
185
- label: {
186
- text: true,
187
- color: true,
188
- id: true,
189
- },
190
- start_date: true,
191
- end_date: true,
192
- status: true,
193
- type: true,
194
- activity_type: true,
195
- stakeholders: {
196
- id: true,
197
- name: true,
198
- },
199
- context: {
200
- instance_id: true,
201
- pathway_id: true,
202
- step_id: true,
203
- track_id: true,
204
- },
205
- },
206
- },
207
- }));
208
- // 3. Get all activities in the track up to current activity
209
- const activitiesQuery = (await awellSdk.orchestration.query({
210
- pathwayActivities: {
211
- __args: {
212
- pathway_id: pathwayId,
213
- pagination: {
214
- offset: 0,
215
- count: 500
62
+ __args: { id: pathwayId },
63
+ pathway: {
64
+ tracks: {
65
+ id: true,
66
+ title: true
67
+ }
216
68
  }
217
69
  },
218
- success: true,
219
- activities: {
220
- id: true,
221
- date: true,
222
- action: true,
223
- status: true,
224
- subject: {
225
- type: true,
226
- name: true
227
- },
228
- object: {
229
- id: true,
230
- type: true,
231
- name: true
232
- },
233
- indirect_object: {
70
+ pathwayElements: {
71
+ __args: { pathway_id: pathwayId },
72
+ elements: {
234
73
  id: true,
74
+ name: true,
75
+ label: {
76
+ text: true
77
+ },
78
+ start_date: true,
79
+ end_date: true,
80
+ status: true,
235
81
  type: true,
236
- name: true
237
- },
238
- form: {
239
- id: true,
240
- title: true,
241
- questions: {
242
- key: true,
243
- title: true,
244
- questionConfig: {
245
- mandatory: true
246
- }
82
+ stakeholders: {
83
+ name: true
84
+ },
85
+ context: {
86
+ step_id: true,
87
+ track_id: true
247
88
  }
89
+ }
90
+ },
91
+ pathwayActivities: {
92
+ __args: {
93
+ pathway_id: pathwayId,
94
+ pagination: { offset: 0, count: 500 } // TODO: we might need to handle this differently later but it is ok for now
248
95
  },
249
- track: {
96
+ activities: {
250
97
  id: true,
251
- title: true
252
- },
253
- context: {
254
- instance_id: true,
255
- pathway_id: true,
256
- track_id: true,
257
- step_id: true,
258
- action_id: true
98
+ date: true,
99
+ action: true,
100
+ status: true,
101
+ resolution: true,
102
+ subject: { type: true, name: true },
103
+ object: {
104
+ type: true,
105
+ name: true,
106
+ id: true // id field to get message ID
107
+ },
108
+ indirect_object: { type: true, name: true },
109
+ form: {
110
+ id: true,
111
+ title: true
112
+ },
113
+ track: { id: true, title: true },
114
+ context: { track_id: true, step_id: true }
115
+ }
116
+ },
117
+ pathwayDataPoints: {
118
+ __args: {
119
+ pathway_id: pathwayId,
259
120
  },
260
- session_id: true,
261
- stakeholders: {
262
- type: true,
121
+ dataPoints: {
263
122
  id: true,
264
- name: true,
265
- email: true,
266
- preferred_language: true
123
+ data_set_id: true,
124
+ key: true,
125
+ serialized_value: true,
126
+ data_point_definition_id: true,
127
+ date: true,
128
+ valueType: true,
129
+ activity_id: true,
267
130
  },
268
- resolution: true,
269
- stream_id: true
270
131
  }
271
- }
272
- }));
273
- // Find current activity to get its date
274
- const currentActivity = activitiesQuery.pathwayActivities.activities
275
- .find(activity => activity.id === currentActivityId);
276
- const currentActivityDate = (_a = currentActivity === null || currentActivity === void 0 ? void 0 : currentActivity.date) !== null && _a !== void 0 ? _a : '';
277
- // Get the track IDs we need to match against
278
- const relevantTrackIds = new Set();
279
- relevantTrackIds.add(trackId);
280
- // Filter activities by track and date
281
- const trackActivities = activitiesQuery.pathwayActivities.activities
132
+ });
133
+ }
134
+ catch (error) {
135
+ throw new Error(`Failed to fetch track data: ${error instanceof Error ? error.message : String(error)}`);
136
+ }
137
+ }
138
+ /**
139
+ * Filter activities that belong to the specified track
140
+ */
141
+ function filterTrackActivities(activities, trackId, currentActivityDate) {
142
+ return activities
282
143
  .filter(activity => {
283
- var _a;
284
- const isInTrack = ((_a = activity.context) === null || _a === void 0 ? void 0 : _a.track_id) === trackId;
285
- const isBeforeOrEqualDate = currentActivityDate.length === 0 || activity.date <= currentActivityDate;
144
+ var _a, _b;
145
+ const isInTrack = !(0, lodash_1.isNil)((_a = activity.context) === null || _a === void 0 ? void 0 : _a.track_id) &&
146
+ !(0, lodash_1.isEmpty)((_b = activity.context) === null || _b === void 0 ? void 0 : _b.track_id) &&
147
+ activity.context.track_id === trackId;
148
+ const hasNoCurrentActivityDate = (0, lodash_1.isEmpty)(currentActivityDate);
149
+ const isBeforeOrEqualToCurrentDate = !hasNoCurrentActivityDate && activity.date <= currentActivityDate;
150
+ const isBeforeOrEqualDate = hasNoCurrentActivityDate || isBeforeOrEqualToCurrentDate;
286
151
  return isInTrack && isBeforeOrEqualDate;
287
152
  })
288
153
  .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
289
- // 4. Get data points for all activities in the track
290
- const dataPointsQuery = (await awellSdk.orchestration.query({
291
- pathwayDataPoints: {
292
- __args: {
293
- pathway_id: pathwayId,
294
- },
295
- code: true,
296
- success: true,
297
- dataPoints: {
298
- id: true,
299
- data_set_id: true,
300
- key: true,
301
- serialized_value: true,
302
- data_point_definition_id: true,
303
- date: true,
304
- valueType: true,
305
- activity_id: true,
306
- },
307
- },
308
- }));
309
- // 6. Enhance activities with data points
310
- const activitiesWithDataPoints = trackActivities.map(activity => {
154
+ }
155
+ /**
156
+ * Filter steps that belong to the specified track
157
+ */
158
+ function filterTrackSteps(elements, trackId) {
159
+ return elements.filter(element => {
160
+ var _a, _b;
161
+ if ((0, lodash_1.isNil)((_a = element.context) === null || _a === void 0 ? void 0 : _a.track_id) || (0, lodash_1.isEmpty)((_b = element.context) === null || _b === void 0 ? void 0 : _b.track_id))
162
+ return false;
163
+ if ((0, lodash_1.isNil)(element.type) || (0, lodash_1.isEmpty)(element.type))
164
+ return false;
165
+ return element.context.track_id === trackId && element.type === 'STEP';
166
+ });
167
+ }
168
+ /**
169
+ * Create a map of activity ID to data points for faster lookup
170
+ */
171
+ function createDataPointsMap(dataPoints) {
172
+ const activityDataPointsMap = new Map();
173
+ dataPoints.forEach(dataPoint => {
311
174
  var _a;
312
- const activityDataPoints = dataPointsQuery.pathwayDataPoints.dataPoints
313
- .filter(dp => dp.activity_id === activity.id)
314
- .map(dp => {
315
- if (dp.data_point_definition_id.endsWith('-ACTIVATION')) {
316
- return {
317
- ...dp,
318
- definitionKey: 'activation_date',
319
- definitionTitle: 'Activation Date',
320
- };
175
+ if (typeof dataPoint.activity_id === 'string' && dataPoint.activity_id !== '') {
176
+ if (!activityDataPointsMap.has(dataPoint.activity_id)) {
177
+ activityDataPointsMap.set(dataPoint.activity_id, []);
321
178
  }
322
- return dp;
323
- });
324
- const questions = (_a = activity.form) === null || _a === void 0 ? void 0 : _a.questions;
325
- if (questions !== undefined && questions !== null) {
326
- const formResponses = questions.map(question => {
327
- var _a, _b, _c, _d, _e;
328
- const dataPoint = activityDataPoints.find(dp => dp.data_point_definition_id === question.key);
329
- return {
330
- id: (_a = dataPoint === null || dataPoint === void 0 ? void 0 : dataPoint.id) !== null && _a !== void 0 ? _a : '',
331
- data_set_id: (_b = dataPoint === null || dataPoint === void 0 ? void 0 : dataPoint.data_set_id) !== null && _b !== void 0 ? _b : '',
332
- key: question.key,
333
- serialized_value: (_c = dataPoint === null || dataPoint === void 0 ? void 0 : dataPoint.serialized_value) !== null && _c !== void 0 ? _c : '',
334
- data_point_definition_id: question.key,
335
- date: (_d = dataPoint === null || dataPoint === void 0 ? void 0 : dataPoint.date) !== null && _d !== void 0 ? _d : activity.date,
336
- valueType: (_e = dataPoint === null || dataPoint === void 0 ? void 0 : dataPoint.valueType) !== null && _e !== void 0 ? _e : 'STRING',
337
- activity_id: activity.id,
338
- definitionKey: question.key,
339
- definitionTitle: question.title,
340
- };
341
- });
342
- activityDataPoints.push(...formResponses);
179
+ // Add enhanced data point with improved title detection
180
+ const enhancedDataPoint = { ...dataPoint };
181
+ // Apply pattern-based mappings for titles
182
+ if (typeof dataPoint.data_point_definition_id === 'string' && dataPoint.data_point_definition_id !== '') {
183
+ if (dataPoint.data_point_definition_id.endsWith('-ACTIVATION')) {
184
+ enhancedDataPoint.definitionTitle = 'Activation Date';
185
+ }
186
+ else if (dataPoint.data_point_definition_id.endsWith('-COMPLETION')) {
187
+ enhancedDataPoint.definitionTitle = 'Completion Date';
188
+ }
189
+ }
190
+ (_a = activityDataPointsMap.get(dataPoint.activity_id)) === null || _a === void 0 ? void 0 : _a.push(enhancedDataPoint);
343
191
  }
344
- return {
345
- ...activity,
346
- dataPoints: activityDataPoints
347
- };
348
192
  });
349
- // 8. Get steps from the elements query and filter by track ID and type STEP
350
- const steps = elementsQuery.pathwayElements.elements
351
- .filter(element => {
193
+ return activityDataPointsMap;
194
+ }
195
+ /**
196
+ * Extract activities with forms for processing
197
+ */
198
+ function extractActivitiesWithForms(activities) {
199
+ return activities
200
+ .filter(activity => { var _a; return typeof ((_a = activity.form) === null || _a === void 0 ? void 0 : _a.id) === 'string' && activity.form.id !== ''; })
201
+ .map(activity => {
352
202
  var _a;
353
- const elementTrackId = (_a = element.context) === null || _a === void 0 ? void 0 : _a.track_id;
354
- const isInTrack = elementTrackId === trackId;
355
- const isStep = element.type === 'STEP';
356
- return isInTrack && isStep;
357
- })
358
- .map(element => {
359
- var _a, _b;
360
203
  return ({
361
- id: element.id,
362
- parent_id: element.parent_id,
363
- name: element.name,
364
- label: (_b = (_a = element.label) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '',
365
- start_date: element.start_date,
366
- end_date: element.end_date,
367
- status: element.status,
368
- activity_type: element.activity_type,
369
- stakeholders: element.stakeholders.map(stakeholder => {
370
- var _a;
371
- return ({
372
- id: stakeholder.id,
373
- name: (_a = stakeholder.name) !== null && _a !== void 0 ? _a : '',
374
- });
375
- }),
376
- activities: [],
204
+ activityId: activity.id,
205
+ formId: (_a = activity.form) === null || _a === void 0 ? void 0 : _a.id
377
206
  });
378
207
  });
379
- // 9. Associate activities with steps
380
- const stepsWithActivities = steps.map(step => {
381
- const stepActivities = activitiesWithDataPoints.filter(activity => { var _a; return ((_a = activity.context) === null || _a === void 0 ? void 0 : _a.step_id) === step.id; });
208
+ }
209
+ /**
210
+ * Process form definitions and responses in batches
211
+ */
212
+ async function processFormDefinitionsAndResponses(awellSdk, pathwayId, activitiesWithForms) {
213
+ const formDefinitionsMap = new Map();
214
+ const formResponsesMap = {};
215
+ if (activitiesWithForms.length === 0) {
216
+ return { formDefinitionsMap, formResponsesMap };
217
+ }
218
+ // Prepare queries in batches to avoid overloading
219
+ const batchSize = 10;
220
+ const batches = [];
221
+ for (let i = 0; i < activitiesWithForms.length; i += batchSize) {
222
+ batches.push(activitiesWithForms.slice(i, i + batchSize));
223
+ }
224
+ for (const batch of batches) {
225
+ await processBatch(awellSdk, pathwayId, batch, formDefinitionsMap, formResponsesMap);
226
+ }
227
+ return { formDefinitionsMap, formResponsesMap };
228
+ }
229
+ /**
230
+ * Process a batch of form definitions and responses
231
+ */
232
+ async function processBatch(awellSdk, pathwayId, batch, formDefinitionsMap, formResponsesMap) {
233
+ try {
234
+ // Create an array of promises for form definitions and responses
235
+ const formDefinitionPromises = batch.map(async ({ formId }) => {
236
+ try {
237
+ // Only fetch form definition if we haven't already
238
+ if (!formDefinitionsMap.has(formId)) {
239
+ return await awellSdk.orchestration.query({
240
+ form: {
241
+ __args: {
242
+ id: formId,
243
+ pathway_id: pathwayId,
244
+ },
245
+ form: {
246
+ id: true,
247
+ title: true,
248
+ key: true,
249
+ definition_id: true,
250
+ release_id: true,
251
+ questions: {
252
+ id: true,
253
+ key: true,
254
+ title: true,
255
+ userQuestionType: true,
256
+ options: {
257
+ label: true,
258
+ value: true,
259
+ value_string: true,
260
+ },
261
+ },
262
+ },
263
+ },
264
+ });
265
+ }
266
+ return null;
267
+ }
268
+ catch (error) {
269
+ return null;
270
+ }
271
+ });
272
+ const formResponsePromises = batch.map(async ({ activityId }) => {
273
+ try {
274
+ return await awellSdk.orchestration.query({
275
+ formResponse: {
276
+ __args: {
277
+ pathway_id: pathwayId,
278
+ activity_id: activityId
279
+ },
280
+ response: {
281
+ answers: {
282
+ question_id: true,
283
+ value: true,
284
+ label: true,
285
+ value_type: true
286
+ }
287
+ }
288
+ }
289
+ });
290
+ }
291
+ catch (error) {
292
+ return null;
293
+ }
294
+ });
295
+ // Await all promises in the batch
296
+ const formDefinitionResults = await Promise.all(formDefinitionPromises);
297
+ const formResponseResults = await Promise.all(formResponsePromises);
298
+ // Process form definitions
299
+ formDefinitionResults.forEach((result, index) => {
300
+ if (!(0, lodash_1.isNil)(result) && !(0, lodash_1.isNil)((0, lodash_1.get)(result, 'form.form'))) {
301
+ const { formId } = batch[index];
302
+ formDefinitionsMap.set(formId, (0, lodash_1.get)(result, 'form.form'));
303
+ }
304
+ });
305
+ // Process form responses
306
+ batch.forEach(({ activityId, formId }, index) => {
307
+ const result = formResponseResults[index];
308
+ if (!(0, lodash_1.isNil)(result) && !(0, lodash_1.isNil)((0, lodash_1.get)(result, 'formResponse.response'))) {
309
+ const responseData = result.formResponse.response;
310
+ // Create the map entry if it doesn't exist
311
+ if (!Object.prototype.hasOwnProperty.call(formResponsesMap, formId)) {
312
+ formResponsesMap[formId] = {};
313
+ }
314
+ const answers = Array.isArray(responseData.answers) ? responseData.answers : [];
315
+ formResponsesMap[formId][activityId] = {
316
+ activity_id: activityId,
317
+ form_id: formId,
318
+ answers: answers
319
+ };
320
+ }
321
+ });
322
+ }
323
+ catch (error) {
324
+ // Continue with partial data rather than failing completely
325
+ }
326
+ }
327
+ /**
328
+ * Extract activities that are messages
329
+ */
330
+ function extractMessageActivities(activities) {
331
+ const messageActivities = activities
332
+ .filter(activity => {
333
+ return !(0, lodash_1.isNil)(activity.object) &&
334
+ typeof activity.object.type === 'string' &&
335
+ activity.object.type === 'MESSAGE' &&
336
+ !(0, lodash_1.isNil)(activity.object.id) &&
337
+ !(0, lodash_1.isEmpty)(activity.object.id);
338
+ })
339
+ .map(activity => {
340
+ // Use object.id as the message ID
341
+ const messageId = activity.object.id;
342
+ // Extract fallback content from activity if available
343
+ let fallbackSubject = '';
344
+ if (!(0, lodash_1.isNil)(activity.object.name) && !(0, lodash_1.isEmpty)(activity.object.name)) {
345
+ fallbackSubject = activity.object.name;
346
+ }
382
347
  return {
383
- ...step,
384
- activities: stepActivities.map(activity => activity.id),
348
+ activityId: activity.id,
349
+ messageId,
350
+ fallbackSubject,
351
+ fallbackBody: ''
385
352
  };
386
353
  });
387
- // 10. Process the track data
388
- // First try to get track title from activities
389
- const trackFromActivities = (_b = trackActivities.find(activity => { var _a; return ((_a = activity.track) === null || _a === void 0 ? void 0 : _a.id) === trackId; })) === null || _b === void 0 ? void 0 : _b.track;
390
- // If not found in activities, try to get from elements
391
- const trackElement = elementsQuery.pathwayElements.elements.find(element => { var _a; return element.type === 'TRACK' && ((_a = element.context) === null || _a === void 0 ? void 0 : _a.track_id) === trackId; });
392
- // Finally check pathway tracks
393
- const trackFromPathway = pathwayQuery.pathway.pathway.tracks.find((t) => t.id === trackId);
394
- const finalTrack = {
395
- id: trackId,
396
- title: (_e = (_d = (_c = trackFromActivities === null || trackFromActivities === void 0 ? void 0 : trackFromActivities.title) !== null && _c !== void 0 ? _c : trackElement === null || trackElement === void 0 ? void 0 : trackElement.name) !== null && _d !== void 0 ? _d : trackFromPathway === null || trackFromPathway === void 0 ? void 0 : trackFromPathway.title) !== null && _e !== void 0 ? _e : 'Untitled Track'
354
+ return messageActivities;
355
+ }
356
+ /**
357
+ * Fetch message contents for message activities
358
+ */
359
+ async function fetchMessageContents(awellSdk, messageActivities) {
360
+ const messageContentsMap = new Map();
361
+ if (messageActivities.length === 0) {
362
+ return messageContentsMap;
363
+ }
364
+ // Process in batches to avoid overloading
365
+ const batchSize = 10;
366
+ const batches = [];
367
+ for (let i = 0; i < messageActivities.length; i += batchSize) {
368
+ batches.push(messageActivities.slice(i, i + batchSize));
369
+ }
370
+ for (const batch of batches) {
371
+ await Promise.all(batch.map(async ({ activityId, messageId, fallbackSubject, fallbackBody }) => {
372
+ try {
373
+ // Try to fetch message content with the query structure from documentation
374
+ const response = await awellSdk.orchestration.query({
375
+ message: {
376
+ __args: {
377
+ id: messageId
378
+ },
379
+ message: {
380
+ id: true,
381
+ subject: true,
382
+ body: true,
383
+ format: true,
384
+ attachments: {
385
+ id: true,
386
+ name: true,
387
+ type: true,
388
+ url: true
389
+ }
390
+ }
391
+ }
392
+ });
393
+ // Use lodash to check for null/undefined values
394
+ if (!(0, lodash_1.isNil)(response) &&
395
+ !(0, lodash_1.isNil)(response.message) &&
396
+ !(0, lodash_1.isNil)(response.message.message)) {
397
+ messageContentsMap.set(activityId, {
398
+ subject: response.message.message.subject,
399
+ body: response.message.message.body
400
+ });
401
+ }
402
+ else {
403
+ // Use fallback content if available
404
+ const hasFallbackSubject = !(0, lodash_1.isNil)(fallbackSubject) && !(0, lodash_1.isEmpty)(fallbackSubject);
405
+ const hasFallbackBody = !(0, lodash_1.isNil)(fallbackBody) && !(0, lodash_1.isEmpty)(fallbackBody);
406
+ if (hasFallbackSubject || hasFallbackBody) {
407
+ messageContentsMap.set(activityId, {
408
+ subject: fallbackSubject,
409
+ body: fallbackBody
410
+ });
411
+ }
412
+ }
413
+ }
414
+ catch (error) {
415
+ // Use fallback content if available after error
416
+ const hasFallbackSubject = !(0, lodash_1.isNil)(fallbackSubject) && !(0, lodash_1.isEmpty)(fallbackSubject);
417
+ const hasFallbackBody = !(0, lodash_1.isNil)(fallbackBody) && !(0, lodash_1.isEmpty)(fallbackBody);
418
+ if (hasFallbackSubject || hasFallbackBody) {
419
+ messageContentsMap.set(activityId, {
420
+ subject: fallbackSubject,
421
+ body: fallbackBody
422
+ });
423
+ }
424
+ }
425
+ }));
426
+ }
427
+ return messageContentsMap;
428
+ }
429
+ /**
430
+ * Process a step with its activities
431
+ */
432
+ function processStep(step, trackActivities, activityDataPointsMap, formDefinitionsMap, formResponsesMap, messageContentsMap) {
433
+ var _a, _b;
434
+ const stepActivities = trackActivities
435
+ .filter(activity => { var _a; return ((_a = activity.context) === null || _a === void 0 ? void 0 : _a.step_id) === step.id; })
436
+ .map(activity => processActivity(activity, activityDataPointsMap, formDefinitionsMap, formResponsesMap, messageContentsMap));
437
+ return {
438
+ name: step.name,
439
+ label: typeof ((_a = step.label) === null || _a === void 0 ? void 0 : _a.text) === 'string' ? step.label.text : '',
440
+ status: step.status,
441
+ start_date: step.start_date,
442
+ end_date: step.end_date,
443
+ stakeholders: (_b = step.stakeholders) === null || _b === void 0 ? void 0 : _b.map(s => ({
444
+ name: typeof s.name === 'string' ? s.name : ''
445
+ })),
446
+ activities: stepActivities
397
447
  };
398
- const rawTrackData = {
399
- track: finalTrack,
400
- activities: activitiesWithDataPoints,
401
- steps: stepsWithActivities,
448
+ }
449
+ /**
450
+ * Process an activity with its form and data points
451
+ */
452
+ function processActivity(activity, activityDataPointsMap, formDefinitionsMap, formResponsesMap, messageContentsMap) {
453
+ var _a, _b, _c, _d;
454
+ const baseActivity = {
455
+ date: activity.date,
456
+ action: activity.action,
457
+ status: activity.status,
458
+ resolution: activity.resolution,
459
+ subject: {
460
+ type: activity.subject.type,
461
+ name: activity.subject.name
462
+ },
463
+ object: {
464
+ type: activity.object.type,
465
+ name: activity.object.name
466
+ }
402
467
  };
403
- // Clean the data for LLM consumption and return only cleaned data
404
- const cleanedData = await cleanDataForLLM(rawTrackData, awellSdk, pathwayId);
405
- return cleanedData;
406
- };
407
- exports.getTrackData = getTrackData;
468
+ // Add indirect object if it exists
469
+ if (!(0, lodash_1.isNil)((_a = activity.indirect_object) === null || _a === void 0 ? void 0 : _a.type) &&
470
+ !(0, lodash_1.isEmpty)((_b = activity.indirect_object) === null || _b === void 0 ? void 0 : _b.type) &&
471
+ !(0, lodash_1.isNil)((_c = activity.indirect_object) === null || _c === void 0 ? void 0 : _c.name) &&
472
+ !(0, lodash_1.isEmpty)((_d = activity.indirect_object) === null || _d === void 0 ? void 0 : _d.name)) {
473
+ baseActivity.indirect_object = {
474
+ type: activity.indirect_object.type,
475
+ name: activity.indirect_object.name
476
+ };
477
+ }
478
+ // Process message if exists
479
+ processActivityMessage(baseActivity, activity, messageContentsMap);
480
+ // Process form if exists
481
+ processActivityForm(baseActivity, activity, formDefinitionsMap, formResponsesMap);
482
+ // Process data points
483
+ processActivityDataPoints(baseActivity, activity, activityDataPointsMap);
484
+ return baseActivity;
485
+ }
486
+ /**
487
+ * Process message for an activity
488
+ */
489
+ function processActivityMessage(baseActivity, activity, messageContentsMap) {
490
+ if (messageContentsMap.has(activity.id)) {
491
+ const messageContent = messageContentsMap.get(activity.id);
492
+ if (!(0, lodash_1.isNil)(messageContent)) {
493
+ baseActivity.message = {
494
+ subject: messageContent.subject,
495
+ body: messageContent.body
496
+ };
497
+ }
498
+ }
499
+ }
500
+ /**
501
+ * Process form for an activity
502
+ */
503
+ function processActivityForm(baseActivity, activity, formDefinitionsMap, formResponsesMap) {
504
+ if ((0, lodash_1.isNil)(activity.form) || (0, lodash_1.isNil)(activity.form.id) || activity.form.id === '') {
505
+ return;
506
+ }
507
+ const formId = activity.form.id;
508
+ const formTitle = typeof activity.form.title === 'string' && !(0, lodash_1.isEmpty)(activity.form.title)
509
+ ? activity.form.title
510
+ : 'Untitled Form';
511
+ // Check if we have form responses for this activity
512
+ const hasFormResponses = Object.prototype.hasOwnProperty.call(formResponsesMap, formId) &&
513
+ Object.prototype.hasOwnProperty.call(formResponsesMap[formId], activity.id);
514
+ if (hasFormResponses) {
515
+ const formResponseData = formResponsesMap[formId][activity.id];
516
+ const formDefinition = formDefinitionsMap.get(formId);
517
+ // Create form with responses
518
+ if (!(0, lodash_1.isNil)(formDefinition)) {
519
+ // Map questions to their answers with proper formatting
520
+ baseActivity.form = {
521
+ title: formTitle,
522
+ questions: formResponseData.answers.map(answer => {
523
+ var _a, _b, _c, _d;
524
+ const question = formDefinition.questions.find((q) => q.id === answer.question_id);
525
+ let responseText = (_a = answer.value) !== null && _a !== void 0 ? _a : 'No response';
526
+ // Handle different question types
527
+ if (!(0, lodash_1.isNil)(question)) {
528
+ if (question.userQuestionType === 'YES_NO') {
529
+ responseText = responseText === '1' ? 'Yes' : responseText === '0' ? 'No' : 'No response';
530
+ }
531
+ else if (question.userQuestionType === 'MULTIPLE_CHOICE' &&
532
+ typeof answer.value === 'string' && !(0, lodash_1.isEmpty)(answer.value)) {
533
+ const option = (_b = question.options) === null || _b === void 0 ? void 0 : _b.find((opt) => opt.value_string === answer.value);
534
+ responseText = (_c = option === null || option === void 0 ? void 0 : option.label) !== null && _c !== void 0 ? _c : responseText;
535
+ }
536
+ }
537
+ return {
538
+ title: (_d = question === null || question === void 0 ? void 0 : question.title) !== null && _d !== void 0 ? _d : answer.question_id,
539
+ response: responseText
540
+ };
541
+ })
542
+ };
543
+ }
544
+ else {
545
+ // Fallback if form definition not available
546
+ baseActivity.form = {
547
+ title: formTitle,
548
+ questions: formResponseData.answers.map(answer => {
549
+ var _a;
550
+ return ({
551
+ title: answer.question_id,
552
+ response: (_a = answer.value) !== null && _a !== void 0 ? _a : 'No response'
553
+ });
554
+ })
555
+ };
556
+ }
557
+ }
558
+ else {
559
+ // Just include the form title if no responses
560
+ baseActivity.form = {
561
+ title: formTitle
562
+ };
563
+ }
564
+ }
565
+ /**
566
+ * Process data points for an activity
567
+ */
568
+ function processActivityDataPoints(baseActivity, activity, activityDataPointsMap) {
569
+ const activityDataPoints = activityDataPointsMap.get(activity.id);
570
+ if ((0, lodash_1.isNil)(activityDataPoints) || activityDataPoints.length === 0) {
571
+ return;
572
+ }
573
+ // Determine which data points to include
574
+ let dataPointsToInclude = [];
575
+ const hasForm = !(0, lodash_1.isNil)(activity.form) && !(0, lodash_1.isEmpty)((0, lodash_1.get)(activity.form, 'id'));
576
+ if (hasForm) {
577
+ // If this activity has a form, only include activation data points
578
+ dataPointsToInclude = activityDataPoints.filter(dp => !(0, lodash_1.isNil)(dp) && !(0, lodash_1.isNil)(dp.data_point_definition_id) &&
579
+ dp.data_point_definition_id.endsWith('-ACTIVATION'));
580
+ }
581
+ else {
582
+ // If this activity doesn't have a form, include all data points
583
+ dataPointsToInclude = activityDataPoints;
584
+ }
585
+ if (dataPointsToInclude.length > 0) {
586
+ baseActivity.data_points = dataPointsToInclude.map(dp => ({
587
+ value: dp.serialized_value,
588
+ title: !(0, lodash_1.isNil)(dp.definitionTitle) ? dp.definitionTitle : (!(0, lodash_1.isNil)(dp.key) ? dp.key : dp.data_point_definition_id),
589
+ date: dp.date
590
+ }));
591
+ }
592
+ }
408
593
  //# sourceMappingURL=getTrackData.js.map