@awell-health/awell-extensions 2.0.36 → 2.0.37

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/dist/extensions/shelly/actions/generateMessage/config/datapoints.d.ts +10 -0
  2. package/dist/extensions/shelly/actions/generateMessage/config/datapoints.js +14 -0
  3. package/dist/extensions/shelly/actions/generateMessage/config/datapoints.js.map +1 -0
  4. package/dist/extensions/shelly/actions/generateMessage/config/fields.d.ts +61 -0
  5. package/dist/extensions/shelly/actions/generateMessage/config/fields.js +74 -0
  6. package/dist/extensions/shelly/actions/generateMessage/config/fields.js.map +1 -0
  7. package/dist/extensions/shelly/actions/generateMessage/config/index.d.ts +2 -0
  8. package/dist/extensions/shelly/actions/generateMessage/config/index.js +9 -0
  9. package/dist/extensions/shelly/actions/generateMessage/config/index.js.map +1 -0
  10. package/dist/extensions/shelly/actions/generateMessage/generateMessage.d.ts +4 -0
  11. package/dist/extensions/shelly/actions/generateMessage/generateMessage.js +47 -0
  12. package/dist/extensions/shelly/actions/generateMessage/generateMessage.js.map +1 -0
  13. package/dist/extensions/shelly/actions/generateMessage/generateMessage.test.d.ts +1 -0
  14. package/dist/extensions/shelly/actions/generateMessage/generateMessage.test.js +103 -0
  15. package/dist/extensions/shelly/actions/generateMessage/generateMessage.test.js.map +1 -0
  16. package/dist/extensions/shelly/actions/generateMessage/generateMessageRealOpenAI.test.d.ts +1 -0
  17. package/dist/extensions/shelly/actions/generateMessage/generateMessageRealOpenAI.test.js +77 -0
  18. package/dist/extensions/shelly/actions/generateMessage/generateMessageRealOpenAI.test.js.map +1 -0
  19. package/dist/extensions/shelly/actions/generateMessage/index.d.ts +1 -0
  20. package/dist/extensions/shelly/actions/generateMessage/index.js +6 -0
  21. package/dist/extensions/shelly/actions/generateMessage/index.js.map +1 -0
  22. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/constants.d.ts +24 -0
  23. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/constants.js +131 -0
  24. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/constants.js.map +1 -0
  25. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.d.ts +12 -0
  26. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.js +68 -0
  27. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.js.map +1 -0
  28. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.test.d.ts +1 -0
  29. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.test.js +69 -0
  30. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.test.js.map +1 -0
  31. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLMRealOpenAI.test.d.ts +1 -0
  32. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLMRealOpenAI.test.js +65 -0
  33. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLMRealOpenAI.test.js.map +1 -0
  34. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/index.d.ts +1 -0
  35. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/index.js +6 -0
  36. package/dist/extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/index.js.map +1 -0
  37. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ export declare const dataPoints: {
2
+ subject: {
3
+ key: string;
4
+ valueType: "string";
5
+ };
6
+ message: {
7
+ key: string;
8
+ valueType: "string";
9
+ };
10
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dataPoints = void 0;
4
+ exports.dataPoints = {
5
+ subject: {
6
+ key: 'subject',
7
+ valueType: 'string',
8
+ },
9
+ message: {
10
+ key: 'message',
11
+ valueType: 'string',
12
+ },
13
+ };
14
+ //# sourceMappingURL=datapoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datapoints.js","sourceRoot":"","sources":["../../../../../../extensions/shelly/actions/generateMessage/config/datapoints.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAG;IACxB,OAAO,EAAE;QACP,GAAG,EAAE,SAAS;QACd,SAAS,EAAE,QAAQ;KACpB;IACD,OAAO,EAAE;QACP,GAAG,EAAE,SAAS;QACd,SAAS,EAAE,QAAQ;KACpB;CAC4C,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { FieldType } from '@awell-health/extensions-core';
2
+ import z from 'zod';
3
+ /**
4
+ * Fields definitions for the message form.
5
+ */
6
+ export declare const fields: {
7
+ communicationObjective: {
8
+ id: string;
9
+ label: string;
10
+ description: string;
11
+ type: FieldType.STRING;
12
+ required: true;
13
+ };
14
+ personalizationInput: {
15
+ id: string;
16
+ label: string;
17
+ description: string;
18
+ type: FieldType.STRING;
19
+ required: false;
20
+ };
21
+ additionalInstructions: {
22
+ id: string;
23
+ label: string;
24
+ description: string;
25
+ type: FieldType.STRING;
26
+ required: false;
27
+ };
28
+ stakeholder: {
29
+ id: string;
30
+ label: string;
31
+ description: string;
32
+ type: FieldType.STRING;
33
+ required: false;
34
+ };
35
+ language: {
36
+ id: string;
37
+ label: string;
38
+ description: string;
39
+ type: FieldType.STRING;
40
+ required: false;
41
+ };
42
+ };
43
+ export declare const FieldsValidationSchema: z.ZodObject<{
44
+ communicationObjective: z.ZodString;
45
+ additionalInstructions: z.ZodDefault<z.ZodOptional<z.ZodString>>;
46
+ personalizationInput: z.ZodDefault<z.ZodOptional<z.ZodString>>;
47
+ stakeholder: z.ZodEffects<z.ZodOptional<z.ZodString>, string, string | undefined>;
48
+ language: z.ZodEffects<z.ZodOptional<z.ZodString>, string, string | undefined>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ language: string;
51
+ additionalInstructions: string;
52
+ stakeholder: string;
53
+ communicationObjective: string;
54
+ personalizationInput: string;
55
+ }, {
56
+ communicationObjective: string;
57
+ language?: string | undefined;
58
+ additionalInstructions?: string | undefined;
59
+ stakeholder?: string | undefined;
60
+ personalizationInput?: string | undefined;
61
+ }>;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FieldsValidationSchema = exports.fields = void 0;
7
+ const extensions_core_1 = require("@awell-health/extensions-core");
8
+ const zod_1 = __importDefault(require("zod"));
9
+ /**
10
+ * Fields definitions for the message form.
11
+ */
12
+ exports.fields = {
13
+ communicationObjective: {
14
+ id: 'communicationObjective',
15
+ label: 'Communication Objective',
16
+ description: 'Provide the main purpose of the message. Add any important message context.',
17
+ type: extensions_core_1.FieldType.STRING,
18
+ required: true,
19
+ },
20
+ personalizationInput: {
21
+ id: 'personalizationInput',
22
+ label: 'Personalization Input',
23
+ description: '[Optional] Specify the personalization input for the message (name, age, gender, date of the last checkup, etc). This is used to personalize the message to the recipient.',
24
+ type: extensions_core_1.FieldType.STRING,
25
+ required: false,
26
+ },
27
+ additionalInstructions: {
28
+ id: 'additionalInstructions',
29
+ label: 'Additional Instructions',
30
+ description: '[Optional] Specify any important additional instructions for the message (style, tone, etc). If not specified, default instructions will be used.',
31
+ type: extensions_core_1.FieldType.STRING,
32
+ required: false,
33
+ },
34
+ stakeholder: {
35
+ id: 'stakeholder',
36
+ label: 'Stakeholder',
37
+ description: '[Optional]Specify the recipient role; defaults to "Patient." Used for personalization.',
38
+ type: extensions_core_1.FieldType.STRING,
39
+ required: false,
40
+ },
41
+ language: {
42
+ id: 'language',
43
+ label: 'Language',
44
+ description: '[Optional]Specify the language of the message; defaults to English.',
45
+ type: extensions_core_1.FieldType.STRING,
46
+ required: false,
47
+ },
48
+ };
49
+ /**
50
+ * Validation schema for the fields using Zod.
51
+ */
52
+ const fieldSchemas = {
53
+ communicationObjective: zod_1.default.string().min(1, 'Communication objective is required'),
54
+ additionalInstructions: zod_1.default.string().optional().default(''),
55
+ personalizationInput: zod_1.default.string().optional().default(''),
56
+ stakeholder: zod_1.default
57
+ .string()
58
+ .optional()
59
+ .transform((val) => {
60
+ if (val === undefined || val === '')
61
+ return 'Patient';
62
+ return val;
63
+ }),
64
+ language: zod_1.default
65
+ .string()
66
+ .optional()
67
+ .transform((val) => {
68
+ if (val === undefined || val === '')
69
+ return 'English';
70
+ return val;
71
+ }),
72
+ };
73
+ exports.FieldsValidationSchema = zod_1.default.object(fieldSchemas);
74
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.js","sourceRoot":"","sources":["../../../../../../extensions/shelly/actions/generateMessage/config/fields.ts"],"names":[],"mappings":";;;;;;AAAA,mEAAsE;AACtE,8CAAyC;AAEzC;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,sBAAsB,EAAE;QACtB,EAAE,EAAE,wBAAwB;QAC5B,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,6EAA6E;QAC/E,IAAI,EAAE,2BAAS,CAAC,MAAM;QACtB,QAAQ,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,sBAAsB;QAC1B,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,4KAA4K;QAC9K,IAAI,EAAE,2BAAS,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,wBAAwB;QAC5B,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,mJAAmJ;QACrJ,IAAI,EAAE,2BAAS,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB;IACD,WAAW,EAAE;QACX,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,wFAAwF;QAC1F,IAAI,EAAE,2BAAS,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,qEAAqE;QAClF,IAAI,EAAE,2BAAS,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB;CAC8B,CAAC;AAElC;;GAEG;AACH,MAAM,YAAY,GAAG;IACnB,sBAAsB,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,qCAAqC,CAAC;IAChF,sBAAsB,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,oBAAoB,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACvD,WAAW,EAAE,aAAC;SACX,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,SAAS,CAAC,CAAC,GAAG,EAAU,EAAE;QACzB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;QACtD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACJ,QAAQ,EAAE,aAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,SAAS,CAAC,CAAC,GAAG,EAAU,EAAE;QACzB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;QACtD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;CAC6C,CAAC;AAEvC,QAAA,sBAAsB,GAAG,aAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { fields, FieldsValidationSchema } from './fields';
2
+ export { dataPoints } from './datapoints';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dataPoints = exports.FieldsValidationSchema = exports.fields = void 0;
4
+ var fields_1 = require("./fields");
5
+ Object.defineProperty(exports, "fields", { enumerable: true, get: function () { return fields_1.fields; } });
6
+ Object.defineProperty(exports, "FieldsValidationSchema", { enumerable: true, get: function () { return fields_1.FieldsValidationSchema; } });
7
+ var datapoints_1 = require("./datapoints");
8
+ Object.defineProperty(exports, "dataPoints", { enumerable: true, get: function () { return datapoints_1.dataPoints; } });
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../extensions/shelly/actions/generateMessage/config/index.ts"],"names":[],"mappings":";;;AAAA,mCAAyD;AAAhD,gGAAA,MAAM,OAAA;AAAE,gHAAA,sBAAsB,OAAA;AACvC,2CAAyC;AAAhC,wGAAA,UAAU,OAAA"}
@@ -0,0 +1,4 @@
1
+ import { type Action } from '@awell-health/extensions-core';
2
+ import { type settings } from '../../settings';
3
+ import { fields, dataPoints } from './config';
4
+ export declare const generateMessage: Action<typeof fields, typeof settings, keyof typeof dataPoints>;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMessage = void 0;
4
+ const extensions_core_1 = require("@awell-health/extensions-core");
5
+ const generateMessageWithLLM_1 = require("./lib/generateMessageWithLLM");
6
+ const lib_1 = require("../../lib");
7
+ const config_1 = require("./config");
8
+ exports.generateMessage = {
9
+ key: 'generateMessage',
10
+ category: extensions_core_1.Category.WORKFLOW,
11
+ title: 'Generate Message',
12
+ description: 'Generate a personalized message',
13
+ fields: config_1.fields,
14
+ previewable: false,
15
+ dataPoints: config_1.dataPoints,
16
+ onEvent: async ({ payload, onComplete, onError, helpers }) => {
17
+ const { ChatModelGPT4o, fields: { communicationObjective, personalizationInput, additionalInstructions, stakeholder, language }, } = await (0, lib_1.validatePayloadAndCreateSdk)({
18
+ fieldsSchema: config_1.FieldsValidationSchema,
19
+ payload,
20
+ });
21
+ try {
22
+ const generated_message = await (0, generateMessageWithLLM_1.generateMessageWithLLM)({
23
+ ChatModelGPT4o,
24
+ communicationObjective,
25
+ personalizationInput,
26
+ additionalInstructions,
27
+ stakeholder,
28
+ language,
29
+ });
30
+ const { subject, message } = generated_message;
31
+ console.log(subject);
32
+ console.log(message);
33
+ await onComplete({
34
+ data_points: {
35
+ subject,
36
+ message,
37
+ },
38
+ });
39
+ }
40
+ catch (error) {
41
+ console.error('Error generating message:', error);
42
+ // Catch in extention server
43
+ throw new Error('Error generating message');
44
+ }
45
+ },
46
+ };
47
+ //# sourceMappingURL=generateMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessage.js","sourceRoot":"","sources":["../../../../../extensions/shelly/actions/generateMessage/generateMessage.ts"],"names":[],"mappings":";;;AAAA,mEAAqE;AACrE,yEAAqE;AACrE,mCAAuD;AAEvD,qCAAqE;AAExD,QAAA,eAAe,GAIxB;IACF,GAAG,EAAE,iBAAiB;IACtB,QAAQ,EAAE,0BAAQ,CAAC,QAAQ;IAC3B,KAAK,EAAE,kBAAkB;IACzB,WAAW,EACT,iCAAiC;IACnC,MAAM,EAAN,eAAM;IACN,WAAW,EAAE,KAAK;IAClB,UAAU,EAAV,mBAAU;IACV,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAiB,EAAE;QAC1E,MAAM,EACJ,cAAc,EACd,MAAM,EAAE,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,WAAW,EAAE,QAAQ,EAAE,GACxG,GAAG,MAAM,IAAA,iCAA2B,EAAC;YACpC,YAAY,EAAE,+BAAsB;YACpC,OAAO;SACR,CAAC,CAAA;QAEF,IAAI;YACF,MAAM,iBAAiB,GAAG,MAAM,IAAA,+CAAsB,EAAC;gBACrD,cAAc;gBACd,sBAAsB;gBACtB,oBAAoB;gBACpB,sBAAsB;gBACtB,WAAW;gBACX,QAAQ;aACT,CAAC,CAAA;YAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAA;YAC9C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACpB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAEpB,MAAM,UAAU,CAAC;gBACf,WAAW,EAAE;oBACX,OAAO;oBACP,OAAO;iBACR;aACF,CAAC,CAAA;SACH;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAA;YACjD,4BAA4B;YAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;SAC5C;IACH,CAAC;CACF,CAAA"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /* eslint-disable @typescript-eslint/no-var-requires */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const extensions_core_1 = require("@awell-health/extensions-core");
5
+ const tests_1 = require("@/tests");
6
+ const _1 = require(".");
7
+ const openai_1 = require("@langchain/openai");
8
+ jest.mock('@langchain/openai', () => {
9
+ const mockInvoke = jest.fn().mockResolvedValue({
10
+ subject: 'Test Subject',
11
+ message: 'This is a test message',
12
+ });
13
+ const mockChain = {
14
+ invoke: mockInvoke,
15
+ };
16
+ const mockPipe = jest.fn().mockReturnValue(mockChain);
17
+ const mockChatOpenAI = jest.fn().mockImplementation(() => ({
18
+ pipe: mockPipe,
19
+ }));
20
+ return {
21
+ ChatOpenAI: mockChatOpenAI,
22
+ };
23
+ });
24
+ describe('generateMessage - Mocked LLM calls', () => {
25
+ const { onComplete, onError, helpers, extensionAction, clearMocks } = extensions_core_1.TestHelpers.fromAction(_1.generateMessage);
26
+ beforeEach(() => {
27
+ clearMocks();
28
+ jest.clearAllMocks();
29
+ });
30
+ it('should generate a message with additional instructions', async () => {
31
+ const generateMessageWithLLMSpy = jest.spyOn(require('./lib/generateMessageWithLLM'), 'generateMessageWithLLM');
32
+ const payload = (0, tests_1.generateTestPayload)({
33
+ fields: {
34
+ communicationObjective: 'Reminder',
35
+ stakeholder: 'Patient',
36
+ additionalInstructions: 'Be friendly and encouraging',
37
+ language: 'English',
38
+ personalizationInput: 'John Doe',
39
+ },
40
+ settings: {
41
+ openAiApiKey: 'test_key',
42
+ },
43
+ });
44
+ await extensionAction.onEvent({
45
+ payload,
46
+ onComplete,
47
+ onError,
48
+ helpers,
49
+ });
50
+ expect(openai_1.ChatOpenAI).toHaveBeenCalled();
51
+ expect(generateMessageWithLLMSpy).toHaveBeenCalledWith({
52
+ ChatModelGPT4o: expect.any(Object),
53
+ communicationObjective: 'Reminder',
54
+ stakeholder: 'Patient',
55
+ additionalInstructions: 'Be friendly and encouraging',
56
+ language: 'English',
57
+ personalizationInput: 'John Doe',
58
+ });
59
+ expect(onComplete).toHaveBeenCalledWith({
60
+ data_points: {
61
+ subject: 'Test Subject',
62
+ message: 'This is a test message',
63
+ },
64
+ });
65
+ expect(onError).not.toHaveBeenCalled();
66
+ });
67
+ it('should generate a message without additional instructions', async () => {
68
+ const generateMessageWithLLMSpy = jest.spyOn(require('./lib/generateMessageWithLLM'), 'generateMessageWithLLM');
69
+ const payload = (0, tests_1.generateTestPayload)({
70
+ fields: {
71
+ communicationObjective: 'Update clinician on their patient',
72
+ stakeholder: 'Clinician',
73
+ language: 'Bosnian',
74
+ },
75
+ settings: {
76
+ openAiApiKey: 'test_key',
77
+ },
78
+ });
79
+ await extensionAction.onEvent({
80
+ payload,
81
+ onComplete,
82
+ onError,
83
+ helpers,
84
+ });
85
+ expect(openai_1.ChatOpenAI).toHaveBeenCalled();
86
+ expect(generateMessageWithLLMSpy).toHaveBeenCalledWith({
87
+ ChatModelGPT4o: expect.any(Object),
88
+ communicationObjective: 'Update clinician on their patient',
89
+ stakeholder: 'Clinician',
90
+ additionalInstructions: '',
91
+ language: 'Bosnian',
92
+ personalizationInput: '',
93
+ });
94
+ expect(onComplete).toHaveBeenCalledWith({
95
+ data_points: {
96
+ subject: 'Test Subject',
97
+ message: 'This is a test message',
98
+ },
99
+ });
100
+ expect(onError).not.toHaveBeenCalled();
101
+ });
102
+ });
103
+ //# sourceMappingURL=generateMessage.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessage.test.js","sourceRoot":"","sources":["../../../../../extensions/shelly/actions/generateMessage/generateMessage.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("dotenv/config");
4
+ const extensions_core_1 = require("@awell-health/extensions-core");
5
+ const tests_1 = require("@/tests");
6
+ const _1 = require(".");
7
+ jest.setTimeout(60000); // Increase timeout to 60 seconds for all tests in this file
8
+ describe.skip('generateMessage - Real OpenAI calls', () => {
9
+ const { onComplete, onError, helpers, extensionAction, clearMocks } = extensions_core_1.TestHelpers.fromAction(_1.generateMessage);
10
+ beforeEach(() => {
11
+ clearMocks();
12
+ });
13
+ it('should generate a message with additional instructions', async () => {
14
+ const payload = (0, tests_1.generateTestPayload)({
15
+ fields: {
16
+ communicationObjective: 'Remind patient of upcoming appointment',
17
+ stakeholder: 'Patient',
18
+ additionalInstructions: 'Be friendly and encouraging',
19
+ language: 'English',
20
+ personalizationInput: 'Patient Name: John Doe, Appointment Time: 2:00 PM tomorrow',
21
+ },
22
+ settings: {
23
+ openAiApiKey: process.env.OPENAI_API_KEY,
24
+ },
25
+ });
26
+ await extensionAction.onEvent({
27
+ payload,
28
+ onComplete,
29
+ onError,
30
+ helpers,
31
+ });
32
+ expect(onComplete).toHaveBeenCalledWith(expect.objectContaining({
33
+ data_points: expect.objectContaining({
34
+ subject: expect.any(String),
35
+ message: expect.any(String),
36
+ }),
37
+ }));
38
+ const { subject, message } = onComplete.mock.calls[0][0].data_points;
39
+ expect(subject).toContain('Appointment');
40
+ expect(message).toContain('John Doe');
41
+ expect(message).toContain('2:00 PM');
42
+ expect(message).toMatch(/friendly|encouraging/i);
43
+ expect(onError).not.toHaveBeenCalled();
44
+ });
45
+ it('should generate a message without additional instructions', async () => {
46
+ const payload = (0, tests_1.generateTestPayload)({
47
+ fields: {
48
+ communicationObjective: 'Update clinician on patient progress',
49
+ stakeholder: 'Clinician',
50
+ additionalInstructions: '',
51
+ language: 'English',
52
+ personalizationInput: 'Patient: Jane Smith, Last Visit: 2 weeks ago, Condition: Hypertension',
53
+ },
54
+ settings: {
55
+ openAiApiKey: process.env.OPENAI_API_KEY,
56
+ },
57
+ });
58
+ await extensionAction.onEvent({
59
+ payload,
60
+ onComplete,
61
+ onError,
62
+ helpers,
63
+ });
64
+ expect(onComplete).toHaveBeenCalledWith(expect.objectContaining({
65
+ data_points: expect.objectContaining({
66
+ subject: expect.any(String),
67
+ message: expect.any(String),
68
+ }),
69
+ }));
70
+ const { subject, message } = onComplete.mock.calls[0][0].data_points;
71
+ expect(subject.toLowerCase()).toContain('update');
72
+ expect(message).toContain('Jane Smith');
73
+ expect(message.toLowerCase()).toContain('hypertension');
74
+ expect(onError).not.toHaveBeenCalled();
75
+ });
76
+ });
77
+ //# sourceMappingURL=generateMessageRealOpenAI.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessageRealOpenAI.test.js","sourceRoot":"","sources":["../../../../../extensions/shelly/actions/generateMessage/generateMessageRealOpenAI.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { generateMessage } from './generateMessage';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMessage = void 0;
4
+ var generateMessage_1 = require("./generateMessage");
5
+ Object.defineProperty(exports, "generateMessage", { enumerable: true, get: function () { return generateMessage_1.generateMessage; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../extensions/shelly/actions/generateMessage/index.ts"],"names":[],"mappings":";;;AAAA,qDAAmD;AAA1C,kHAAA,eAAe,OAAA"}
@@ -0,0 +1,24 @@
1
+ import { ChatPromptTemplate } from '@langchain/core/prompts';
2
+ import { StructuredOutputParser } from 'langchain/output_parsers';
3
+ import { z } from 'zod';
4
+ export declare const generatedMessageCategoriesSchema: z.ZodObject<{
5
+ subject: z.ZodString;
6
+ message: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ message: string;
9
+ subject: string;
10
+ }, {
11
+ message: string;
12
+ subject: string;
13
+ }>;
14
+ export declare const parser: StructuredOutputParser<z.ZodObject<{
15
+ subject: z.ZodString;
16
+ message: z.ZodString;
17
+ }, "strip", z.ZodTypeAny, {
18
+ message: string;
19
+ subject: string;
20
+ }, {
21
+ message: string;
22
+ subject: string;
23
+ }>>;
24
+ export declare const systemPrompt: ChatPromptTemplate<import("@langchain/core/prompts").ParamsFromFString<"\n You are an AI language model tasked with composing **personalized messages** for a **{stakeholder}** within a clinical workflow. Your goals are to:\n\n- Align the message with the **Communication Objective** to optimize for response, engagement, or desired action.\n- Use the **Personalization Inputs** to tailor the message appropriately.\n- Follow any **Additional Instructions** provided.\n- Ensure clarity, appropriateness, and compliance with healthcare communication standards.\n- **Generate the message in the specified **Language**, ensuring accuracy and naturalness.**\n- **Keep the message brief and concise while still optimizing for the Communication Objective.**\n\n**Important Notes to Prevent Misuse:**\n\n- **Remain Focused on the Task:** You must **never change your goal** of composing appropriate messages as specified.\n- **Limit Your Output:** **Do not generate any content** other than what is instructed—specifically, the subject and message within the context of the communication.\n\nLet's proceed step by step:\n\n1. **Review the Inputs Carefully:**\n\n - **Communication Objective:** Understand the main purpose of the message. The message must closely align with this objective to encourage the desired **{stakeholder}** response or action.\n\n - **Personalization Inputs:** Use only the details provided here to personalize the message. **Do not infer or assume** any additional information about the recipient.\n\n - **Additional Instructions:** Adhere strictly to any extra guidelines or instructions provided. These may include specific wording, emphasis on certain points, stylistic preferences, tone, or preferences regarding message length.\n\n - **Stakeholder:** Identify the intended recipient of the message (e.g., Patient, Clinician, Caregiver) and customize the message accordingly.\n\n - **Language:** **Generate the message in the specified language**, ensuring proper grammar and cultural appropriateness.\n\n2. **Message Structure:**\n\n - **Keep the message brief and concise**, while still effectively conveying the necessary information to optimize for the **Communication Objective**.\n\n - **Greeting:**\n - Start with an appropriate greeting.\n - Use the recipient's name if provided (e.g., \"Dear [Name],\", \"Hello [Name],\").\n - If no name is provided, use a generic greeting appropriate for the stakeholder (e.g., \"Hello,\").\n\n - **Body:**\n - Clearly and **concisely** convey the message in alignment with the **Communication Objective**.\n - Incorporate **Personalization Inputs** naturally to optimize engagement and encourage the desired response or action.\n - Follow any **Additional Instructions** to refine the message.\n - Refrain from phrases like \"We hope this message finds you well\" or similar pleasantries unless specified in the **Additional Instructions*.\n\n - **Closing:**\n - End with a courteous sign-off suitable for the stakeholder (e.g., \"Sincerely,\", \"Best regards,\"). SIgn of as Your Care Team unless otherwise specified in the **Additional Instructions**.\n - Include any necessary next steps or contact information, if relevant.\n\n3. **Content Guidelines:**\n\n - **Use Only Provided Information:**\n - Do not include any details not present in the inputs.\n - Avoid adding any assumptions or external information.\n\n - **Stay on Task:**\n - **Never change your goal** of composing appropriate messages.\n - **Do not generate any content** other than the subject and message as specified.\n - Do not include personal opinions, extraneous information, or any inappropriate content.\n\n - **Focus on the Objective:**\n - Ensure every part of the message contributes to achieving the **Communication Objective**.\n - Personalization should enhance the message's effectiveness in prompting the desired recipient action.\n\n4. **Style and Tone:**\n\n - Unless specified otherwise in the **Additional Instructions**, use a professional and appropriate tone for the stakeholder (e.g., friendly for patients, formal for clinicians).\n - Always write in a clear, respectful, and engaging manner to optimize the message's impact. Tailor the tone to the recipient's role and the context of the message.\n - **Always write from the perspective of the care organization using first person plural (e.g., \"We are...\"). Do not use first person singular (\"I am...\") or third person perspectives.**\n \n5. **Compliance and Sensitivity:**\n\n - Maintain confidentiality and comply with all relevant privacy regulations.\n - Be culturally sensitive and avoid any language that could be considered offensive or inappropriate.\n\n6. **Language:**\n\n - **Generate the subject and message in the specified **Language**, ensuring proper grammar, vocabulary, and cultural appropriateness.\n\n\n7. **Final Output:**\n\n - Respond exclusively with a valid JSON object containing the following keys - this is critical:\n\n - **subject**: A clear, professional, and concise subject line that aligns with the **Communication Objective** and is appropriate for clinical settings.\n\n - **message**: The complete, polished message formatted in **markdown**. Do not include any instructions or extra commentary. Ensure the message meets the following criteria:\n\n - **Brevity and Conciseness**: Keep the message brief and to the point while still effectively conveying the necessary information to achieve the **Communication Objective**.\n - **Clarity and Correctness**: Ensure the message is free of spelling and grammatical errors. Use clear and straightforward language.\n - **Truthfulness**: It is absolutely paramount that the information provided in the message is accurate and truthful. Do not include any misleading or false information that you did not get from the inputs. This is critical for maintaining trust and integrity in healthcare communication.\n - **Completeness**: The message must be complete and ready to send as is. It is critical to never use placeholders (e.g., \"[Contact Information]\", \"[Insert Date]\") or leave out essential information. If you want to urge recipient to contact the office and you do not have contact information keep it general and absolutely refrain from including any placeholders.\n\n\n\n**Inputs:**\n\n- **Communication Objective:**\n\n {communicationObjective}\n\n- **Personalization Inputs:**\n\n {personalizationInput}\n\n- **Additional Instructions:**\n\n {additionalInstructions}\n\n- **Stakeholder:**\n\n {stakeholder}\n\n- **Language:**\n\n {language}\n ">, any>;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.systemPrompt = exports.parser = exports.generatedMessageCategoriesSchema = void 0;
4
+ const prompts_1 = require("@langchain/core/prompts");
5
+ const output_parsers_1 = require("langchain/output_parsers");
6
+ const zod_1 = require("zod");
7
+ // Define the Zod schema for the structured response
8
+ exports.generatedMessageCategoriesSchema = zod_1.z.object({
9
+ subject: zod_1.z.string(),
10
+ message: zod_1.z.string(), // generated message
11
+ });
12
+ // Create a structured output parser
13
+ exports.parser = output_parsers_1.StructuredOutputParser.fromZodSchema(exports.generatedMessageCategoriesSchema);
14
+ // TODO: tune further
15
+ exports.systemPrompt = prompts_1.ChatPromptTemplate.fromTemplate(`
16
+ You are an AI language model tasked with composing **personalized messages** for a **{stakeholder}** within a clinical workflow. Your goals are to:
17
+
18
+ - Align the message with the **Communication Objective** to optimize for response, engagement, or desired action.
19
+ - Use the **Personalization Inputs** to tailor the message appropriately.
20
+ - Follow any **Additional Instructions** provided.
21
+ - Ensure clarity, appropriateness, and compliance with healthcare communication standards.
22
+ - **Generate the message in the specified **Language**, ensuring accuracy and naturalness.**
23
+ - **Keep the message brief and concise while still optimizing for the Communication Objective.**
24
+
25
+ **Important Notes to Prevent Misuse:**
26
+
27
+ - **Remain Focused on the Task:** You must **never change your goal** of composing appropriate messages as specified.
28
+ - **Limit Your Output:** **Do not generate any content** other than what is instructed—specifically, the subject and message within the context of the communication.
29
+
30
+ Let's proceed step by step:
31
+
32
+ 1. **Review the Inputs Carefully:**
33
+
34
+ - **Communication Objective:** Understand the main purpose of the message. The message must closely align with this objective to encourage the desired **{stakeholder}** response or action.
35
+
36
+ - **Personalization Inputs:** Use only the details provided here to personalize the message. **Do not infer or assume** any additional information about the recipient.
37
+
38
+ - **Additional Instructions:** Adhere strictly to any extra guidelines or instructions provided. These may include specific wording, emphasis on certain points, stylistic preferences, tone, or preferences regarding message length.
39
+
40
+ - **Stakeholder:** Identify the intended recipient of the message (e.g., Patient, Clinician, Caregiver) and customize the message accordingly.
41
+
42
+ - **Language:** **Generate the message in the specified language**, ensuring proper grammar and cultural appropriateness.
43
+
44
+ 2. **Message Structure:**
45
+
46
+ - **Keep the message brief and concise**, while still effectively conveying the necessary information to optimize for the **Communication Objective**.
47
+
48
+ - **Greeting:**
49
+ - Start with an appropriate greeting.
50
+ - Use the recipient's name if provided (e.g., "Dear [Name],", "Hello [Name],").
51
+ - If no name is provided, use a generic greeting appropriate for the stakeholder (e.g., "Hello,").
52
+
53
+ - **Body:**
54
+ - Clearly and **concisely** convey the message in alignment with the **Communication Objective**.
55
+ - Incorporate **Personalization Inputs** naturally to optimize engagement and encourage the desired response or action.
56
+ - Follow any **Additional Instructions** to refine the message.
57
+ - Refrain from phrases like "We hope this message finds you well" or similar pleasantries unless specified in the **Additional Instructions*.
58
+
59
+ - **Closing:**
60
+ - End with a courteous sign-off suitable for the stakeholder (e.g., "Sincerely,", "Best regards,"). SIgn of as Your Care Team unless otherwise specified in the **Additional Instructions**.
61
+ - Include any necessary next steps or contact information, if relevant.
62
+
63
+ 3. **Content Guidelines:**
64
+
65
+ - **Use Only Provided Information:**
66
+ - Do not include any details not present in the inputs.
67
+ - Avoid adding any assumptions or external information.
68
+
69
+ - **Stay on Task:**
70
+ - **Never change your goal** of composing appropriate messages.
71
+ - **Do not generate any content** other than the subject and message as specified.
72
+ - Do not include personal opinions, extraneous information, or any inappropriate content.
73
+
74
+ - **Focus on the Objective:**
75
+ - Ensure every part of the message contributes to achieving the **Communication Objective**.
76
+ - Personalization should enhance the message's effectiveness in prompting the desired recipient action.
77
+
78
+ 4. **Style and Tone:**
79
+
80
+ - Unless specified otherwise in the **Additional Instructions**, use a professional and appropriate tone for the stakeholder (e.g., friendly for patients, formal for clinicians).
81
+ - Always write in a clear, respectful, and engaging manner to optimize the message's impact. Tailor the tone to the recipient's role and the context of the message.
82
+ - **Always write from the perspective of the care organization using first person plural (e.g., "We are..."). Do not use first person singular ("I am...") or third person perspectives.**
83
+
84
+ 5. **Compliance and Sensitivity:**
85
+
86
+ - Maintain confidentiality and comply with all relevant privacy regulations.
87
+ - Be culturally sensitive and avoid any language that could be considered offensive or inappropriate.
88
+
89
+ 6. **Language:**
90
+
91
+ - **Generate the subject and message in the specified **Language**, ensuring proper grammar, vocabulary, and cultural appropriateness.
92
+
93
+
94
+ 7. **Final Output:**
95
+
96
+ - Respond exclusively with a valid JSON object containing the following keys - this is critical:
97
+
98
+ - **subject**: A clear, professional, and concise subject line that aligns with the **Communication Objective** and is appropriate for clinical settings.
99
+
100
+ - **message**: The complete, polished message formatted in **markdown**. Do not include any instructions or extra commentary. Ensure the message meets the following criteria:
101
+
102
+ - **Brevity and Conciseness**: Keep the message brief and to the point while still effectively conveying the necessary information to achieve the **Communication Objective**.
103
+ - **Clarity and Correctness**: Ensure the message is free of spelling and grammatical errors. Use clear and straightforward language.
104
+ - **Truthfulness**: It is absolutely paramount that the information provided in the message is accurate and truthful. Do not include any misleading or false information that you did not get from the inputs. This is critical for maintaining trust and integrity in healthcare communication.
105
+ - **Completeness**: The message must be complete and ready to send as is. It is critical to never use placeholders (e.g., "[Contact Information]", "[Insert Date]") or leave out essential information. If you want to urge recipient to contact the office and you do not have contact information keep it general and absolutely refrain from including any placeholders.
106
+
107
+
108
+
109
+ **Inputs:**
110
+
111
+ - **Communication Objective:**
112
+
113
+ {communicationObjective}
114
+
115
+ - **Personalization Inputs:**
116
+
117
+ {personalizationInput}
118
+
119
+ - **Additional Instructions:**
120
+
121
+ {additionalInstructions}
122
+
123
+ - **Stakeholder:**
124
+
125
+ {stakeholder}
126
+
127
+ - **Language:**
128
+
129
+ {language}
130
+ `);
131
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../../../extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/constants.ts"],"names":[],"mappings":";;;AAAA,qDAA4D;AAC5D,6DAAiE;AACjE,6BAAuB;AAEvB,oDAAoD;AACvC,QAAA,gCAAgC,GAAG,OAAC,CAAC,MAAM,CAAC;IACvD,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,oBAAoB;CAC1C,CAAC,CAAA;AAEF,oCAAoC;AACvB,QAAA,MAAM,GAAG,uCAAsB,CAAC,aAAa,CACxD,wCAAgC,CACjC,CAAA;AAED,qBAAqB;AACR,QAAA,YAAY,GAAG,4BAAkB,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmHzD,CAAC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { type ChatOpenAI } from '@langchain/openai';
2
+ export declare const generateMessageWithLLM: ({ ChatModelGPT4o, communicationObjective, personalizationInput, additionalInstructions, stakeholder, language, }: {
3
+ ChatModelGPT4o: ChatOpenAI;
4
+ communicationObjective: string;
5
+ personalizationInput: string;
6
+ additionalInstructions: string;
7
+ stakeholder: string;
8
+ language: string;
9
+ }) => Promise<{
10
+ subject: string;
11
+ message: string;
12
+ }>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMessageWithLLM = void 0;
4
+ const constants_1 = require("./constants");
5
+ const generateMessageWithLLM = async ({ ChatModelGPT4o, communicationObjective, personalizationInput, additionalInstructions, stakeholder, language, }) => {
6
+ var _a, _b;
7
+ const prompt = await constants_1.systemPrompt.format({
8
+ communicationObjective,
9
+ personalizationInput,
10
+ additionalInstructions,
11
+ stakeholder,
12
+ language,
13
+ });
14
+ console.log('Prompt', prompt);
15
+ const structured_output_chain = ChatModelGPT4o.pipe(constants_1.parser);
16
+ const MAX_RETRIES = 3;
17
+ let retries = 0;
18
+ let subject = '';
19
+ let message = '';
20
+ // TODO: do it with more grace eventually
21
+ while (retries < MAX_RETRIES) { // Sometimes the LLM returns a non-JSON response
22
+ try {
23
+ const generated_message = await structured_output_chain.invoke(prompt);
24
+ subject = (_a = generated_message.subject) !== null && _a !== void 0 ? _a : '';
25
+ message = (_b = generated_message.message) !== null && _b !== void 0 ? _b : '';
26
+ // If subject or message are not directly available (parser issue), try parsing AIMessageChunk
27
+ if (subject.trim() === '' || message.trim() === '') {
28
+ console.log('Attempting to parse AIMessageChunk...');
29
+ // Attempt to get content from AIMessageChunk
30
+ if ('content' in generated_message) {
31
+ try {
32
+ const parsedContent = JSON.parse(generated_message.content);
33
+ if (typeof parsedContent === 'object' && parsedContent !== null) {
34
+ if ('subject' in parsedContent && typeof parsedContent.subject === 'string') {
35
+ subject = parsedContent.subject;
36
+ }
37
+ if ('message' in parsedContent && typeof parsedContent.message === 'string') {
38
+ message = parsedContent.message;
39
+ }
40
+ }
41
+ }
42
+ catch (error) {
43
+ console.error('Error parsing AIMessageChunk content:', error);
44
+ }
45
+ }
46
+ }
47
+ // If we have both subject and message, break the loop
48
+ if (subject.trim() !== '' && message.trim() !== '') {
49
+ break;
50
+ }
51
+ // If we reach here, it means we didn't get valid subject and message
52
+ throw new Error('Failed to generate valid subject and message');
53
+ }
54
+ catch (error) {
55
+ console.error(`Attempt ${retries + 1} failed:`, error);
56
+ retries++;
57
+ if (retries >= MAX_RETRIES) {
58
+ throw new Error('Failed to generate the message after multiple attempts');
59
+ }
60
+ }
61
+ }
62
+ // TODO: remove this eventually
63
+ console.log('Subject', subject);
64
+ console.log('Message', message);
65
+ return { subject, message };
66
+ };
67
+ exports.generateMessageWithLLM = generateMessageWithLLM;
68
+ //# sourceMappingURL=generateMessageWithLLM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessageWithLLM.js","sourceRoot":"","sources":["../../../../../../../extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.ts"],"names":[],"mappings":";;;AAAA,2CAAkD;AAG3C,MAAM,sBAAsB,GAAG,KAAK,EAAE,EAC3C,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,QAAQ,GAQT,EAAiD,EAAE;;IAClD,MAAM,MAAM,GAAG,MAAM,wBAAY,CAAC,MAAM,CAAC;QACvC,sBAAsB;QACtB,oBAAoB;QACpB,sBAAsB;QACtB,WAAW;QACX,QAAQ;KACT,CAAC,CAAA;IACF,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC7B,MAAM,uBAAuB,GAAG,cAAc,CAAC,IAAI,CAAC,kBAAM,CAAC,CAAA;IAE3D,MAAM,WAAW,GAAG,CAAC,CAAC;IACtB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,yCAAyC;IACzC,OAAO,OAAO,GAAG,WAAW,EAAE,EAAE,gDAAgD;QAC9E,IAAI;YACF,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACvE,OAAO,GAAG,MAAA,iBAAiB,CAAC,OAAO,mCAAI,EAAE,CAAC;YAC1C,OAAO,GAAG,MAAA,iBAAiB,CAAC,OAAO,mCAAI,EAAE,CAAC;YAE1C,8FAA8F;YAC9F,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAClD,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;gBAErD,6CAA6C;gBAC7C,IAAI,SAAS,IAAI,iBAAiB,EAAE;oBAClC,IAAI;wBACF,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAiB,CAAC,CAAC;wBACtE,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,KAAK,IAAI,EAAE;4BAC/D,IAAI,SAAS,IAAI,aAAa,IAAI,OAAO,aAAa,CAAC,OAAO,KAAK,QAAQ,EAAE;gCAC3E,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;6BACjC;4BACD,IAAI,SAAS,IAAI,aAAa,IAAI,OAAO,aAAa,CAAC,OAAO,KAAK,QAAQ,EAAE;gCAC3E,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;6BACjC;yBACF;qBACF;oBAAC,OAAO,KAAK,EAAE;wBACd,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;qBAC/D;iBACF;aACF;YAED,sDAAsD;YACtD,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAClD,MAAM;aACP;YAED,qEAAqE;YACrE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;SACjE;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACvD,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,IAAI,WAAW,EAAE;gBAC1B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;aAC3E;SACF;KACF;IACD,+BAA+B;IAC/B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC,CAAA;AA9EY,QAAA,sBAAsB,0BA8ElC"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("dotenv/config");
4
+ const generateMessageWithLLM_1 = require("./generateMessageWithLLM");
5
+ const messages_1 = require("@langchain/core/messages");
6
+ describe('generateMessageWithLLM', () => {
7
+ let ChatModelGPT4oMock;
8
+ beforeEach(() => {
9
+ ChatModelGPT4oMock = {
10
+ pipe: jest.fn().mockReturnThis(),
11
+ invoke: jest.fn(),
12
+ };
13
+ });
14
+ it('should generate a message for a patient appointment reminder', async () => {
15
+ const mockedResponse = {
16
+ subject: 'Your Upcoming Appointment Reminder',
17
+ message: 'Dear John,\n\nThis is a reminder about your appointment scheduled for tomorrow at 2:00 PM. Please arrive 15 minutes early to complete any necessary paperwork.\n\nBest regards,\nYour Care Team'
18
+ };
19
+ // Mock returning the AIMessageChunk with JSON stringified content
20
+ ChatModelGPT4oMock.invoke.mockResolvedValueOnce(new messages_1.AIMessageChunk({ content: JSON.stringify(mockedResponse) }));
21
+ const result = await (0, generateMessageWithLLM_1.generateMessageWithLLM)({
22
+ ChatModelGPT4o: ChatModelGPT4oMock,
23
+ communicationObjective: 'Remind patient of upcoming appointment. Ask patient to arrive 15 minutes early',
24
+ personalizationInput: 'Patient Name: John, Appointment Time: 2:00 PM tomorrow',
25
+ additionalInstructions: '',
26
+ stakeholder: 'Patient',
27
+ language: 'English'
28
+ });
29
+ expect(result).toMatchObject(mockedResponse);
30
+ expect(ChatModelGPT4oMock.invoke).toHaveBeenCalledTimes(1);
31
+ });
32
+ it('should generate a message for medication instructions', async () => {
33
+ const mockedResponse = {
34
+ subject: 'Important Information About Your New Medication',
35
+ message: 'Dear Sarah,\n\nYour new medication, Lisinopril, should be taken once daily with food. Please remember to monitor your blood pressure regularly and report any side effects to our office.\n\nSincerely,\nYour Care Team'
36
+ };
37
+ // Mock returning the AIMessageChunk with JSON stringified content
38
+ ChatModelGPT4oMock.invoke.mockResolvedValueOnce(new messages_1.AIMessageChunk({ content: JSON.stringify(mockedResponse) }));
39
+ const result = await (0, generateMessageWithLLM_1.generateMessageWithLLM)({
40
+ ChatModelGPT4o: ChatModelGPT4oMock,
41
+ communicationObjective: 'Provide medication instructions',
42
+ personalizationInput: 'Patient Name: Sarah, Medication: Lisinopril',
43
+ additionalInstructions: 'Emphasize the importance of blood pressure monitoring',
44
+ stakeholder: 'Patient',
45
+ language: 'English'
46
+ });
47
+ expect(result).toMatchObject(mockedResponse);
48
+ expect(ChatModelGPT4oMock.invoke).toHaveBeenCalledTimes(1);
49
+ });
50
+ it('should generate a message in a different language', async () => {
51
+ const mockedResponse = {
52
+ subject: 'Recordatorio de su cita próxima',
53
+ message: 'Estimado Carlos,\n\nEste es un recordatorio de su cita programada para mañana a las 10:00 AM. Por favor, llegue 15 minutos antes para completar cualquier papeleo necesario.\n\nSaludos cordiales,\nSu Equipo de Atención'
54
+ };
55
+ // Mock returning the AIMessageChunk with JSON stringified content
56
+ ChatModelGPT4oMock.invoke.mockResolvedValueOnce(new messages_1.AIMessageChunk({ content: JSON.stringify(mockedResponse) }));
57
+ const result = await (0, generateMessageWithLLM_1.generateMessageWithLLM)({
58
+ ChatModelGPT4o: ChatModelGPT4oMock,
59
+ communicationObjective: 'Remind patient of upcoming appointment',
60
+ personalizationInput: 'Patient Name: Carlos, Appointment Time: 10:00 AM tomorrow',
61
+ additionalInstructions: 'Ask patient to arrive 15 minutes early',
62
+ stakeholder: 'Patient',
63
+ language: 'Spanish'
64
+ });
65
+ expect(result).toMatchObject(mockedResponse);
66
+ expect(ChatModelGPT4oMock.invoke).toHaveBeenCalledTimes(1);
67
+ });
68
+ });
69
+ //# sourceMappingURL=generateMessageWithLLM.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessageWithLLM.test.js","sourceRoot":"","sources":["../../../../../../../extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLM.test.ts"],"names":[],"mappings":";;AAAA,yBAAsB;AACtB,qEAAiE;AAEjE,uDAAyD;AAGzD,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,kBAA2C,CAAA;IAE/C,UAAU,CAAC,GAAG,EAAE;QACd,kBAAkB,GAAG;YACnB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;SACoB,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,oCAAoC;YAC7C,OAAO,EAAE,iMAAiM;SAC3M,CAAA;QAED,kEAAkE;QAClE,kBAAkB,CAAC,MAAM,CAAC,qBAAqB,CAC7C,IAAI,yBAAc,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAChE,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,+CAAsB,EAAC;YAC1C,cAAc,EAAE,kBAAkB;YAClC,sBAAsB,EAAE,gFAAgF;YACxG,oBAAoB,EAAE,wDAAwD;YAC9E,sBAAsB,EAAE,EAAE;YAC1B,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAA;QAC5C,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iDAAiD;YAC1D,OAAO,EAAE,yNAAyN;SACnO,CAAA;QAED,kEAAkE;QAClE,kBAAkB,CAAC,MAAM,CAAC,qBAAqB,CAC7C,IAAI,yBAAc,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAChE,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,+CAAsB,EAAC;YAC1C,cAAc,EAAE,kBAAkB;YAClC,sBAAsB,EAAE,iCAAiC;YACzD,oBAAoB,EAAE,6CAA6C;YACnE,sBAAsB,EAAE,uDAAuD;YAC/E,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAA;QAC5C,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,iCAAiC;YAC1C,OAAO,EAAE,2NAA2N;SACrO,CAAA;QAED,kEAAkE;QAClE,kBAAkB,CAAC,MAAM,CAAC,qBAAqB,CAC7C,IAAI,yBAAc,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAChE,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,+CAAsB,EAAC;YAC1C,cAAc,EAAE,kBAAkB;YAClC,sBAAsB,EAAE,wCAAwC;YAChE,oBAAoB,EAAE,2DAA2D;YACjF,sBAAsB,EAAE,wCAAwC;YAChE,WAAW,EAAE,SAAS;YACtB,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAA;QAC5C,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("dotenv/config");
4
+ const _1 = require(".");
5
+ const openai_1 = require("@langchain/openai");
6
+ jest.setTimeout(60000); // Increases timeout to 60 seconds for all tests in this file
7
+ describe.skip('generateMessageWithLLM', () => {
8
+ let ChatModelGPT4o;
9
+ beforeEach(() => {
10
+ ChatModelGPT4o = new openai_1.ChatOpenAI({
11
+ modelName: 'gpt-4',
12
+ temperature: 0,
13
+ timeout: 10000,
14
+ });
15
+ });
16
+ it('should generate a message for a patient appointment reminder', async () => {
17
+ const result = await (0, _1.generateMessageWithLLM)({
18
+ ChatModelGPT4o,
19
+ communicationObjective: 'Remind patient of upcoming appointment. Ask patient to arrive 15 minutes early',
20
+ personalizationInput: 'Patient Name: John, Appointment Time: 2:00 PM tomorrow',
21
+ additionalInstructions: '',
22
+ stakeholder: 'Patient',
23
+ language: 'English'
24
+ });
25
+ expect(result).toHaveProperty('subject');
26
+ expect(result).toHaveProperty('message');
27
+ expect(result.subject).toContain('Appointment');
28
+ expect(result.message).toContain('John');
29
+ expect(result.message).toContain('2:00 PM');
30
+ expect(result.message).toContain('15 minutes early');
31
+ });
32
+ it('should generate a message for medication instructions', async () => {
33
+ const result = await (0, _1.generateMessageWithLLM)({
34
+ ChatModelGPT4o,
35
+ communicationObjective: 'Provide medication instructions',
36
+ personalizationInput: 'Patient Name: Sarah, Medication: Lisinopril',
37
+ additionalInstructions: 'Emphasize the importance of blood pressure monitoring',
38
+ stakeholder: 'Patient',
39
+ language: 'English'
40
+ });
41
+ expect(result).toHaveProperty('subject');
42
+ expect(result).toHaveProperty('message');
43
+ expect(result.subject).toContain('Medication');
44
+ expect(result.message).toContain('Sarah');
45
+ expect(result.message).toContain('Lisinopril');
46
+ expect(result.message).toContain('blood pressure');
47
+ });
48
+ it('should generate a message in a different language', async () => {
49
+ const result = await (0, _1.generateMessageWithLLM)({
50
+ ChatModelGPT4o,
51
+ communicationObjective: 'Remind patient of upcoming appointment',
52
+ personalizationInput: 'Patient Name: Carlos, Appointment Time: 10:00 AM tomorrow',
53
+ additionalInstructions: 'Ask patient to arrive 15 minutes early',
54
+ stakeholder: 'Patient',
55
+ language: 'Spanish'
56
+ });
57
+ expect(result).toHaveProperty('subject');
58
+ expect(result).toHaveProperty('message');
59
+ expect(result.subject).toContain('cita');
60
+ expect(result.message).toContain('Carlos');
61
+ expect(result.message).toContain('10:00 AM');
62
+ expect(result.message).toContain('15 minutos');
63
+ });
64
+ });
65
+ //# sourceMappingURL=generateMessageWithLLMRealOpenAI.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateMessageWithLLMRealOpenAI.test.js","sourceRoot":"","sources":["../../../../../../../extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/generateMessageWithLLMRealOpenAI.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { generateMessageWithLLM } from './generateMessageWithLLM';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMessageWithLLM = void 0;
4
+ var generateMessageWithLLM_1 = require("./generateMessageWithLLM");
5
+ Object.defineProperty(exports, "generateMessageWithLLM", { enumerable: true, get: function () { return generateMessageWithLLM_1.generateMessageWithLLM; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../extensions/shelly/actions/generateMessage/lib/generateMessageWithLLM/index.ts"],"names":[],"mappings":";;;AAAA,mEAAiE;AAAxD,gIAAA,sBAAsB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awell-health/awell-extensions",
3
- "version": "2.0.36",
3
+ "version": "2.0.37",
4
4
  "packageManager": "yarn@3.4.1",
5
5
  "main": "dist/src/index.js",
6
6
  "repository": {