@ctchealth/plato-sdk 0.0.20 → 0.0.22
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 +101 -10
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.js +4 -0
- package/src/index.js.map +1 -1
- package/src/lib/plato-intefaces.d.ts +2 -16
- package/src/lib/plato-intefaces.js +1 -14
- package/src/lib/plato-intefaces.js.map +1 -1
- package/src/lib/plato-sdk.d.ts +9 -75
- package/src/lib/plato-sdk.js +423 -275
- package/src/lib/plato-sdk.js.map +1 -1
- package/src/lib/utils.d.ts +8 -0
- package/src/lib/utils.js +33 -0
- package/src/lib/utils.js.map +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ All API requests require authentication via a client token. Pass a pre-signed JW
|
|
|
17
17
|
- Comprehensive event system for call management
|
|
18
18
|
- Type-safe API with full TypeScript support
|
|
19
19
|
- Medical training simulation configuration
|
|
20
|
-
- Simulation persistence
|
|
20
|
+
- Simulation persistence across page reloads
|
|
21
21
|
|
|
22
22
|
## Installation
|
|
23
23
|
|
|
@@ -294,22 +294,32 @@ Uploads a PDF file for slide analysis. The file will be uploaded to S3 and analy
|
|
|
294
294
|
|
|
295
295
|
- **Latin-only file names:** The PDF file name must contain only Latin characters. Non-latin characters in the file name are not supported.
|
|
296
296
|
- **Maximum 100 pages:** PDF files cannot exceed 100 pages.
|
|
297
|
-
- **No duplicate content:** Uploading a PDF with identical content
|
|
297
|
+
- **No duplicate content:** Uploading a PDF with identical content that was already uploaded by your organization throws an error. Duplicates are detected based on file content, not file name, and are scoped per organization.
|
|
298
298
|
|
|
299
299
|
**Example:**
|
|
300
300
|
|
|
301
301
|
```typescript
|
|
302
|
-
|
|
302
|
+
import { PdfAlreadyExistsError } from 'plato-sdk';
|
|
303
|
+
|
|
303
304
|
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
|
304
305
|
const file = fileInput.files?.[0];
|
|
305
306
|
|
|
306
307
|
if (file) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
308
|
+
try {
|
|
309
|
+
const pdfId = await client.uploadPdfSlides(file);
|
|
310
|
+
console.log('PDF uploaded, ID:', pdfId);
|
|
311
|
+
// Poll status until analysis completes
|
|
312
|
+
} catch (error) {
|
|
313
|
+
if (error instanceof PdfAlreadyExistsError) {
|
|
314
|
+
// Inform the user this PDF already exists in their organization
|
|
315
|
+
console.error(
|
|
316
|
+
'This PDF has already been uploaded by your organization. PDF ID:',
|
|
317
|
+
error.pdfId
|
|
318
|
+
);
|
|
319
|
+
} else {
|
|
320
|
+
console.error('Upload failed:', error.message);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
313
323
|
}
|
|
314
324
|
```
|
|
315
325
|
|
|
@@ -599,6 +609,7 @@ const inProgress = simulations.find(
|
|
|
599
609
|
);
|
|
600
610
|
```
|
|
601
611
|
|
|
612
|
+
<!--
|
|
602
613
|
## Call Recovery
|
|
603
614
|
|
|
604
615
|
The SDK automatically handles call recovery in case of page refreshes or browser closures during active calls. This ensures that call data is never lost and all calls get properly processed by the backend, even if the page is refreshed while a call is in progress.
|
|
@@ -900,6 +911,7 @@ A: The `recoverAbandonedCall()` method returns `true` when a call is recovered.
|
|
|
900
911
|
**Q: What if the backend is down during recovery?**
|
|
901
912
|
|
|
902
913
|
A: The recovery attempt is logged and the stored state is cleared to prevent infinite retries. The SDK continues working normally. Recovery failures are graceful and don't break the app.
|
|
914
|
+
-->
|
|
903
915
|
|
|
904
916
|
## Event System
|
|
905
917
|
|
|
@@ -914,6 +926,7 @@ The SDK provides a comprehensive event system for managing voice calls:
|
|
|
914
926
|
- `message`: Triggered when a message is received (contains transcript and metadata)
|
|
915
927
|
- `volume-level`: Triggered with volume level updates (number)
|
|
916
928
|
- `error`: Triggered when an error occurs
|
|
929
|
+
- `call-ended-reason`: Triggered just before `call-end` with the reason the call was terminated (e.g. silence timeout). Use this to show the user a contextual message immediately
|
|
917
930
|
- `call-details-ready`: Triggered when post-call processing completes and call details are available (includes full `CallDTO` with transcript, summary, ratings, and evaluation)
|
|
918
931
|
|
|
919
932
|
### Event Usage
|
|
@@ -939,6 +952,29 @@ call.on('call-details-ready', callDetails => {
|
|
|
939
952
|
});
|
|
940
953
|
```
|
|
941
954
|
|
|
955
|
+
## Detecting Why a Call Ended
|
|
956
|
+
|
|
957
|
+
The `call-ended-reason` event fires **just before** `call-end`, giving you the reason the call was terminated in time to update the UI before any post-call processing begins.
|
|
958
|
+
|
|
959
|
+
### Usage
|
|
960
|
+
|
|
961
|
+
```typescript
|
|
962
|
+
call.on('call-ended-reason', ({ reason, isInactivity }) => {
|
|
963
|
+
// reason — raw string from the platform, e.g. "silence-timed-out"
|
|
964
|
+
// isInactivity — true when reason contains "silence" or "inactivity"
|
|
965
|
+
});
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
### Known Reason Values
|
|
969
|
+
|
|
970
|
+
| `reason` | `isInactivity` | When it occurs |
|
|
971
|
+
| --------------------- | -------------- | ------------------------------------------------------- |
|
|
972
|
+
| `silence-timed-out` | `true` | No speech detected within the configured silence window |
|
|
973
|
+
| `customer-ended-call` | `false` | The user clicked "End Call" |
|
|
974
|
+
| `pipeline-error` | `false` | An internal platform error terminated the call |
|
|
975
|
+
|
|
976
|
+
> **Note:** The `reason` field reflects the raw value from the underlying voice platform. New values may be introduced over time. Always handle unknown reasons gracefully by falling back to a generic message.
|
|
977
|
+
|
|
942
978
|
## Automatic Post-Call Feedback
|
|
943
979
|
|
|
944
980
|
The SDK automatically fetches detailed call information after each call ends and completes post-call processing. This includes comprehensive feedback such as transcript, summary, evaluation metrics, strengths, weaknesses, and ratings.
|
|
@@ -1118,10 +1154,22 @@ call.on('call-details-ready', callDetails => {
|
|
|
1118
1154
|
|
|
1119
1155
|
### Timing Considerations
|
|
1120
1156
|
|
|
1157
|
+
- `call-ended-reason`: Fires immediately before `call-end`, with the reason the call stopped
|
|
1121
1158
|
- `call-end`: Fires immediately when the call stops
|
|
1122
1159
|
- `call-details-ready`: Fires after backend processing completes (typically 2-5 seconds after call ends)
|
|
1123
1160
|
|
|
1124
|
-
Plan your UX accordingly—show a loading/processing state
|
|
1161
|
+
Plan your UX accordingly—show a contextual end message on `call-ended-reason`, then a loading/processing state until `call-details-ready` arrives.
|
|
1162
|
+
|
|
1163
|
+
### Call Duration and Data Availability
|
|
1164
|
+
|
|
1165
|
+
The quality of data returned in `call-details-ready` depends on the duration of the call:
|
|
1166
|
+
|
|
1167
|
+
| Call duration | Behaviour |
|
|
1168
|
+
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1169
|
+
| **< ~15 seconds** | `call-details-ready` fires immediately after `call-end` with whatever the database currently holds. Fields like `transcript`, `summary`, `score`, `strengths`, and `weaknesses` will typically be empty or zero — the call was too short to generate a meaningful analysis. |
|
|
1170
|
+
| **≥ ~15 seconds** | The SDK polls the backend until Vapi's post-call analysis is ready (transcript present), then emits `call-details-ready` with the fully populated `CallDTO`. |
|
|
1171
|
+
|
|
1172
|
+
> **Note:** The ~15 second threshold accounts for the Vapi connection handshake (typically 1–5 seconds) plus a minimum amount of conversation time required for analysis to be generated. Always handle empty fields gracefully regardless of call length.
|
|
1125
1173
|
|
|
1126
1174
|
## Data Types
|
|
1127
1175
|
|
|
@@ -1429,6 +1477,49 @@ try {
|
|
|
1429
1477
|
}
|
|
1430
1478
|
```
|
|
1431
1479
|
|
|
1480
|
+
### PDF Already Exists Error
|
|
1481
|
+
|
|
1482
|
+
When a PDF with identical content has already been uploaded by your organization, `uploadPdfSlides()` throws a `PdfAlreadyExistsError`. The error exposes the `pdfId` of the existing record so you can use it directly without re-uploading.
|
|
1483
|
+
|
|
1484
|
+
```typescript
|
|
1485
|
+
import { PdfAlreadyExistsError } from 'plato-sdk';
|
|
1486
|
+
|
|
1487
|
+
try {
|
|
1488
|
+
const pdfId = await client.uploadPdfSlides(file);
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
if (error instanceof PdfAlreadyExistsError) {
|
|
1491
|
+
console.log('PDF already exists, using existing ID:', error.pdfId);
|
|
1492
|
+
} else {
|
|
1493
|
+
console.error('Upload failed:', error.message);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
### Concurrency Limit Error
|
|
1499
|
+
|
|
1500
|
+
When the platform has reached its maximum number of simultaneous active calls, `startCall()` throws a `CallConcurrencyLimitError`. This is a platform-wide limit, not user-specific. You should catch this specifically and show the user a clear message rather than a generic error.
|
|
1501
|
+
|
|
1502
|
+
```typescript
|
|
1503
|
+
import { CallConcurrencyLimitError } from 'plato-sdk';
|
|
1504
|
+
|
|
1505
|
+
const handleStartCall = async (simulationId: string) => {
|
|
1506
|
+
try {
|
|
1507
|
+
const call = await platoClient.startCall(simulationId);
|
|
1508
|
+
|
|
1509
|
+
call.on('call-start', () => setCallActive(true));
|
|
1510
|
+
call.on('call-end', () => setCallActive(false));
|
|
1511
|
+
} catch (error) {
|
|
1512
|
+
if (error instanceof CallConcurrencyLimitError) {
|
|
1513
|
+
setErrorMessage(
|
|
1514
|
+
'The platform has reached its maximum number of simultaneous calls. Please try again in a moment.'
|
|
1515
|
+
);
|
|
1516
|
+
} else {
|
|
1517
|
+
setErrorMessage('Failed to start call. Please try again.');
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
```
|
|
1522
|
+
|
|
1432
1523
|
## Support
|
|
1433
1524
|
|
|
1434
1525
|
For support and questions, please contact the development team.
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PdfAlreadyExistsError = exports.CallConcurrencyLimitError = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
/**
|
|
5
6
|
* Copyright (c) 2025 ctcHealth. All rights reserved.
|
|
@@ -15,4 +16,7 @@ const tslib_1 = require("tslib");
|
|
|
15
16
|
* For internal use only.
|
|
16
17
|
*/
|
|
17
18
|
tslib_1.__exportStar(require("./lib/plato-sdk"), exports);
|
|
19
|
+
var utils_1 = require("./lib/utils");
|
|
20
|
+
Object.defineProperty(exports, "CallConcurrencyLimitError", { enumerable: true, get: function () { return utils_1.CallConcurrencyLimitError; } });
|
|
21
|
+
Object.defineProperty(exports, "PdfAlreadyExistsError", { enumerable: true, get: function () { return utils_1.PdfAlreadyExistsError; } });
|
|
18
22
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/plato-sdk/src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/plato-sdk/src/index.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;GAYG;AACH,0DAAgC;AAChC,qCAA+E;AAAtE,kHAAA,yBAAyB,OAAA;AAAE,8GAAA,qBAAqB,OAAA"}
|
|
@@ -125,10 +125,6 @@ export interface CallDTO {
|
|
|
125
125
|
* call ID obtained
|
|
126
126
|
*/
|
|
127
127
|
callId: string;
|
|
128
|
-
/**
|
|
129
|
-
* call User ID
|
|
130
|
-
*/
|
|
131
|
-
platoUserId: string;
|
|
132
128
|
/**
|
|
133
129
|
* call Assistant ID
|
|
134
130
|
*/
|
|
@@ -245,9 +241,10 @@ export interface PresignedPost {
|
|
|
245
241
|
* Response for requesting a PDF upload.
|
|
246
242
|
*/
|
|
247
243
|
export interface RequestPdfUploadResponse {
|
|
248
|
-
presignedPost
|
|
244
|
+
presignedPost?: PresignedPost;
|
|
249
245
|
objectKey: string;
|
|
250
246
|
pdfId: string;
|
|
247
|
+
alreadyExists?: boolean;
|
|
251
248
|
}
|
|
252
249
|
/**
|
|
253
250
|
* Persona description within simulation briefing
|
|
@@ -327,17 +324,6 @@ export interface CheckPdfStatusResponse {
|
|
|
327
324
|
processedBatches: number[];
|
|
328
325
|
totalBatches?: number;
|
|
329
326
|
}
|
|
330
|
-
export declare enum PdfSlidesSortField {
|
|
331
|
-
CREATED_AT = "createdAt",
|
|
332
|
-
FILENAME = "originalFilename",
|
|
333
|
-
TOTAL_SLIDES = "totalSlides"
|
|
334
|
-
}
|
|
335
|
-
export declare class PdfSlidesAnalysisQueryDto {
|
|
336
|
-
limit?: RecordingsLimit;
|
|
337
|
-
page?: number;
|
|
338
|
-
sort?: SortOrder;
|
|
339
|
-
sortBy?: PdfSlidesSortField;
|
|
340
|
-
}
|
|
341
327
|
export interface SlideAnalysis {
|
|
342
328
|
slideNumber: number;
|
|
343
329
|
title?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PdfSlidesStatus = exports.RecommendationPriority = exports.CreationPhase = exports.SimulationRecordingsDto = exports.RecordingStatus = exports.SortOrder = exports.SimulationRecordingsQueryDto = exports.CreateSimulationDto = exports.ProductConfig = exports.CharacterCreateDto = exports.ContextDto = exports.ProfessionalProfileDto = exports.PersonalityAndBehaviourDto = exports.AvatarLanguage = exports.AssistantVoiceGender = exports.SegmentType = exports.PracticeType = exports.YearOfExperience = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright (c) 2025 ctcHealth. All rights reserved.
|
|
6
6
|
*
|
|
@@ -159,17 +159,4 @@ var PdfSlidesStatus;
|
|
|
159
159
|
PdfSlidesStatus["COMPLETED"] = "completed";
|
|
160
160
|
PdfSlidesStatus["FAILED"] = "failed";
|
|
161
161
|
})(PdfSlidesStatus || (exports.PdfSlidesStatus = PdfSlidesStatus = {}));
|
|
162
|
-
var PdfSlidesSortField;
|
|
163
|
-
(function (PdfSlidesSortField) {
|
|
164
|
-
PdfSlidesSortField["CREATED_AT"] = "createdAt";
|
|
165
|
-
PdfSlidesSortField["FILENAME"] = "originalFilename";
|
|
166
|
-
PdfSlidesSortField["TOTAL_SLIDES"] = "totalSlides";
|
|
167
|
-
})(PdfSlidesSortField || (exports.PdfSlidesSortField = PdfSlidesSortField = {}));
|
|
168
|
-
class PdfSlidesAnalysisQueryDto {
|
|
169
|
-
limit;
|
|
170
|
-
page;
|
|
171
|
-
sort;
|
|
172
|
-
sortBy;
|
|
173
|
-
}
|
|
174
|
-
exports.PdfSlidesAnalysisQueryDto = PdfSlidesAnalysisQueryDto;
|
|
175
162
|
//# sourceMappingURL=plato-intefaces.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plato-intefaces.js","sourceRoot":"","sources":["../../../../../libs/plato-sdk/src/lib/plato-intefaces.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;GAYG;AACH,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,qCAAmB,CAAA;IACnB,uCAAqB,CAAA;IACrB,yCAAuB,CAAA;IACvB,qCAAmB,CAAA;AACrB,CAAC,EALW,gBAAgB,gCAAhB,gBAAgB,QAK3B;AAED,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,4CAA4B,CAAA;IAC5B,qCAAqB,CAAA;IACrB,iEAAiD,CAAA;IACjD,iCAAiB,CAAA;AACnB,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AACD,IAAY,WAOX;AAPD,WAAY,WAAW;IACrB,oDAAqC,CAAA;IACrC,0CAA2B,CAAA;IAC3B,0EAA2D,CAAA;IAC3D,gFAAiE,CAAA;IACjE,qDAAsC,CAAA;IACtC,wEAAyD,CAAA;AAC3D,CAAC,EAPW,WAAW,2BAAX,WAAW,QAOtB;AAED,IAAY,oBAGX;AAHD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,yCAAiB,CAAA;AACnB,CAAC,EAHW,oBAAoB,oCAApB,oBAAoB,QAG/B;AAED,IAAY,cAQX;AARD,WAAY,cAAc;IACxB,gCAAc,CAAA;IACd,+BAAa,CAAA;IACb,gCAAc,CAAA;IACd,gCAAc,CAAA;IACd,+BAAa,CAAA;IACb,+BAAa,CAAA;IACb,gCAAc,CAAA;AAChB,CAAC,EARW,cAAc,8BAAd,cAAc,QAQzB;AAED,MAAa,0BAA0B;IACrC,aAAa,CAAU;IACvB,mBAAmB,CAAU;IAC7B,eAAe,CAAU;IACzB,YAAY,CAAU;IACtB,cAAc,CAAU;CACzB;AAND,gEAMC;AAED,MAAa,sBAAsB;IACjC,gBAAgB,CAAU;IAC1B,gBAAgB,CAAU;IAC1B,uBAAuB,CAAU;IACjC,QAAQ,CAAU;CACnB;AALD,wDAKC;AAED,MAAa,UAAU;IACrB,2BAA2B,CAAU;IACrC,iBAAiB,CAAU;IAC3B,kBAAkB,CAAU;CAC7B;AAJD,gCAIC;AAED,MAAa,kBAAkB;IAC7B,IAAI,CAAU;IACd,mBAAmB,CAA0B;IAC7C,OAAO,CAAe;IACtB,uBAAuB,CAA8B;IACrD,OAAO,CAAc;IACrB,eAAe,CAAwB;CACxC;AAPD,gDAOC;AAED,MAAa,aAAa;IACxB,IAAI,CAAU;IACd,WAAW,CAAU;CACtB;AAHD,sCAGC;AAED,MAAa,mBAAmB;IAC9B,OAAO,CAAsB;IAC7B,OAAO,CAAiB;IACxB,QAAQ,CAAU;IAClB,UAAU,CAAU;IACpB,qBAAqB,CAAU;IAC/B,OAAO,CAAU;IACjB,cAAc,CAAkB;IAChC,UAAU,CAAU;IACpB,UAAU,CAAW;CACtB;AAVD,kDAUC;AAID,MAAa,4BAA4B;IACvC,KAAK,CAAmB;IACxB,IAAI,CAAU;IACd,IAAI,CAAa;CAClB;AAJD,oEAIC;AAED,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,wBAAW,CAAA;IACX,0BAAa,CAAA;AACf,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAED,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,4CAAyB,CAAA;IACzB,wCAAqB,CAAA;IACrB,oCAAiB,CAAA;AACnB,CAAC,EALW,eAAe,+BAAf,eAAe,QAK1B;AAED,MAAa,uBAAuB;IAClC,GAAG,CAAU;IACb,SAAS,CAAQ;IACjB,eAAe,CAAmB;CACnC;AAJD,0DAIC;
|
|
1
|
+
{"version":3,"file":"plato-intefaces.js","sourceRoot":"","sources":["../../../../../libs/plato-sdk/src/lib/plato-intefaces.ts"],"names":[],"mappings":"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"}
|
package/src/lib/plato-sdk.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CallDTO, CreateSimulationDto, CreationPhase, SimulationRecordingsDto, SimulationRecordingsQueryDto, SimulationDetailsDto, RecommendationsResponseDto,
|
|
1
|
+
import { CallDTO, CreateSimulationDto, CreationPhase, SimulationRecordingsDto, SimulationRecordingsQueryDto, SimulationDetailsDto, RecommendationsResponseDto, PdfSlideDto, CheckPdfStatusResponse, AssistantImageDto } from './plato-intefaces';
|
|
2
2
|
export interface ApiClientConfig {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
jwtToken: string;
|
|
@@ -36,17 +36,19 @@ export interface CallEventMap {
|
|
|
36
36
|
};
|
|
37
37
|
'volume-level': number;
|
|
38
38
|
'call-details-ready': CallDTO;
|
|
39
|
+
'call-ended-reason': {
|
|
40
|
+
reason: string;
|
|
41
|
+
isInactivity: boolean;
|
|
42
|
+
};
|
|
39
43
|
}
|
|
40
44
|
export type CallEventNames = keyof CallEventMap;
|
|
41
45
|
export type CallEventListener<K extends CallEventNames> = (payload: CallEventMap[K]) => void;
|
|
42
46
|
export declare class PlatoApiClient {
|
|
43
47
|
private config;
|
|
44
|
-
private static readonly ACTIVE_CALL_STORAGE_KEY;
|
|
45
48
|
private http;
|
|
46
49
|
private eventListeners;
|
|
47
50
|
private callControllerInstance?;
|
|
48
51
|
private eventsAttached;
|
|
49
|
-
private currentCallId?;
|
|
50
52
|
private vapiEventNames;
|
|
51
53
|
eventNames: CallEventNames[];
|
|
52
54
|
constructor(config: ApiClientConfig);
|
|
@@ -79,66 +81,6 @@ export declare class PlatoApiClient {
|
|
|
79
81
|
* Internal: Emit SDK-specific events that are not part of Vapi.
|
|
80
82
|
*/
|
|
81
83
|
private emit;
|
|
82
|
-
/**
|
|
83
|
-
* Store active call state in localStorage for recovery purposes.
|
|
84
|
-
* @private
|
|
85
|
-
*/
|
|
86
|
-
private storeCallState;
|
|
87
|
-
/**
|
|
88
|
-
* Retrieve active call state from localStorage.
|
|
89
|
-
* Validates the stored data and clears it if invalid.
|
|
90
|
-
* @private
|
|
91
|
-
* @returns The stored call state or null if not found or invalid
|
|
92
|
-
*/
|
|
93
|
-
private getStoredCallState;
|
|
94
|
-
/**
|
|
95
|
-
* Clear active call state from localStorage.
|
|
96
|
-
* @private
|
|
97
|
-
*/
|
|
98
|
-
private clearCallState;
|
|
99
|
-
/**
|
|
100
|
-
* Check if a stored call is considered abandoned based on age.
|
|
101
|
-
* Calls older than 5 minutes are considered abandoned.
|
|
102
|
-
* @private
|
|
103
|
-
* @param state The call state to check
|
|
104
|
-
* @returns true if the call is abandoned, false otherwise
|
|
105
|
-
*/
|
|
106
|
-
private isCallAbandoned;
|
|
107
|
-
/**
|
|
108
|
-
* Recover and clean up any abandoned calls from previous sessions.
|
|
109
|
-
*
|
|
110
|
-
* This method should be called during application initialization,
|
|
111
|
-
* typically in ngOnInit() or useEffect(). It detects calls that were
|
|
112
|
-
* active when the page was last refreshed and notifies the backend
|
|
113
|
-
* to process them if they're older than 5 minutes.
|
|
114
|
-
*
|
|
115
|
-
* The backend endpoint is idempotent, so calling this method multiple
|
|
116
|
-
* times for the same call is safe.
|
|
117
|
-
*
|
|
118
|
-
* @returns Promise<boolean> - true if an abandoned call was recovered and processed
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* // In Angular component
|
|
122
|
-
* async ngOnInit(): Promise<void> {
|
|
123
|
-
* const recovered = await this.platoClient.recoverAbandonedCall();
|
|
124
|
-
* if (recovered) {
|
|
125
|
-
* console.log('Recovered abandoned call from previous session');
|
|
126
|
-
* }
|
|
127
|
-
* }
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* // In React component
|
|
131
|
-
* useEffect(() => {
|
|
132
|
-
* platoClient.recoverAbandonedCall()
|
|
133
|
-
* .then(recovered => {
|
|
134
|
-
* if (recovered) {
|
|
135
|
-
* console.log('Recovered abandoned call');
|
|
136
|
-
* }
|
|
137
|
-
* })
|
|
138
|
-
* .catch(console.error);
|
|
139
|
-
* }, []);
|
|
140
|
-
*/
|
|
141
|
-
recoverAbandonedCall(): Promise<boolean>;
|
|
142
84
|
createSimulation(createSimulationParams: CreateSimulationDto): Promise<{
|
|
143
85
|
simulationId: string;
|
|
144
86
|
phase: CreationPhase;
|
|
@@ -164,27 +106,19 @@ export declare class PlatoApiClient {
|
|
|
164
106
|
* Remove all listeners for all call events.
|
|
165
107
|
*/
|
|
166
108
|
private removeAllEventListeners;
|
|
109
|
+
/**
|
|
110
|
+
* Starts a call for the given simulation.
|
|
111
|
+
* Polls the backend after call-end until the call is finalized, then emits 'call-details-ready'.
|
|
112
|
+
*/
|
|
167
113
|
startCall(simulationId: string): Promise<{
|
|
168
114
|
stopCall: () => void;
|
|
169
115
|
callId: string;
|
|
170
|
-
/**
|
|
171
|
-
* Subscribe to call events for this call with strict typing.
|
|
172
|
-
* @param event Event name
|
|
173
|
-
* @param listener Listener function
|
|
174
|
-
*/
|
|
175
116
|
on: <K extends CallEventNames>(event: K, listener: CallEventListener<K>) => void;
|
|
176
|
-
/**
|
|
177
|
-
* Unsubscribe from call events for this call with strict typing.
|
|
178
|
-
* @param event Event name
|
|
179
|
-
* @param listener Listener function
|
|
180
|
-
*/
|
|
181
117
|
off: <K extends CallEventNames>(event: K, listener: CallEventListener<K>) => void;
|
|
182
118
|
}>;
|
|
183
|
-
private onCallEnded;
|
|
184
119
|
private createCall;
|
|
185
120
|
uploadPdfSlides(file: File | Blob): Promise<string>;
|
|
186
121
|
getRecommendations(): Promise<RecommendationsResponseDto>;
|
|
187
|
-
getSlidesAnalysis(queryParams: PdfSlidesAnalysisQueryDto): Promise<PdfSlidesDto[]>;
|
|
188
122
|
getSlideAnalysis(id: string): Promise<PdfSlideDto>;
|
|
189
123
|
deleteSlideAnalysis(id: string): Promise<void>;
|
|
190
124
|
checkPdfStatus(id: string): Promise<CheckPdfStatusResponse>;
|