@ctchealth/plato-sdk 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -17
- package/package.json +4 -3
- package/src/index.d.ts +14 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/plato-intefaces.d.ts +243 -0
- package/src/lib/plato-intefaces.js +124 -0
- package/src/lib/plato-intefaces.js.map +1 -0
- package/src/lib/plato-sdk.d.ts +102 -0
- package/src/lib/plato-sdk.js +257 -0
- package/src/lib/plato-sdk.js.map +1 -0
- package/eslint.config.cjs +0 -121
- package/jest.config.ts +0 -10
- package/project.json +0 -24
- package/src/index.ts +0 -1
- package/src/lib/plato-intefaces.ts +0 -232
- package/src/lib/plato-sdk.ts +0 -265
- package/tsconfig.json +0 -22
- package/tsconfig.lib.json +0 -11
- package/tsconfig.spec.json +0 -10
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlatoApiClient = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/**
|
|
6
|
+
* Copyright (c) 2025 ctcHealth. All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* This file is part of the ctcHealth Plato Platform, a proprietary software system developed by ctcHealth.
|
|
9
|
+
*
|
|
10
|
+
* This source code and all related materials are confidential and proprietary to ctcHealth.
|
|
11
|
+
* Unauthorized access, use, copying, modification, distribution, or disclosure is strictly prohibited
|
|
12
|
+
* and may result in disciplinary action and civil and/or criminal penalties.
|
|
13
|
+
*
|
|
14
|
+
* This software is intended solely for authorized use within ctcHealth and its designated partners.
|
|
15
|
+
*
|
|
16
|
+
* For internal use only.
|
|
17
|
+
*/
|
|
18
|
+
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
19
|
+
const web_1 = tslib_1.__importDefault(require("@vapi-ai/web"));
|
|
20
|
+
class PlatoApiClient {
|
|
21
|
+
config;
|
|
22
|
+
http;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
24
|
+
eventListeners = {};
|
|
25
|
+
callControllerInstance;
|
|
26
|
+
eventsAttached = false;
|
|
27
|
+
eventNames = [
|
|
28
|
+
'call-start',
|
|
29
|
+
'call-end',
|
|
30
|
+
'speech-start',
|
|
31
|
+
'speech-end',
|
|
32
|
+
'error',
|
|
33
|
+
'message',
|
|
34
|
+
'volume-level',
|
|
35
|
+
];
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = config;
|
|
38
|
+
if (!config.baseUrl) {
|
|
39
|
+
throw new Error('baseUrl is required');
|
|
40
|
+
}
|
|
41
|
+
if (!config.token) {
|
|
42
|
+
throw new Error('token is required');
|
|
43
|
+
}
|
|
44
|
+
if (!config.user) {
|
|
45
|
+
throw new Error('user is required');
|
|
46
|
+
}
|
|
47
|
+
if (config.baseUrl.endsWith('/')) {
|
|
48
|
+
config.baseUrl = config.baseUrl.slice(0, -1);
|
|
49
|
+
}
|
|
50
|
+
this.http = axios_1.default.create({
|
|
51
|
+
baseURL: config.baseUrl,
|
|
52
|
+
headers: {
|
|
53
|
+
'x-api-key': config.token,
|
|
54
|
+
'x-api-key-user': config.user,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Register a listener for a call event with strict typing.
|
|
60
|
+
* @param event Event name
|
|
61
|
+
* @param listener Listener function
|
|
62
|
+
*/
|
|
63
|
+
on(event, listener) {
|
|
64
|
+
if (!this.eventListeners[event]) {
|
|
65
|
+
this.eventListeners[event] = [];
|
|
66
|
+
}
|
|
67
|
+
const listeners = this.eventListeners[event];
|
|
68
|
+
if (listeners) {
|
|
69
|
+
listeners.push(listener);
|
|
70
|
+
}
|
|
71
|
+
if (this.callControllerInstance && !this.eventsAttached) {
|
|
72
|
+
this.attachEvents();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Remove a listener for a call event with strict typing.
|
|
77
|
+
* @param event Event name
|
|
78
|
+
* @param listener Listener function
|
|
79
|
+
*/
|
|
80
|
+
off(event, listener) {
|
|
81
|
+
const listeners = this.eventListeners[event];
|
|
82
|
+
if (!listeners)
|
|
83
|
+
return;
|
|
84
|
+
this.eventListeners[event] = listeners.filter(l => l !== listener);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Internal: Attach event listeners and propagate to registered listeners.
|
|
88
|
+
*/
|
|
89
|
+
attachEvents() {
|
|
90
|
+
if (this.eventsAttached || !this.callControllerInstance)
|
|
91
|
+
return;
|
|
92
|
+
this.eventsAttached = true;
|
|
93
|
+
const vapi = this.callControllerInstance;
|
|
94
|
+
this.eventNames.forEach(event => {
|
|
95
|
+
vapi.on(event, (payload) => {
|
|
96
|
+
(this.eventListeners[event] || []).forEach(listener => listener(payload));
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async createSimulation(createSimulationParams) {
|
|
101
|
+
try {
|
|
102
|
+
const res = await this.http.post('/api/v1/simulation', {
|
|
103
|
+
...createSimulationParams,
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
simulationId: res.data.simulationId,
|
|
107
|
+
phase: res.data.phase,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
112
|
+
console.error('Error creating simulation:', e.response?.data.message);
|
|
113
|
+
}
|
|
114
|
+
throw e;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async checkSimulationStatus(simulationId) {
|
|
118
|
+
const res = await this.http.get(`/api/v1/simulation/status/${simulationId}`);
|
|
119
|
+
return res.data;
|
|
120
|
+
}
|
|
121
|
+
async getUserSimulations() {
|
|
122
|
+
try {
|
|
123
|
+
const res = await this.http.get('/api/v1/simulation/user/simulations');
|
|
124
|
+
return res.data;
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
128
|
+
console.error('Error getting user simulations:', e.response?.data.message);
|
|
129
|
+
}
|
|
130
|
+
throw e;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async getSimulationDetails(simulationId) {
|
|
134
|
+
try {
|
|
135
|
+
const res = await this.http.get(`/api/v1/simulation/details/${simulationId}`);
|
|
136
|
+
return res.data;
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
140
|
+
console.error('Error getting simulation details:', e.response?.data.message);
|
|
141
|
+
}
|
|
142
|
+
throw e;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async getCallDetails(callId) {
|
|
146
|
+
try {
|
|
147
|
+
const res = await this.http.get(`/api/v1/simulation/call/${callId}`);
|
|
148
|
+
return res.data;
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
152
|
+
console.error('Error getting call details:', e.response?.data.message);
|
|
153
|
+
}
|
|
154
|
+
throw e;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getCallRecordings(queryParams) {
|
|
158
|
+
try {
|
|
159
|
+
const res = await this.http.get(`/api/v1/simulation/call/recordings`, {
|
|
160
|
+
params: queryParams,
|
|
161
|
+
});
|
|
162
|
+
return res.data;
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
166
|
+
console.error('Error getting call recordings:', e.response?.data.message);
|
|
167
|
+
}
|
|
168
|
+
throw e;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async getCallRecording(callId) {
|
|
172
|
+
try {
|
|
173
|
+
const res = await this.http.get(`/api/v1/simulation/call/recordings/${callId}`);
|
|
174
|
+
return res.data;
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
if (axios_1.default.isAxiosError(e)) {
|
|
178
|
+
console.error('Error getting call recording:', e.response?.data.message);
|
|
179
|
+
}
|
|
180
|
+
throw e;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Remove all listeners for all call events.
|
|
185
|
+
*/
|
|
186
|
+
removeAllEventListeners() {
|
|
187
|
+
if (!this.callControllerInstance)
|
|
188
|
+
return;
|
|
189
|
+
this.eventNames.forEach(event => {
|
|
190
|
+
(this.eventListeners[event] || []).forEach(listener => {
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
192
|
+
// @ts-expect-error
|
|
193
|
+
this.callControllerInstance?.off(event, listener);
|
|
194
|
+
});
|
|
195
|
+
this.eventListeners[event] = [];
|
|
196
|
+
});
|
|
197
|
+
this.eventsAttached = false;
|
|
198
|
+
}
|
|
199
|
+
async startCall(simulationId) {
|
|
200
|
+
this.callControllerInstance = new web_1.default('f07d17ec-d4e6-487d-a0b9-0539c01aecbb', 'https://db41aykk1gw9e.cloudfront.net' // base url
|
|
201
|
+
);
|
|
202
|
+
if (!this.eventsAttached) {
|
|
203
|
+
this.attachEvents();
|
|
204
|
+
}
|
|
205
|
+
const { data } = await this.http.get(`/api/v1/simulation/${simulationId}`);
|
|
206
|
+
const assistantId = data;
|
|
207
|
+
const call = await this.callControllerInstance.start(assistantId);
|
|
208
|
+
if (!call || !call.assistantId) {
|
|
209
|
+
throw new Error('Cannot start a call, please try again later');
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const apiCall = await this.createCall({
|
|
213
|
+
callId: call.id,
|
|
214
|
+
assistantId: call.assistantId,
|
|
215
|
+
});
|
|
216
|
+
// Return stopCall, callId, and event subscription methods with strict typing
|
|
217
|
+
return {
|
|
218
|
+
stopCall: () => {
|
|
219
|
+
this.callControllerInstance?.stop();
|
|
220
|
+
this.removeAllEventListeners();
|
|
221
|
+
},
|
|
222
|
+
callId: apiCall._id,
|
|
223
|
+
/**
|
|
224
|
+
* Subscribe to call events for this call with strict typing.
|
|
225
|
+
* @param event Event name
|
|
226
|
+
* @param listener Listener function
|
|
227
|
+
*/
|
|
228
|
+
on: (event, listener) => this.on(event, listener),
|
|
229
|
+
/**
|
|
230
|
+
* Unsubscribe from call events for this call with strict typing.
|
|
231
|
+
* @param event Event name
|
|
232
|
+
* @param listener Listener function
|
|
233
|
+
*/
|
|
234
|
+
off: (event, listener) => this.off(event, listener),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
this.callControllerInstance?.stop();
|
|
239
|
+
this.removeAllEventListeners();
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async createCall(payload) {
|
|
244
|
+
const response = await this.http.post('/api/v1/simulation/call', {
|
|
245
|
+
...payload,
|
|
246
|
+
});
|
|
247
|
+
return response.data;
|
|
248
|
+
}
|
|
249
|
+
async uploadPdfSlides(file) {
|
|
250
|
+
const formData = new FormData();
|
|
251
|
+
formData.append('file', file);
|
|
252
|
+
const response = await this.http.post('/api/v1/pdfSlides/upload', formData);
|
|
253
|
+
return response.data;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.PlatoApiClient = PlatoApiClient;
|
|
257
|
+
//# sourceMappingURL=plato-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plato-sdk.js","sourceRoot":"","sources":["../../../../../libs/plato-sdk/src/lib/plato-sdk.ts"],"names":[],"mappings":"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"}
|
package/eslint.config.cjs
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
const { defineConfig, globalIgnores } = require('eslint/config');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const typescriptEslintEslintPlugin = require('@typescript-eslint/eslint-plugin');
|
|
5
|
-
const globals = require('globals');
|
|
6
|
-
const tsParser = require('@typescript-eslint/parser');
|
|
7
|
-
const jest = require('eslint-plugin-jest');
|
|
8
|
-
const js = require('@eslint/js');
|
|
9
|
-
const headers = require('eslint-plugin-headers');
|
|
10
|
-
const { FlatCompat } = require('@eslint/eslintrc');
|
|
11
|
-
const baseRules = require('../../eslint-config-base.cjs');
|
|
12
|
-
|
|
13
|
-
const compat = new FlatCompat({
|
|
14
|
-
baseDirectory: __dirname,
|
|
15
|
-
recommendedConfig: js.configs.recommended,
|
|
16
|
-
allConfig: js.configs.all,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
module.exports = defineConfig([
|
|
20
|
-
globalIgnores([
|
|
21
|
-
'**/.eslintrc.js',
|
|
22
|
-
'src/index.d.ts',
|
|
23
|
-
'scripts/db-migrations/archived/**/*',
|
|
24
|
-
'**/*.spec.ts',
|
|
25
|
-
'**/*.config.js',
|
|
26
|
-
'**/*.config.cjs',
|
|
27
|
-
'**/jest.config.ts',
|
|
28
|
-
]),
|
|
29
|
-
{
|
|
30
|
-
files: ['**/*.ts'],
|
|
31
|
-
plugins: {
|
|
32
|
-
headers,
|
|
33
|
-
},
|
|
34
|
-
rules: {
|
|
35
|
-
'headers/header-format': [
|
|
36
|
-
'error',
|
|
37
|
-
{
|
|
38
|
-
source: 'string',
|
|
39
|
-
content: `Copyright (c) 2025 ctcHealth. All rights reserved.
|
|
40
|
-
|
|
41
|
-
This file is part of the ctcHealth Plato Platform, a proprietary software system developed by ctcHealth.
|
|
42
|
-
|
|
43
|
-
This source code and all related materials are confidential and proprietary to ctcHealth.
|
|
44
|
-
Unauthorized access, use, copying, modification, distribution, or disclosure is strictly prohibited
|
|
45
|
-
and may result in disciplinary action and civil and/or criminal penalties.
|
|
46
|
-
|
|
47
|
-
This software is intended solely for authorized use within ctcHealth and its designated partners.
|
|
48
|
-
|
|
49
|
-
For internal use only.`,
|
|
50
|
-
style: 'jsdoc',
|
|
51
|
-
trailingNewlines: 1,
|
|
52
|
-
preservePragmas: false,
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
extends: compat.extends(
|
|
59
|
-
'plugin:@typescript-eslint/recommended',
|
|
60
|
-
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
|
61
|
-
'plugin:@typescript-eslint/strict'
|
|
62
|
-
),
|
|
63
|
-
|
|
64
|
-
files: ['**/*.ts'],
|
|
65
|
-
ignores: ['**/*.json', '**/*.spec.ts'],
|
|
66
|
-
|
|
67
|
-
plugins: {
|
|
68
|
-
'@typescript-eslint': typescriptEslintEslintPlugin,
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
languageOptions: {
|
|
72
|
-
globals: {
|
|
73
|
-
...globals.node,
|
|
74
|
-
...globals.jest,
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
parser: tsParser,
|
|
78
|
-
ecmaVersion: 10,
|
|
79
|
-
sourceType: 'module',
|
|
80
|
-
|
|
81
|
-
parserOptions: {
|
|
82
|
-
project: path.join(__dirname, 'tsconfig.lib.json'),
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
rules: {
|
|
87
|
-
...baseRules.rules, // shared rules
|
|
88
|
-
// project-specific rules
|
|
89
|
-
'@typescript-eslint/ban-ts-comment': 'warn',
|
|
90
|
-
'@typescript-eslint/interface-name-prefix': 'off',
|
|
91
|
-
'@typescript-eslint/explicit-function-return-type': 'warn',
|
|
92
|
-
'@typescript-eslint/promise-function-async': ['error'],
|
|
93
|
-
'@typescript-eslint/no-floating-promises': 'error',
|
|
94
|
-
'@typescript-eslint/await-thenable': 'error',
|
|
95
|
-
semi: ['error', 'always'],
|
|
96
|
-
'@typescript-eslint/unbound-method': 'error',
|
|
97
|
-
'keyword-spacing': ['error'],
|
|
98
|
-
'@typescript-eslint/restrict-template-expressions': 'error',
|
|
99
|
-
'@typescript-eslint/prefer-regexp-exec': 'warn',
|
|
100
|
-
'@typescript-eslint/require-await': 'warn',
|
|
101
|
-
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
102
|
-
'@typescript-eslint/no-unnecessary-condition': 'warn',
|
|
103
|
-
'@typescript-eslint/prefer-ts-expect-error': 'warn',
|
|
104
|
-
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
105
|
-
'space-infix-ops': 'off',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
files: ['**/*.spec.ts'],
|
|
110
|
-
extends: compat.extends('plugin:jest/recommended'),
|
|
111
|
-
|
|
112
|
-
plugins: {
|
|
113
|
-
jest,
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
rules: {
|
|
117
|
-
'@typescript-eslint/unbound-method': 'off',
|
|
118
|
-
'jest/unbound-method': 'error',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
]);
|
package/jest.config.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
displayName: 'plato-sdk',
|
|
3
|
-
preset: '../../jest.preset.js',
|
|
4
|
-
testEnvironment: 'node',
|
|
5
|
-
transform: {
|
|
6
|
-
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
7
|
-
},
|
|
8
|
-
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
|
-
coverageDirectory: '../../coverage/libs/plato-sdk',
|
|
10
|
-
};
|
package/project.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "plato-sdk",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "libs/plato-sdk/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"tags": [],
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/js:tsc",
|
|
10
|
-
"outputs": ["{options.outputPath}"],
|
|
11
|
-
"options": {
|
|
12
|
-
"outputPath": "dist/libs/plato-sdk",
|
|
13
|
-
"main": "libs/plato-sdk/src/index.ts",
|
|
14
|
-
"tsConfig": "libs/plato-sdk/tsconfig.lib.json",
|
|
15
|
-
"assets": ["libs/plato-sdk/*.md"]
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"nx-release-publish": {
|
|
19
|
-
"options": {
|
|
20
|
-
"packageRoot": "dist/{projectRoot}"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/plato-sdk';
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2025 ctcHealth. All rights reserved.
|
|
3
|
-
*
|
|
4
|
-
* This file is part of the ctcHealth Plato Platform, a proprietary software system developed by ctcHealth.
|
|
5
|
-
*
|
|
6
|
-
* This source code and all related materials are confidential and proprietary to ctcHealth.
|
|
7
|
-
* Unauthorized access, use, copying, modification, distribution, or disclosure is strictly prohibited
|
|
8
|
-
* and may result in disciplinary action and civil and/or criminal penalties.
|
|
9
|
-
*
|
|
10
|
-
* This software is intended solely for authorized use within ctcHealth and its designated partners.
|
|
11
|
-
*
|
|
12
|
-
* For internal use only.
|
|
13
|
-
*/
|
|
14
|
-
export enum YearOfExperience {
|
|
15
|
-
'1-5' = '1-5 years',
|
|
16
|
-
'6-10' = '6-10 years',
|
|
17
|
-
'11-20' = '16-20 years',
|
|
18
|
-
'20+' = '20+ years',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export enum PracticeType {
|
|
22
|
-
Private = 'Private Practice',
|
|
23
|
-
Hospital = 'Hospital',
|
|
24
|
-
AcademicMedicalCenter = 'Academic Medical Center',
|
|
25
|
-
Clinic = 'Clinic',
|
|
26
|
-
}
|
|
27
|
-
export enum SegmentType {
|
|
28
|
-
Traditionalist = 'The Traditionalist',
|
|
29
|
-
Innovator = 'The Innovator',
|
|
30
|
-
PatientOrientedPhysician = 'The Patient-Oriented Physician',
|
|
31
|
-
FinanciallyDrivenPrescriber = 'The Financially-Driven Prescriber',
|
|
32
|
-
EvidencePurist = 'The Evidence-Purist',
|
|
33
|
-
CostConsciousPrescriber = 'The Cost-Conscious Prescriber',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export enum AssistantVoiceGender {
|
|
37
|
-
Male = 'Male',
|
|
38
|
-
Female = 'Female',
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class PersonalityAndBehaviourDto {
|
|
42
|
-
riskTolerance!: number;
|
|
43
|
-
researchOrientation!: number;
|
|
44
|
-
recognitionNeed!: number;
|
|
45
|
-
brandLoyalty!: number;
|
|
46
|
-
patientEmpathy!: number;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class ProfessionalProfileDto {
|
|
50
|
-
practiceSettings!: string;
|
|
51
|
-
yearOfExperience!: number;
|
|
52
|
-
specialityAndDepartment!: string;
|
|
53
|
-
location!: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export class ContextDto {
|
|
57
|
-
subSpecialityOrTherapyFocus!: string;
|
|
58
|
-
typicalPatientMix!: string;
|
|
59
|
-
keyClinicalDrivers!: string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export class CharacterCreateDto {
|
|
63
|
-
name!: string;
|
|
64
|
-
professionalProfile!: ProfessionalProfileDto;
|
|
65
|
-
segment!: SegmentType;
|
|
66
|
-
personalityAndBehaviour!: PersonalityAndBehaviourDto;
|
|
67
|
-
context!: ContextDto;
|
|
68
|
-
assistantGender?: AssistantVoiceGender;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export class ProductConfig {
|
|
72
|
-
name!: string;
|
|
73
|
-
description!: string;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export class CreateSimulationDto {
|
|
77
|
-
persona!: CharacterCreateDto;
|
|
78
|
-
product!: ProductConfig;
|
|
79
|
-
presentation?: string;
|
|
80
|
-
scenario!: string;
|
|
81
|
-
objectives?: string[];
|
|
82
|
-
anticipatedObjections?: string[];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export type RecordingsLimit = 5 | 10 | 25;
|
|
86
|
-
|
|
87
|
-
export class SimulationRecordingsQueryDto {
|
|
88
|
-
limit?: RecordingsLimit;
|
|
89
|
-
page?: number;
|
|
90
|
-
sort?: SortOrder;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export enum SortOrder {
|
|
94
|
-
ASC = 'asc',
|
|
95
|
-
DESC = 'desc',
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export enum RecordingStatus {
|
|
99
|
-
STARTED = 'STARTED',
|
|
100
|
-
PROCESSING = 'PROCESSING',
|
|
101
|
-
FINISHED = 'FINISHED',
|
|
102
|
-
FAILED = 'FAILED',
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export class SimulationRecordingsDto {
|
|
106
|
-
_id!: string;
|
|
107
|
-
createdAt!: Date;
|
|
108
|
-
recordingStatus?: RecordingStatus;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
export interface CallCreateDto {
|
|
113
|
-
/**
|
|
114
|
-
* Call ID obtained
|
|
115
|
-
*/
|
|
116
|
-
callId: string;
|
|
117
|
-
/**
|
|
118
|
-
* Call Assistant ID
|
|
119
|
-
*/
|
|
120
|
-
assistantId: string;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface CallDTO {
|
|
124
|
-
/**
|
|
125
|
-
* call ID
|
|
126
|
-
*/
|
|
127
|
-
_id: string;
|
|
128
|
-
/**
|
|
129
|
-
* call ID obtained
|
|
130
|
-
*/
|
|
131
|
-
callId: string;
|
|
132
|
-
/**
|
|
133
|
-
* call User ID
|
|
134
|
-
*/
|
|
135
|
-
platoUserId: string;
|
|
136
|
-
/**
|
|
137
|
-
* call Assistant ID
|
|
138
|
-
*/
|
|
139
|
-
assistantId: string;
|
|
140
|
-
/**
|
|
141
|
-
* call summary of the conversation
|
|
142
|
-
*/
|
|
143
|
-
summary: string;
|
|
144
|
-
/**
|
|
145
|
-
* call transcript of the conversation
|
|
146
|
-
*/
|
|
147
|
-
transcript: string;
|
|
148
|
-
/**
|
|
149
|
-
* call feedback provided by the user
|
|
150
|
-
*/
|
|
151
|
-
feedback: string;
|
|
152
|
-
/**
|
|
153
|
-
* Success Evaluation returned by model
|
|
154
|
-
*/
|
|
155
|
-
successEvaluation: boolean;
|
|
156
|
-
/**
|
|
157
|
-
* call Recording URL
|
|
158
|
-
*/
|
|
159
|
-
recordingUrl: string;
|
|
160
|
-
/**
|
|
161
|
-
* Status of recording processing (e.g., 'STARTED', 'PROCESSING', 'FINISHED', 'FAILED')
|
|
162
|
-
*/
|
|
163
|
-
recordingStatus?: RecordingStatus;
|
|
164
|
-
/**
|
|
165
|
-
* Date and Time of the creation of the message
|
|
166
|
-
*/
|
|
167
|
-
createdAt: Date;
|
|
168
|
-
/**
|
|
169
|
-
* Date and Time of the creation of the message
|
|
170
|
-
*/
|
|
171
|
-
endedAt: Date;
|
|
172
|
-
/**
|
|
173
|
-
* Rating of the call given by the user
|
|
174
|
-
*/
|
|
175
|
-
rating: number;
|
|
176
|
-
/**
|
|
177
|
-
* Main strenghts of the user conversation based on the analysis of the AI
|
|
178
|
-
*/
|
|
179
|
-
strengths: Array<string>;
|
|
180
|
-
/**
|
|
181
|
-
* Main weak points of the user conversation based on the analysis of the AI
|
|
182
|
-
*/
|
|
183
|
-
weaknesses: Array<string>;
|
|
184
|
-
/**
|
|
185
|
-
* Name of Metric for the AI feedback report
|
|
186
|
-
*/
|
|
187
|
-
metric1: string;
|
|
188
|
-
/**
|
|
189
|
-
* Name of Metric for the AI feedback report
|
|
190
|
-
*/
|
|
191
|
-
metric2: string;
|
|
192
|
-
/**
|
|
193
|
-
* Name of Metric for the AI feedback report
|
|
194
|
-
*/
|
|
195
|
-
metric3: string;
|
|
196
|
-
/**
|
|
197
|
-
* AI feedback value for Metric 1
|
|
198
|
-
*/
|
|
199
|
-
metric1Value: number;
|
|
200
|
-
/**
|
|
201
|
-
* AI feedback value for Metric 2
|
|
202
|
-
*/
|
|
203
|
-
metric2Value: number;
|
|
204
|
-
/**
|
|
205
|
-
* AI feedback value for Metric 3
|
|
206
|
-
*/
|
|
207
|
-
metric3Value: number;
|
|
208
|
-
/**
|
|
209
|
-
* AI feedback value for the call score
|
|
210
|
-
*/
|
|
211
|
-
score?: number;
|
|
212
|
-
/**
|
|
213
|
-
* Defines if the calls will be consider for the memory feature
|
|
214
|
-
*/
|
|
215
|
-
inMemory: boolean;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export enum CreationStatus {
|
|
219
|
-
CREATING = 'CREATING',
|
|
220
|
-
READY = 'READY',
|
|
221
|
-
ERROR = 'ERROR',
|
|
222
|
-
}
|
|
223
|
-
export enum CreationPhase {
|
|
224
|
-
STARTING = 'STARTING',
|
|
225
|
-
CORE = 'CORE',
|
|
226
|
-
BOUNDARIES = 'BOUNDARIES',
|
|
227
|
-
SPEECH_AND_THOUGHT = 'SPEECH_AND_THOUGHT',
|
|
228
|
-
CONVERSATION_EVOLUTION = 'CONVERSATION_EVOLUTION',
|
|
229
|
-
MEMORY = 'MEMORY',
|
|
230
|
-
FINISHED = 'FINISHED',
|
|
231
|
-
ERROR = 'ERROR',
|
|
232
|
-
}
|