@ctchealth/plato-sdk 0.0.9 → 0.0.11

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 CHANGED
@@ -8,11 +8,12 @@ The Plato SDK provides a simple and type-safe way to integrate with the Plato pl
8
8
 
9
9
  ## Features
10
10
 
11
- - 🎭 Create AI personas with customizable professional profiles and personalities
12
- - 🗣️ Real-time voice interactions with AI assistants
13
- - 📊 Comprehensive event system for call management
14
- - 🔒 Type-safe API with full TypeScript support
15
- - 🎯 Medical training simulation configuration
11
+ - Create AI personas with customizable professional profiles and personalities
12
+ - Real-time voice interactions with AI assistants
13
+ - Comprehensive event system for call management
14
+ - Type-safe API with full TypeScript support
15
+ - Medical training simulation configuration
16
+ - Simulation persistence and recovery across page reloads
16
17
 
17
18
  ## Installation
18
19
 
@@ -64,16 +65,10 @@ const simulation = await client.createSimulation({
64
65
  },
65
66
  presentation: 'Oral tablets, 10 tablets per pack',
66
67
  scenario: 'Discussing treatment options for an elderly patient with chronic arthritis',
67
- objectives: [
68
- 'Demonstrate efficacy of Ibuprofen in pain management',
69
- 'Highlight safety profile and contraindications',
70
- 'Encourage patient adherence',
71
- ],
72
- anticipatedObjections: [
73
- 'Concerns about gastrointestinal side effects',
74
- 'Preference for lower-cost generic alternatives',
75
- 'Potential interactions with other medications',
76
- ],
68
+ objectives:
69
+ 'Demonstrate efficacy of Ibuprofen in pain management Highlight safety profile and contraindications Encourage patient adherence',
70
+ anticipatedObjections:
71
+ 'Concerns about gastrointestinal side effects Preference for lower-cost generic alternatives Potential interactions with other medications',
77
72
  });
78
73
 
79
74
  // Check the simulation status - If simulation creation phase is equals to FINISHED, the simulation is ready to use
@@ -161,6 +156,7 @@ Retrieves detailed information about a completed call, including transcript, sum
161
156
  - `metric1Value`, `metric2Value`, `metric3Value`: Values for each metric
162
157
  - `createdAt`: Timestamp when the call was created
163
158
  - `endedAt`: Timestamp when the call ended
159
+ - `callDurationMs`: Duration of the call in milliseconds
164
160
  - And other call-related fields
165
161
 
166
162
  **Example:**
@@ -221,6 +217,84 @@ const recordingUrl = await client.getCallRecording(call._id);
221
217
  console.log('Recording URL:', recordingUrl);
