@voctiv/agent-sdk 0.2.4 → 0.2.6
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 +79 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ export default defineScript(async ({ channel, logger, context }) => {
|
|
|
79
79
|
- `channel` is the media channel for SIP, WS, ASR, TTS, audio playback, LLM, and structured data messages.
|
|
80
80
|
- `logger` writes structured script logs and can stream logs to a debug endpoint.
|
|
81
81
|
- `context` contains dialog identity, caller/called numbers, language, flags, params, entry point, persisted env, and runtime budget.
|
|
82
|
-
- `platform` exposes
|
|
82
|
+
- `platform` exposes platform operations: NLU, dialog state, outbound call scheduling, messaging, and phrase records.
|
|
83
83
|
|
|
84
84
|
`MediaChannel` is the main real-time API:
|
|
85
85
|
|
|
@@ -103,6 +103,28 @@ The important states are:
|
|
|
103
103
|
- `active`: final 200 OK has been received or sent.
|
|
104
104
|
- `terminated`: the call ended and no more audio is possible.
|
|
105
105
|
|
|
106
|
+
### How Pre-Answer Works
|
|
107
|
+
|
|
108
|
+
Pre-answer means the SIP media path is open before the call is finally answered with `200 OK`. In this state the caller can already hear TTS, the script can already receive audio for ASR, and DTMF can be exchanged.
|
|
109
|
+
|
|
110
|
+
Use pre-answer when you need to do something before committing the call to the final answer state:
|
|
111
|
+
|
|
112
|
+
- play an informational greeting or disclaimer;
|
|
113
|
+
- collect a short value with ASR, such as account number or menu choice;
|
|
114
|
+
- detect and navigate an IVR that speaks before answering;
|
|
115
|
+
- delay `answer()` until the script is ready to transfer, bridge, or continue.
|
|
116
|
+
|
|
117
|
+
For inbound calls, the script controls this explicitly:
|
|
118
|
+
|
|
119
|
+
1. Call `channel.sip.sendProgress()` to send `183 Session Progress` with SDP.
|
|
120
|
+
2. Wait for `channel.sip.waitForEarly()` if your next logic step needs media to be ready.
|
|
121
|
+
3. Use `channel.audio.say()`, `channel.audio.play()`, `channel.createAsr()`, or `channel.sip.sendDtmf()` normally.
|
|
122
|
+
4. Call `channel.sip.answer()` when you want to send the final `200 OK`.
|
|
123
|
+
|
|
124
|
+
For outbound calls, pre-answer is controlled by the remote side. If the remote endpoint sends `183 Session Progress` with SDP, ScriptEngine moves the call to `early`. If it answers directly, `waitForEarly()` resolves when the call becomes `active`.
|
|
125
|
+
|
|
126
|
+
`early` is a media-ready state, not a final answer state. `answer()` is still the explicit transition that sends final `200 OK` for inbound calls. External billing behavior depends on the carrier.
|
|
127
|
+
|
|
106
128
|
### Outbound Pre-Answer
|
|
107
129
|
|
|
108
130
|
For outbound calls, early media starts when the remote side sends a provisional response with SDP, usually `183 Session Progress`. This is useful for IVRs that speak before answering.
|
|
@@ -349,7 +371,7 @@ await channel.audio.say(
|
|
|
349
371
|
|
|
350
372
|
## Platform API
|
|
351
373
|
|
|
352
|
-
`platform` exposes Voctiv
|
|
374
|
+
`platform` exposes Voctiv platform operations.
|
|
353
375
|
|
|
354
376
|
`platform.nlu.extract(utterance, options?)` calls NLU v3 `/infer`. The runtime sends `phrase`, `context`, and `agent_id`. If `options.context` is omitted, current dialog params are serialized and used as NLU context.
|
|
355
377
|
|
|
@@ -361,7 +383,7 @@ const result = await platform.nlu.extract('I want to reschedule', {
|
|
|
361
383
|
});
|
|
362
384
|
```
|
|
363
385
|
|
|
364
|
-
|
|
386
|
+
Platform APIs require `context.legacyV3Compat === true`. This includes NLU, outbound calls, dialog writes, messaging sends, and phrase records.
|
|
365
387
|
|
|
366
388
|
### Dialog State
|
|
367
389
|
|
|
@@ -372,19 +394,68 @@ platform.dialog.result = 'done';
|
|
|
372
394
|
|
|
373
395
|
Setters update the local value immediately and ask the platform DB to persist asynchronously. They are not awaitable and should not be used as transactional writes.
|
|
374
396
|
|
|
375
|
-
###
|
|
397
|
+
### Platform-Scheduled Calls
|
|
398
|
+
|
|
399
|
+
Use `platform.call(msisdn, options?)` when the script needs to ask the platform to place an outbound SIP call. This is different from `channel.sip.makeCall()`: `makeCall()` creates a B-leg immediately inside the current live SIP session, while `platform.call()` schedules a separate platform-managed call that may happen now or later.
|
|
400
|
+
|
|
401
|
+
The destination number should be E.164 formatted.
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
await platform.call('+12025551234');
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
By default, the platform schedules the call for immediate processing. Use `date` to schedule it for the future:
|
|
376
408
|
|
|
377
409
|
```ts
|
|
378
410
|
await platform.call('+12025551234', {
|
|
379
|
-
date: new Date(Date.now() + 60_000),
|
|
411
|
+
date: new Date(Date.now() + 15 * 60_000),
|
|
380
412
|
entryPoint: 'on_callback',
|
|
381
|
-
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`entryPoint` is passed to the script when the scheduled call starts. Use it to route the callback into a specific branch:
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
export default defineScript(async ({ context, channel }) => {
|
|
420
|
+
if (context.entryPoint === 'on_callback') {
|
|
421
|
+
channel.sip.answer();
|
|
422
|
+
await channel.audio.say('Hello, this is your scheduled callback.');
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
await channel.audio.say('I will call you back in fifteen minutes.');
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Use `dateEnd` to define the latest time when the call is still useful. If the platform cannot place the call before that deadline, it can skip the attempt.
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
await platform.call('+12025551234', {
|
|
434
|
+
date: new Date('2026-04-29T10:00:00Z'),
|
|
435
|
+
dateEnd: new Date('2026-04-29T10:30:00Z'),
|
|
436
|
+
entryPoint: 'on_reminder',
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Retries are controlled with `recallCount` and `recallDelay`:
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
await platform.call('+12025551234', {
|
|
444
|
+
entryPoint: 'on_follow_up',
|
|
445
|
+
recallCount: 3,
|
|
382
446
|
recallDelay: 300,
|
|
383
|
-
priority: 10,
|
|
384
447
|
});
|
|
385
448
|
```
|
|
386
449
|
|
|
387
|
-
This
|
|
450
|
+
This means the platform may retry up to three times, waiting about five minutes between attempts.
|
|
451
|
+
|
|
452
|
+
Other scheduling options:
|
|
453
|
+
|
|
454
|
+
- `priority`: higher-priority calls can be processed earlier by the dialer.
|
|
455
|
+
- `timezone`: timezone offset used by the platform when interpreting scheduled dates.
|
|
456
|
+
- `onSuccessCall`: entry point to use after a successful call.
|
|
457
|
+
- `onFailedCall`: entry point to use after failed attempts.
|
|
458
|
+
- `protoAdditional`: extra protocol-level parameters, such as SIP headers expected by your telephony setup.
|
|
388
459
|
|
|
389
460
|
### Messaging
|
|
390
461
|
|
package/package.json
CHANGED