222
218
  ```
223
219
 
220
+ ##### uploadPdfSlides(file: File | Blob)
221
+
222
+ Uploads a PDF file for slide analysis. The file will be uploaded to S3 and analyzed asynchronously.
223
+
224
+ **Parameters:**
225
+
226
+ - `file` (File | Blob): The PDF file to upload
227
+
228
+ **Returns:** `Promise<UploadPdfSlidesResponseDto>` — An object containing:
229
+
230
+ - `objectKey`: The S3 object key where the PDF was saved
231
+ - `filename`: The original filename
232
+ - `size`: The file size in bytes
233
+ - `contentType`: The content type of the file
234
+
235
+ **Example:**
236
+
237
+ ```typescript
238
+ // Upload a PDF file from an input element
239
+ const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
240
+ const file = fileInput.files?.[0];
241
+
242
+ if (file) {
243
+ const result = await client.uploadPdfSlides(file);
244
+ console.log('PDF uploaded:', result.objectKey);
245
+ console.log('Original filename:', result.filename);
246
+ }
247
+ ```
248
+
249
+ ##### getRecommendations()
250
+
251
+ Retrieves recommendations based on the user's recent call performance. Analyzes up to 10 of the most recent calls to identify patterns and provide actionable insights.
252
+
253
+ **Returns:** `Promise<RecommendationsResponseDto>` — An object containing:
254
+
255
+ - `recommendations`: Array of recommendation objects, each with:
256
+ - `title`: Brief title of the recommendation
257
+ - `description`: Detailed, actionable description
258
+ - `priority`: Priority level (`'high'`, `'medium'`, or `'low'`)
259
+ - `strengths`: Array of identified strengths, each with:
260
+ - `strength`: Description of the strength
261
+ - `frequency`: Number of calls where this strength appeared
262
+ - `improvementAreas`: Array of areas needing improvement, each with:
263
+ - `area`: Description of the improvement area
264
+ - `frequency`: Number of calls where this weakness appeared
265
+ - `summary`: A 2-3 sentence overall summary of performance trends
266
+ - `callsAnalyzed`: Number of calls that were analyzed
267
+ - `generatedAt`: Timestamp when the recommendations were generated
268
+
269
+ **Example:**
270
+
271
+ ```typescript
272
+ // Get personalized recommendations based on call history
273
+ const recommendations = await client.getRecommendations();
274
+
275
+ console.log(`Analyzed ${recommendations.callsAnalyzed} calls`);
276
+ console.log('Summary:', recommendations.summary);
277
+
278
+ // Display high-priority recommendations
279
+ recommendations.recommendations
280
+ .filter(rec => rec.priority === 'high')
281
+ .forEach(rec => {
282
+ console.log(`[HIGH] ${rec.title}: ${rec.description}`);
283
+ });
284
+
285
+ // Show recurring strengths
286
+ recommendations.strengths.forEach(s => {
287
+ console.log(`Strength (${s.frequency} calls): ${s.strength}`);
288
+ });
289
+
290
+ // Show areas for improvement
291
+ recommendations.improvementAreas.forEach(area => {
292
+ console.log(`Needs work (${area.frequency} calls): ${area.area}`);
293
+ });
294
+ ```
295
+
296
+ **Note:** This method requires the user to have at least one completed call. If no calls are found, a `BadRequestException` will be thrown.
297
+
224
298
  ## Checking Simulation Status
225
299
 
226
300
  You can check the current phase/status of a simulation using the `checkSimulationStatus` method. This is useful for polling the simulation creation process until it is ready or has failed.
@@ -233,6 +307,60 @@ console.log('Current phase:', status.phase); // e.g., 'FINISHED', 'ERROR', etc.
233
307
  - **Returns:** `{ phase: CreationPhase }` — The current phase of the simulation creation process.
234
308
  - **Typical usage:** Poll this method until the phase is `FINISHED` or `ERROR` before starting a call.
235
309
 
310
+ ## Simulation Persistence
311
+
312
+ Simulations are persisted server-side and can be recovered after page reloads. Store the simulation ID client-side (e.g., localStorage) for quick recovery.
313
+
314
+ ### getSimulationDetails(simulationId: string)
315
+
316
+ Retrieves detailed information about a simulation, including its original configuration.
317
+
318
+ **Returns:** `Promise<SimulationDetailsDto>` containing:
319
+
320
+ - `simulationId`: MongoDB ID
321
+ - `phase`: Current creation phase
322
+ - `assistantId`: The assistant ID (available after creation)
323
+ - `configuration`: Original `CreateSimulationDto`
324
+ - `createdAt`, `updatedAt`: Timestamps
325
+
326
+ **Example:**
327
+
328
+ ```typescript
329
+ // Store simulation ID after creation
330
+ const simulation = await client.createSimulation(config);
331
+ localStorage.setItem('plato_simulation_id', simulation.simulationId);
332
+
333
+ // Recover simulation on page reload
334
+ const simulationId = localStorage.getItem('plato_simulation_id');
335
+ if (simulationId) {
336
+ const details = await client.getSimulationDetails(simulationId);
337
+
338
+ if (details.phase !== CreationPhase.ERROR) {
339
+ // Resume polling if still in progress
340
+ if (details.phase !== CreationPhase.FINISHED) {
341
+ startPolling(details.simulationId);
342
+ }
343
+ } else {
344
+ localStorage.removeItem('plato_simulation_id');
345
+ }
346
+ }
347
+ ```
348
+
349
+ ### getUserSimulations()
350
+
351
+ Retrieves all simulations for the authenticated user. Useful when the simulation ID is not stored locally.
352
+
353
+ **Returns:** `Promise<Array<{ simulationId: string; phase: CreationPhase }>>`
354
+
355
+ **Example:**
356
+
357
+ ```typescript
358
+ const simulations = await client.getUserSimulations();
359
+ const inProgress = simulations.find(
360
+ sim => sim.phase !== CreationPhase.FINISHED && sim.phase !== CreationPhase.ERROR
361
+ );
362
+ ```
363
+
236
364
  ## Event System
237
365
 
238
366
  The SDK provides a comprehensive event system for managing voice calls:
@@ -277,8 +405,8 @@ interface CreateSimulationDto {
277
405
  product: ProductConfig;
278
406
  presentation?: string;
279
407
  scenario: string;
280
- objectives?: string[];
281
- anticipatedObjections?: string[];
408
+ objectives?: string;
409
+ anticipatedObjections?: string;
282
410
  trainingConfiguration: TrainingConfigurationDto;
283
411
  }
284
412
  ```
@@ -298,6 +426,69 @@ interface CharacterCreateDto {
298
426
  }
299
427
  ```
300
428
 
429
+ ### SimulationDetailsDto
430
+
431
+ Detailed simulation information returned by `getSimulationDetails()`:
432
+
433
+ ```typescript
434
+ interface SimulationDetailsDto {
435
+ simulationId: string;
436
+ phase: CreationPhase;
437
+ assistantId: string;
438
+ configuration?: CreateSimulationDto;
439
+ createdAt: Date;
440
+ updatedAt: Date;
441
+ }
442
+ ```
443
+
444
+ ### CreationPhase
445
+
446
+ Enum representing the simulation creation phases:
447
+
448
+ ```typescript
449
+ enum CreationPhase {
450
+ STARTING = 'STARTING',
451
+ CORE = 'CORE',
452
+ BOUNDARIES = 'BOUNDARIES',
453
+ SPEECH_AND_THOUGHT = 'SPEECH_AND_THOUGHT',
454
+ CONVERSATION_EVOLUTION = 'CONVERSATION_EVOLUTION',
455
+ MEMORY = 'MEMORY',
456
+ FINISHED = 'FINISHED',
457
+ ERROR = 'ERROR',
458
+ }
459
+ ```
460
+
461
+ ### RecommendationsResponseDto
462
+
463
+ Response object from `getRecommendations()`:
464
+
465
+ ```typescript
466
+ interface RecommendationsResponseDto {
467
+ recommendations: RecommendationItemDto[];
468
+ strengths: PerformancePatternDto[];
469
+ improvementAreas: ImprovementAreaDto[];
470
+ summary: string;
471
+ callsAnalyzed: number;
472
+ generatedAt: Date;
473
+ }
474
+
475
+ interface RecommendationItemDto {
476
+ title: string;
477
+ description: string;
478
+ priority: 'high' | 'medium' | 'low';
479
+ }
480
+
481
+ interface PerformancePatternDto {
482
+ strength: string;
483
+ frequency: number;
484
+ }
485
+
486
+ interface ImprovementAreaDto {
487
+ area: string;
488
+ frequency: number;
489
+ }
490
+ ```
491
+
301
492
  ## Error Handling
302
493
 
303
494
  The SDK throws errors for invalid configurations and API failures:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctchealth/plato-sdk",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
6
  "@vapi-ai/web": "2.1.8",
@@ -11,5 +11,6 @@
11
11
  "typings": "./src/index.d.ts",
12
12
  "publishConfig": {
13
13
  "access": "public"
14
- }
15
- }
14
+ },
15
+ "types": "./src/index.d.ts"
16
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,14 @@
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 * from './lib/plato-sdk';
package/src/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ /**
5
+ * Copyright (c) 2025 ctcHealth. All rights reserved.
6
+ *
7
+ * This file is part of the ctcHealth Plato Platform, a proprietary software system developed by ctcHealth.
8
+ *
9
+ * This source code and all related materials are confidential and proprietary to ctcHealth.
10
+ * Unauthorized access, use, copying, modification, distribution, or disclosure is strictly prohibited
11
+ * and may result in disciplinary action and civil and/or criminal penalties.
12
+ *
13
+ * This software is intended solely for authorized use within ctcHealth and its designated partners.
14
+ *
15
+ * For internal use only.
16
+ */
17
+ tslib_1.__exportStar(require("./lib/plato-sdk"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/plato-sdk/src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;GAYG;AACH,0DAAgC"}
@@ -0,0 +1,269 @@
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 declare 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
+ export declare enum PracticeType {
21
+ Private = "Private Practice",
22
+ Hospital = "Hospital",
23
+ AcademicMedicalCenter = "Academic Medical Center",
24
+ Clinic = "Clinic"
25
+ }
26
+ export declare enum SegmentType {
27
+ Traditionalist = "The Traditionalist",
28
+ Innovator = "The Innovator",
29
+ PatientOrientedPhysician = "The Patient-Oriented Physician",
30
+ FinanciallyDrivenPrescriber = "The Financially-Driven Prescriber",
31
+ EvidencePurist = "The Evidence-Purist",
32
+ CostConsciousPrescriber = "The Cost-Conscious Prescriber"
33
+ }
34
+ export declare enum AssistantVoiceGender {
35
+ Male = "Male",
36
+ Female = "Female"
37
+ }
38
+ export declare class PersonalityAndBehaviourDto {
39
+ riskTolerance: number;
40
+ researchOrientation: number;
41
+ recognitionNeed: number;
42
+ brandLoyalty: number;
43
+ patientEmpathy: number;
44
+ }
45
+ export declare class ProfessionalProfileDto {
46
+ practiceSettings: string;
47
+ yearOfExperience: number;
48
+ specialityAndDepartment: string;
49
+ location: string;
50
+ }
51
+ export declare class ContextDto {
52
+ subSpecialityOrTherapyFocus: string;
53
+ typicalPatientMix: string;
54
+ keyClinicalDrivers: string;
55
+ }
56
+ export declare class CharacterCreateDto {
57
+ name: string;
58
+ professionalProfile: ProfessionalProfileDto;
59
+ segment: SegmentType;
60
+ personalityAndBehaviour: PersonalityAndBehaviourDto;
61
+ context: ContextDto;
62
+ assistantGender?: AssistantVoiceGender;
63
+ }
64
+ export declare class ProductConfig {
65
+ name: string;
66
+ description: string;
67
+ }
68
+ export declare class CreateSimulationDto {
69
+ persona: CharacterCreateDto;
70
+ product: ProductConfig;
71
+ presentation?: string;
72
+ scenario: string;
73
+ objectives?: string;
74
+ anticipatedObjections?: string;
75
+ }
76
+ export type RecordingsLimit = 5 | 10 | 25;
77
+ export declare class SimulationRecordingsQueryDto {
78
+ limit?: RecordingsLimit;
79
+ page?: number;
80
+ sort?: SortOrder;
81
+ }
82
+ export declare enum SortOrder {
83
+ ASC = "asc",
84
+ DESC = "desc"
85
+ }
86
+ export declare enum RecordingStatus {
87
+ STARTED = "STARTED",
88
+ PROCESSING = "PROCESSING",
89
+ FINISHED = "FINISHED",
90
+ FAILED = "FAILED"
91
+ }
92
+ export declare class SimulationRecordingsDto {
93
+ _id: string;
94
+ createdAt: Date;
95
+ recordingStatus?: RecordingStatus;
96
+ }
97
+ export interface CallCreateDto {
98
+ /**
99
+ * Call ID obtained
100
+ */
101
+ callId: string;
102
+ /**
103
+ * Call Assistant ID
104
+ */
105
+ assistantId: string;
106
+ }
107
+ export interface CallDTO {
108
+ /**
109
+ * call ID
110
+ */
111
+ _id: string;
112
+ /**
113
+ * call ID obtained
114
+ */
115
+ callId: string;
116
+ /**
117
+ * call User ID
118
+ */
119
+ platoUserId: string;
120
+ /**
121
+ * call Assistant ID
122
+ */
123
+ assistantId: string;
124
+ /**
125
+ * call summary of the conversation
126
+ */
127
+ summary: string;
128
+ /**
129
+ * call transcript of the conversation
130
+ */
131
+ transcript: string;
132
+ /**
133
+ * call feedback provided by the user
134
+ */
135
+ feedback: string;
136
+ /**
137
+ * Success Evaluation returned by model
138
+ */
139
+ successEvaluation: boolean;
140
+ /**
141
+ * call Recording URL
142
+ */
143
+ recordingUrl: string;
144
+ /**
145
+ * Status of recording processing (e.g., 'STARTED', 'PROCESSING', 'FINISHED', 'FAILED')
146
+ */
147
+ recordingStatus?: RecordingStatus;
148
+ /**
149
+ * Date and Time of the creation of the message
150
+ */
151
+ createdAt: Date;
152
+ /**
153
+ * Date and Time of the creation of the message
154
+ */
155
+ endedAt: Date;
156
+ /**
157
+ * Rating of the call given by the user
158
+ */
159
+ rating: number;
160
+ /**
161
+ * Main strenghts of the user conversation based on the analysis of the AI
162
+ */
163
+ strengths: Array<string>;
164
+ /**
165
+ * Main weak points of the user conversation based on the analysis of the AI
166
+ */
167
+ weaknesses: Array<string>;
168
+ /**
169
+ * Name of Metric for the AI feedback report
170
+ */
171
+ metric1: string;
172
+ /**
173
+ * Name of Metric for the AI feedback report
174
+ */
175
+ metric2: string;
176
+ /**
177
+ * Name of Metric for the AI feedback report
178
+ */
179
+ metric3: string;
180
+ /**
181
+ * AI feedback value for Metric 1
182
+ */
183
+ metric1Value: number;
184
+ /**
185
+ * AI feedback value for Metric 2
186
+ */
187
+ metric2Value: number;
188
+ /**
189
+ * AI feedback value for Metric 3
190
+ */
191
+ metric3Value: number;
192
+ /**
193
+ * AI feedback value for the call score
194
+ */
195
+ score?: number;
196
+ /**
197
+ * Defines if the calls will be consider for the memory feature
198
+ */
199
+ inMemory: boolean;
200
+ /**
201
+ * Duration of the call in milliseconds
202
+ */
203
+ callDurationMs?: number;
204
+ }
205
+ export declare enum CreationPhase {
206
+ STARTING = "STARTING",
207
+ CORE = "CORE",
208
+ BOUNDARIES = "BOUNDARIES",
209
+ SPEECH_AND_THOUGHT = "SPEECH_AND_THOUGHT",
210
+ CONVERSATION_EVOLUTION = "CONVERSATION_EVOLUTION",
211
+ MEMORY = "MEMORY",
212
+ FINISHED = "FINISHED",
213
+ ERROR = "ERROR"
214
+ }
215
+ /**
216
+ * Response DTO for PDF file upload.
217
+ */
218
+ export interface UploadPdfSlidesResponseDto {
219
+ /**
220
+ * The S3 object key where the PDF was saved
221
+ */
222
+ objectKey: string;
223
+ /**
224
+ * The original filename
225
+ */
226
+ filename: string;
227
+ /**
228
+ * The file size in bytes
229
+ */
230
+ size: number;
231
+ /**
232
+ * The content type of the file
233
+ */
234
+ contentType: string;
235
+ }
236
+ export interface SimulationDetailsDto {
237
+ simulationId: string;
238
+ phase: CreationPhase;
239
+ assistantId: string;
240
+ configuration?: CreateSimulationDto;
241
+ createdAt: Date;
242
+ updatedAt: Date;
243
+ }
244
+ export declare enum RecommendationPriority {
245
+ HIGH = "high",
246
+ MEDIUM = "medium",
247
+ LOW = "low"
248
+ }
249
+ export interface RecommendationItemDto {
250
+ title: string;
251
+ description: string;
252
+ priority: RecommendationPriority;
253
+ }
254
+ export interface PerformancePatternDto {
255
+ strength: string;
256
+ frequency: number;
257
+ }
258
+ export interface ImprovementAreaDto {
259
+ area: string;
260
+ frequency: number;
261
+ }
262
+ export interface RecommendationsResponseDto {
263
+ recommendations: RecommendationItemDto[];
264
+ strengths: PerformancePatternDto[];
265
+ improvementAreas: ImprovementAreaDto[];
266
+ summary: string;
267
+ callsAnalyzed: number;
268
+ generatedAt: Date;
269
+ }