dvgateway-sdk 1.6.0 → 1.6.2

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.
Files changed (37) hide show
  1. package/dist/client.d.ts +204 -7
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +236 -7
  4. package/dist/client.js.map +1 -1
  5. package/dist/flow/builder.d.ts +102 -0
  6. package/dist/flow/builder.d.ts.map +1 -0
  7. package/dist/flow/builder.js +341 -0
  8. package/dist/flow/builder.js.map +1 -0
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/play-audio.test.js +23 -1
  14. package/dist/play-audio.test.js.map +1 -1
  15. package/dist/streams/audio-playback.test.d.ts +8 -0
  16. package/dist/streams/audio-playback.test.d.ts.map +1 -0
  17. package/dist/streams/audio-playback.test.js +114 -0
  18. package/dist/streams/audio-playback.test.js.map +1 -0
  19. package/dist/streams/call-events.d.ts.map +1 -1
  20. package/dist/streams/call-events.js +51 -0
  21. package/dist/streams/call-events.js.map +1 -1
  22. package/dist/streams/tts-playback.test.d.ts +10 -0
  23. package/dist/streams/tts-playback.test.d.ts.map +1 -0
  24. package/dist/streams/tts-playback.test.js +103 -0
  25. package/dist/streams/tts-playback.test.js.map +1 -0
  26. package/dist/streams/tts-stream.d.ts +17 -4
  27. package/dist/streams/tts-stream.d.ts.map +1 -1
  28. package/dist/streams/tts-stream.js +34 -10
  29. package/dist/streams/tts-stream.js.map +1 -1
  30. package/dist/transport/http-client.d.ts +2 -2
  31. package/dist/transport/http-client.d.ts.map +1 -1
  32. package/dist/transport/http-client.js +4 -3
  33. package/dist/transport/http-client.js.map +1 -1
  34. package/dist/types/index.d.ts +175 -1
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/index.js.map +1 -1
  37. package/package.json +1 -1
package/dist/client.d.ts CHANGED
@@ -21,9 +21,10 @@
21
21
  */
22
22
  import { type AudioStreamHandle, type PipelineType } from './streams/audio-stream.js';
23
23
  import { PipelineBuilder } from './pipeline/builder.js';
24
+ import { VoiceFlowBuilder } from './flow/builder.js';
24
25
  import { PipelineMetrics } from './observability/metrics.js';
25
26
  import { type SimulateOptions, type SimulatedCall } from './simulator/simulator.js';
26
- import type { DVGatewayOptions, CallSession, CallEvent, ChannelStateChangeEvent, TTSCompleteEvent, TranscriptResult, StreamDir, TtsAdapter, Unsubscribe, DTMFResult, PlayAudioResult, WarmTransferResult } from './types/index.js';
27
+ import type { DVGatewayOptions, CallSession, CallEvent, ChannelStateChangeEvent, AudioPlaybackEvent, TTSCompleteEvent, TtsPlaybackEvent, TranscriptResult, StreamDir, TtsAdapter, Unsubscribe, DTMFResult, InjectTtsResult, PlayAudioResult, WarmTransferResult } from './types/index.js';
27
28
  export declare class DVGatewayClient {
28
29
  private readonly auth;
29
30
  private readonly wsPool;
@@ -131,6 +132,89 @@ export declare class DVGatewayClient {
131
132
  dir?: StreamDir;
132
133
  pipelineType?: PipelineType;
133
134
  }): AudioStreamHandle;
135
+ /**
136
+ * Attach audio streaming (ExternalMedia) to a flow-mode call mid-call.
137
+ *
138
+ * Only valid for calls that entered the gateway with the dialplan arg
139
+ * `Stasis(dvgateway, flow=true, ...)` — those calls land in a holding
140
+ * bridge with no ExternalMedia until this method is called. Idempotent —
141
+ * if audio is already attached the gateway returns the existing channel.
142
+ *
143
+ * Use `dir`:
144
+ * - `'both'` (default) — full duplex, STT + TTS
145
+ * - `'out'` — gateway → caller only (TTS playback, no STT cost)
146
+ * - `'in'` — caller → gateway only (STT only)
147
+ *
148
+ * @returns The Asterisk ExternalMedia channel ID. Returned mainly for
149
+ * observability — most callers will ignore it.
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * await gw.attachAudio(linkedId, 'out');
154
+ * await gw.say(linkedId, 'Welcome', tts);
155
+ * await gw.detachAudio(linkedId);
156
+ * ```
157
+ *
158
+ * @see {@link flow} for the high-level VoiceFlow builder that handles
159
+ * attach/detach automatically per stage.
160
+ */
161
+ attachAudio(linkedId: string, dir?: 'both' | 'in' | 'out'): Promise<string>;
162
+ /**
163
+ * Detach audio streaming from a flow-mode call. The original channel
164
+ * stays parked in its holding bridge so {@link attachAudio} can be
165
+ * called again later. Idempotent — no-op if audio is not attached.
166
+ */
167
+ detachAudio(linkedId: string): Promise<void>;
168
+ /**
169
+ * Query audio attach state for a flow-mode call.
170
+ *
171
+ * `flowMode` is `false` when the call did NOT enter with `flow=true`
172
+ * (or has already ended) — those calls have audio attached at
173
+ * StasisStart and cannot be detached.
174
+ */
175
+ getAudioStatus(linkedId: string): Promise<{
176
+ flowMode: boolean;
177
+ attached: boolean;
178
+ extMediaId: string;
179
+ bridgeId: string;
180
+ }>;
181
+ /**
182
+ * Create a fluent SDK voice flow — a stage graph that drives a call
183
+ * through IVR-like steps, attaching/detaching audio per stage.
184
+ *
185
+ * Only meaningful for calls that entered with dialplan arg
186
+ * `flow=true`. The flow runtime listens for `call:new` events and
187
+ * spawns a per-call execution that:
188
+ * 1. Enters the start stage (calls `attachAudio` if `audio !== 'none'`)
189
+ * 2. Runs the stage's `onEnter` (which can `say`, `playAudio`, `collectDtmf`)
190
+ * 3. Transitions on DTMF (`onDtmf` map) or explicit `ctx.transitionTo()`
191
+ * 4. Detaches audio between stages when modes differ
192
+ * 5. Ends on `call:ended` or when a stage calls `ctx.hangup()`
193
+ *
194
+ * @example IVR menu
195
+ * ```typescript
196
+ * gw.flow()
197
+ * .stage('greet', {
198
+ * audio: 'tts-only',
199
+ * onEnter: async (ctx) => ctx.say('1번 상담, 9번 종료', tts),
200
+ * onDtmf: { '1': 'chat', '9': 'bye' },
201
+ * })
202
+ * .stage('chat', {
203
+ * audio: 'full',
204
+ * onEnter: async (ctx) => ctx.runPipeline(myPipeline),
205
+ * })
206
+ * .stage('bye', {
207
+ * audio: 'tts-only',
208
+ * onEnter: async (ctx) => {
209
+ * await ctx.say('감사합니다', tts);
210
+ * await ctx.hangup();
211
+ * },
212
+ * })
213
+ * .startStage('greet')
214
+ * .start();
215
+ * ```
216
+ */
217
+ flow(): VoiceFlowBuilder;
134
218
  /**
135
219
  * Notify the gateway that AI processing has started (STT → LLM → TTS).
136
220
  * If comfort noise is enabled on the gateway (GW_COMFORT_NOISE_ENABLED=true),
@@ -180,17 +264,34 @@ export declare class DVGatewayClient {
180
264
  * Inject synthesized speech into an active call.
181
265
  * audioChunks should be 16kHz, 16-bit PCM (slin16) audio.
182
266
  *
267
+ * Returns an {@link InjectTtsResult} carrying the `injectId` (UUID) the
268
+ * gateway will surface on the corresponding `tts:playback` events. SDK
269
+ * 1.6.1+ generates the UUID client-side so callers can correlate events
270
+ * to *this* inject without an extra round-trip.
271
+ *
183
272
  * @example
184
273
  * ```typescript
185
- * const ttsAdapter = new ElevenLabsAdapter({ apiKey: '...' });
186
- * await gw.injectTts('abc123', ttsAdapter.synthesize('Hello!'));
274
+ * const r = await gw.injectTts(linkedId, ttsAdapter.synthesize('Hello!'));
275
+ * gw.onTtsPlayback((ev) => {
276
+ * if (ev.injectId === r.injectId && ev.phase === 'complete') {
277
+ * console.log('real RTP playback complete');
278
+ * }
279
+ * });
187
280
  * ```
281
+ *
282
+ * @param injectId - Optional caller-supplied UUID; defaults to a fresh
283
+ * one. Override only for tests / multi-process correlation.
188
284
  */
189
- injectTts(linkedId: string, audioChunks: AsyncIterable<Buffer>): Promise<void>;
285
+ injectTts(linkedId: string, audioChunks: AsyncIterable<Buffer>, injectId?: string): Promise<InjectTtsResult>;
190
286
  /**
191
287
  * Broadcast synthesized speech to all conference participants.
288
+ *
289
+ * Returns {@link InjectTtsResult} for parity with {@link injectTts}.
290
+ * Note: gateway 1.3.9.3 does not yet emit `tts:playback` for conference
291
+ * participant Players (only 1:1 calls), so the ID is forward-compat
292
+ * plumbing today.
192
293
  */
193
- broadcastTts(confId: string, audioChunks: AsyncIterable<Buffer>): Promise<void>;
294
+ broadcastTts(confId: string, audioChunks: AsyncIterable<Buffer>, injectId?: string): Promise<InjectTtsResult>;
194
295
  /**
195
296
  * Convenience: synthesize text and inject it directly.
196
297
  * Requires a TtsAdapter instance.
@@ -210,7 +311,7 @@ export declare class DVGatewayClient {
210
311
  * await gw.say(linkedId, '안녕하세요', tts); // cache hit — no API call
211
312
  * ```
212
313
  */
213
- say(linkedId: string, text: string, tts: TtsAdapter): Promise<void>;
314
+ say(linkedId: string, text: string, tts: TtsAdapter): Promise<InjectTtsResult>;
214
315
  /**
215
316
  * Broadcast synthesized speech to a conference.
216
317
  * Pass a CachedTtsAdapter for zero-cost repeated broadcasts.
@@ -220,7 +321,7 @@ export declare class DVGatewayClient {
220
321
  * await gw.broadcastSay(confId, '회의를 시작합니다.', cachedTts);
221
322
  * ```
222
323
  */
223
- broadcastSay(confId: string, text: string, tts: TtsAdapter): Promise<void>;
324
+ broadcastSay(confId: string, text: string, tts: TtsAdapter): Promise<InjectTtsResult>;
224
325
  /**
225
326
  * Mute the gateway's STT audio pipeline for a call.
226
327
  *
@@ -637,6 +738,102 @@ export declare class DVGatewayClient {
637
738
  * @since SDK 1.5.3
638
739
  */
639
740
  onChannelState(handler: (event: ChannelStateChangeEvent) => void | Promise<void>): Unsubscribe;
741
+ /**
742
+ * Subscribe to `audio:playback` events — the canonical signal for
743
+ * {@link playAudio} lifecycle (start / complete / canceled / failed).
744
+ *
745
+ * **Primary use case — DTMF prompt audio with accurate timeout extension:**
746
+ * application code that plays an instructional prompt and then waits for
747
+ * DTMF input previously had to estimate prompt length with a hard-coded
748
+ * fallback (e.g. `baseTimeoutMs + 8000`). With this event the application
749
+ * can extend its timeout by the *actual* playback duration, dropping both
750
+ * unnecessary slack and the risk of the timer firing before the prompt
751
+ * finishes.
752
+ *
753
+ * @example
754
+ * ```typescript
755
+ * const result = await gw.playAudio({
756
+ * linkedId,
757
+ * url: promptUrl,
758
+ * waitForCompletion: false,
759
+ * });
760
+ * const playbackId = result.playbackId;
761
+ *
762
+ * let actualMs = 0;
763
+ * const audioDone = new Promise<void>((resolve) => {
764
+ * const unsub = gw.onAudioPlayback((ev) => {
765
+ * if (ev.playbackId !== playbackId) return;
766
+ * if (ev.phase === 'complete' || ev.phase === 'canceled' || ev.phase === 'failed') {
767
+ * actualMs = ev.durationMs ?? 0;
768
+ * unsub();
769
+ * resolve();
770
+ * }
771
+ * });
772
+ * });
773
+ *
774
+ * try {
775
+ * await Promise.race([audioDone, sleep(30_000)]);
776
+ * const effectiveTimeout = baseTimeoutMs + actualMs + 500;
777
+ * } catch {
778
+ * // fallback to conservative estimate
779
+ * }
780
+ * ```
781
+ *
782
+ * @see AudioPlaybackEvent for phase contract, `errorReason` vocabulary,
783
+ * and full payload details.
784
+ *
785
+ * @since SDK 1.6.0 (gateway v1.3.9.2+ required)
786
+ */
787
+ onAudioPlayback(handler: (event: AudioPlaybackEvent) => void | Promise<void>): Unsubscribe;
788
+ /**
789
+ * Subscribe to `tts:playback` events — the canonical signal for
790
+ * {@link injectTts} lifecycle (start / complete / canceled / failed).
791
+ *
792
+ * Mirrors {@link onAudioPlayback} for the streaming-PCM injection path.
793
+ * Strictly more informative than the legacy {@link onTtsComplete}:
794
+ *
795
+ * - `onTtsComplete` fires for *every* terminal phase but exposes only
796
+ * `linkedId` — no way to distinguish complete from canceled
797
+ * (e.g. preempted by a new `injectTts`) or failed (e.g. `channel_lost`).
798
+ * - `onTtsPlayback` carries `injectId` (correlation across sequential
799
+ * injects in the same call), `phase` (4-way), `durationMs`
800
+ * (deterministic — gateway ticker is exactly 20ms paced), and
801
+ * `errorReason` (cancel cause / error class).
802
+ *
803
+ * @example
804
+ * ```typescript
805
+ * // Chain TTS prompts and wait for the *real* end of each.
806
+ * const r1 = await gw.injectTts(linkedId, greetingAudio());
807
+ * const done = new Promise<void>((resolve) => {
808
+ * const unsub = gw.onTtsPlayback((ev) => {
809
+ * if (ev.injectId !== r1.injectId) return;
810
+ * if (ev.phase === 'complete' || ev.phase === 'canceled' || ev.phase === 'failed') {
811
+ * unsub();
812
+ * resolve();
813
+ * }
814
+ * });
815
+ * });
816
+ * await done;
817
+ * const r2 = await gw.injectTts(linkedId, menuAudio()); // safe to start now
818
+ * ```
819
+ *
820
+ * **Pre-1.6.1 fallback** for SDK consumers — older SDKs / older gateways
821
+ * won't see `tts:playback`. Use a `hasattr`-style feature check if
822
+ * supporting both:
823
+ * ```typescript
824
+ * if ('onTtsPlayback' in gw) {
825
+ * gw.onTtsPlayback(handler);
826
+ * } else {
827
+ * gw.onTtsComplete((ev) => handler({ ...ev, phase: 'complete' } as any));
828
+ * }
829
+ * ```
830
+ *
831
+ * @see TtsPlaybackEvent for phase contract, `errorReason` vocabulary,
832
+ * and full payload details.
833
+ *
834
+ * @since SDK 1.6.1 (gateway v1.3.9.3+ required)
835
+ */
836
+ onTtsPlayback(handler: (event: TtsPlaybackEvent) => void | Promise<void>): Unsubscribe;
640
837
  /** List all currently active call sessions */
641
838
  listSessions(): Promise<CallSession[]>;
642
839
  /** List active call sessions filtered by tenant ID */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,EAAqB,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAIzG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,SAAS,EAET,uBAAuB,EACvB,gBAAgB,EAEhB,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,WAAW,EAEX,UAAU,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;gBAElD,IAAI,EAAE,gBAAgB;IAsBlC;;;;;;;;;;;;OAYG;IACH,QAAQ,IAAI,eAAe;IAW3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACG,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC;IAM7D;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;QAAE,GAAG,CAAC,EAAE,SAAS,CAAC;QAAC,YAAY,CAAC,EAAE,YAAY,CAAA;KAAO,GAC1D,iBAAiB;IAMpB;;;;;;;;;;OAUG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD;;;OAGG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;;;OASG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpF;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrF;;;;;;;;;;;;;;;;;;OAkBG;IACG,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzE;;;;;;;;OAQG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhF;;;;;;;;;;;OAWG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE;;;;;;OAMG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,WAAW,CAAC,OAAO,EAAE;QACzB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,GAAG,OAAO,CAAC,UAAU,CAAC;IAmLvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACG,SAAS,CAAC,OAAO,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,GAAG,OAAO,CAAC,eAAe,CAAC;IAwC5B;;;;;;OAMG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C;;;OAGG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAStF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,YAAY,CAAC,OAAO,EAAE;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA4C/B,kFAAkF;IAC5E,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAMtC,uDAAuD;IACjD,WAAW,CAAC,MAAM,EAAE;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQpB,gDAAgD;IAC1C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM3E,8CAA8C;IACxC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE;QACjF,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMvC,iDAAiD;IAC3C,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQlH,6CAA6C;IACvC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtD,wEAAwE;IAClE,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE;QAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,OAAO,CAAC,OAAO,CAAC;IAOpB;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,QAAQ,CAAC,uBAAuB,cAAc;IAErD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE;QAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMvC;;;;OAIG;IACG,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/D;;;;;;;;;;;;;;;;OAgBG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMvC,yBAAyB;IACnB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAKvC,4DAA4D;IACtD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxD,2BAA2B;IACrB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,wBAAwB;IAClB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnE,wBAAwB;IAClB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD,+BAA+B;IACzB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjD,qBAAqB;IACf,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjD,6BAA6B;IACvB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD,sBAAsB;IAChB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD,gCAAgC;IAC1B,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW;IAI7E,8CAA8C;IAC9C,EAAE,CAAC,CAAC,SAAS,SAAS,EACpB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1C,WAAW;IAId;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW;IAItF;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,cAAc,CACZ,OAAO,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAChE,WAAW;IAMd,8CAA8C;IACxC,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAI5C,sDAAsD;IAChD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIpE,qEAAqE;IAC/D,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC;IAMhB;;;OAGG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/E;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,KAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAItF;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC;IAMlF;;;OAGG;IACH,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;CAmBtB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -28,6 +28,7 @@ import { TtsInjector } from './streams/tts-stream.js';
28
28
  import { SessionManager } from './session/manager.js';
29
29
  import { MinutesManager } from './minutes/manager.js';
30
30
  import { PipelineBuilder } from './pipeline/builder.js';
31
+ import { VoiceFlowBuilder } from './flow/builder.js';
31
32
  import { PipelineMetrics } from './observability/metrics.js';
32
33
  import { createLogger } from './observability/logger.js';
33
34
  import { createSimulatedCall, } from './simulator/simulator.js';
@@ -156,6 +157,106 @@ export class DVGatewayClient {
156
157
  streamAudio(linkedId, opts = {}) {
157
158
  return createAudioStream(this.wsPool, linkedId, this.logger, opts);
158
159
  }
160
+ // ─── Voice-Flow On-Demand Audio (gateway flow=true mode) ──────────────
161
+ // @since SDK 1.6.2 (gateway v1.3.9.4+ required)
162
+ /**
163
+ * Attach audio streaming (ExternalMedia) to a flow-mode call mid-call.
164
+ *
165
+ * Only valid for calls that entered the gateway with the dialplan arg
166
+ * `Stasis(dvgateway, flow=true, ...)` — those calls land in a holding
167
+ * bridge with no ExternalMedia until this method is called. Idempotent —
168
+ * if audio is already attached the gateway returns the existing channel.
169
+ *
170
+ * Use `dir`:
171
+ * - `'both'` (default) — full duplex, STT + TTS
172
+ * - `'out'` — gateway → caller only (TTS playback, no STT cost)
173
+ * - `'in'` — caller → gateway only (STT only)
174
+ *
175
+ * @returns The Asterisk ExternalMedia channel ID. Returned mainly for
176
+ * observability — most callers will ignore it.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * await gw.attachAudio(linkedId, 'out');
181
+ * await gw.say(linkedId, 'Welcome', tts);
182
+ * await gw.detachAudio(linkedId);
183
+ * ```
184
+ *
185
+ * @see {@link flow} for the high-level VoiceFlow builder that handles
186
+ * attach/detach automatically per stage.
187
+ */
188
+ async attachAudio(linkedId, dir = 'both') {
189
+ const res = await this.http.post(`/api/v1/audio/${encodeURIComponent(linkedId)}/attach`, { dir });
190
+ const data = (res.data ?? {});
191
+ const extMediaId = typeof data['extMediaId'] === 'string' ? data['extMediaId'] : '';
192
+ this.logger.debug({ linkedId, dir, extMediaId }, 'Audio attached');
193
+ return extMediaId;
194
+ }
195
+ /**
196
+ * Detach audio streaming from a flow-mode call. The original channel
197
+ * stays parked in its holding bridge so {@link attachAudio} can be
198
+ * called again later. Idempotent — no-op if audio is not attached.
199
+ */
200
+ async detachAudio(linkedId) {
201
+ await this.http.delete(`/api/v1/audio/${encodeURIComponent(linkedId)}/detach`);
202
+ this.logger.debug({ linkedId }, 'Audio detached');
203
+ }
204
+ /**
205
+ * Query audio attach state for a flow-mode call.
206
+ *
207
+ * `flowMode` is `false` when the call did NOT enter with `flow=true`
208
+ * (or has already ended) — those calls have audio attached at
209
+ * StasisStart and cannot be detached.
210
+ */
211
+ async getAudioStatus(linkedId) {
212
+ const res = await this.http.get(`/api/v1/audio/${encodeURIComponent(linkedId)}/status`);
213
+ const data = (res.data ?? {});
214
+ return {
215
+ flowMode: Boolean(data['flowMode']),
216
+ attached: Boolean(data['attached']),
217
+ extMediaId: typeof data['extMediaId'] === 'string' ? data['extMediaId'] : '',
218
+ bridgeId: typeof data['bridgeId'] === 'string' ? data['bridgeId'] : '',
219
+ };
220
+ }
221
+ /**
222
+ * Create a fluent SDK voice flow — a stage graph that drives a call
223
+ * through IVR-like steps, attaching/detaching audio per stage.
224
+ *
225
+ * Only meaningful for calls that entered with dialplan arg
226
+ * `flow=true`. The flow runtime listens for `call:new` events and
227
+ * spawns a per-call execution that:
228
+ * 1. Enters the start stage (calls `attachAudio` if `audio !== 'none'`)
229
+ * 2. Runs the stage's `onEnter` (which can `say`, `playAudio`, `collectDtmf`)
230
+ * 3. Transitions on DTMF (`onDtmf` map) or explicit `ctx.transitionTo()`
231
+ * 4. Detaches audio between stages when modes differ
232
+ * 5. Ends on `call:ended` or when a stage calls `ctx.hangup()`
233
+ *
234
+ * @example IVR menu
235
+ * ```typescript
236
+ * gw.flow()
237
+ * .stage('greet', {
238
+ * audio: 'tts-only',
239
+ * onEnter: async (ctx) => ctx.say('1번 상담, 9번 종료', tts),
240
+ * onDtmf: { '1': 'chat', '9': 'bye' },
241
+ * })
242
+ * .stage('chat', {
243
+ * audio: 'full',
244
+ * onEnter: async (ctx) => ctx.runPipeline(myPipeline),
245
+ * })
246
+ * .stage('bye', {
247
+ * audio: 'tts-only',
248
+ * onEnter: async (ctx) => {
249
+ * await ctx.say('감사합니다', tts);
250
+ * await ctx.hangup();
251
+ * },
252
+ * })
253
+ * .startStage('greet')
254
+ * .start();
255
+ * ```
256
+ */
257
+ flow() {
258
+ return new VoiceFlowBuilder(this, this.logger);
259
+ }
159
260
  // ─── Comfort Noise / Thinking Signals ─────────────────────────────────
160
261
  /**
161
262
  * Notify the gateway that AI processing has started (STT → LLM → TTS).
@@ -219,20 +320,37 @@ export class DVGatewayClient {
219
320
  * Inject synthesized speech into an active call.
220
321
  * audioChunks should be 16kHz, 16-bit PCM (slin16) audio.
221
322
  *
323
+ * Returns an {@link InjectTtsResult} carrying the `injectId` (UUID) the
324
+ * gateway will surface on the corresponding `tts:playback` events. SDK
325
+ * 1.6.1+ generates the UUID client-side so callers can correlate events
326
+ * to *this* inject without an extra round-trip.
327
+ *
222
328
  * @example
223
329
  * ```typescript
224
- * const ttsAdapter = new ElevenLabsAdapter({ apiKey: '...' });
225
- * await gw.injectTts('abc123', ttsAdapter.synthesize('Hello!'));
330
+ * const r = await gw.injectTts(linkedId, ttsAdapter.synthesize('Hello!'));
331
+ * gw.onTtsPlayback((ev) => {
332
+ * if (ev.injectId === r.injectId && ev.phase === 'complete') {
333
+ * console.log('real RTP playback complete');
334
+ * }
335
+ * });
226
336
  * ```
337
+ *
338
+ * @param injectId - Optional caller-supplied UUID; defaults to a fresh
339
+ * one. Override only for tests / multi-process correlation.
227
340
  */
228
- async injectTts(linkedId, audioChunks) {
229
- return this.ttsInjector.injectStreaming(linkedId, audioChunks);
341
+ async injectTts(linkedId, audioChunks, injectId) {
342
+ return this.ttsInjector.injectStreaming(linkedId, audioChunks, injectId);
230
343
  }
231
344
  /**
232
345
  * Broadcast synthesized speech to all conference participants.
346
+ *
347
+ * Returns {@link InjectTtsResult} for parity with {@link injectTts}.
348
+ * Note: gateway 1.3.9.3 does not yet emit `tts:playback` for conference
349
+ * participant Players (only 1:1 calls), so the ID is forward-compat
350
+ * plumbing today.
233
351
  */
234
- async broadcastTts(confId, audioChunks) {
235
- return this.ttsInjector.broadcastToConference(confId, audioChunks);
352
+ async broadcastTts(confId, audioChunks, injectId) {
353
+ return this.ttsInjector.broadcastToConference(confId, audioChunks, injectId);
236
354
  }
237
355
  /**
238
356
  * Convenience: synthesize text and inject it directly.
@@ -557,9 +675,19 @@ export class DVGatewayClient {
557
675
  };
558
676
  const res = await this.http.post(`/api/v1/play/${encodeURIComponent(linkedId)}`, body);
559
677
  const data = (res.data ?? {});
678
+ // playbackId is surfaced on both 202 (async start) and 200 (sync result).
679
+ // Empty string when the gateway is older than 1.3.9.2 — older code
680
+ // treats it as "no correlation handle available".
681
+ const playbackIdRaw = data['playbackId'];
682
+ const playbackId = typeof playbackIdRaw === 'string' ? playbackIdRaw : '';
560
683
  if (!waitForCompletion) {
561
684
  // 202 — gateway accepted the request; playback proceeds async.
562
- return { completed: false, interruptedByDtmf: null, durationMs: 0 };
685
+ return {
686
+ completed: false,
687
+ interruptedByDtmf: null,
688
+ durationMs: 0,
689
+ playbackId,
690
+ };
563
691
  }
564
692
  const rawDtmf = data['interruptedByDtmf'];
565
693
  const interruptedByDtmf = typeof rawDtmf === 'string' && rawDtmf !== '' ? rawDtmf : null;
@@ -569,6 +697,7 @@ export class DVGatewayClient {
569
697
  completed: Boolean(data['completed']),
570
698
  interruptedByDtmf,
571
699
  durationMs,
700
+ playbackId,
572
701
  };
573
702
  }
574
703
  /**
@@ -973,6 +1102,106 @@ export class DVGatewayClient {
973
1102
  onChannelState(handler) {
974
1103
  return this.callEvents.onType('channel:state', handler);
975
1104
  }
1105
+ /**
1106
+ * Subscribe to `audio:playback` events — the canonical signal for
1107
+ * {@link playAudio} lifecycle (start / complete / canceled / failed).
1108
+ *
1109
+ * **Primary use case — DTMF prompt audio with accurate timeout extension:**
1110
+ * application code that plays an instructional prompt and then waits for
1111
+ * DTMF input previously had to estimate prompt length with a hard-coded
1112
+ * fallback (e.g. `baseTimeoutMs + 8000`). With this event the application
1113
+ * can extend its timeout by the *actual* playback duration, dropping both
1114
+ * unnecessary slack and the risk of the timer firing before the prompt
1115
+ * finishes.
1116
+ *
1117
+ * @example
1118
+ * ```typescript
1119
+ * const result = await gw.playAudio({
1120
+ * linkedId,
1121
+ * url: promptUrl,
1122
+ * waitForCompletion: false,
1123
+ * });
1124
+ * const playbackId = result.playbackId;
1125
+ *
1126
+ * let actualMs = 0;
1127
+ * const audioDone = new Promise<void>((resolve) => {
1128
+ * const unsub = gw.onAudioPlayback((ev) => {
1129
+ * if (ev.playbackId !== playbackId) return;
1130
+ * if (ev.phase === 'complete' || ev.phase === 'canceled' || ev.phase === 'failed') {
1131
+ * actualMs = ev.durationMs ?? 0;
1132
+ * unsub();
1133
+ * resolve();
1134
+ * }
1135
+ * });
1136
+ * });
1137
+ *
1138
+ * try {
1139
+ * await Promise.race([audioDone, sleep(30_000)]);
1140
+ * const effectiveTimeout = baseTimeoutMs + actualMs + 500;
1141
+ * } catch {
1142
+ * // fallback to conservative estimate
1143
+ * }
1144
+ * ```
1145
+ *
1146
+ * @see AudioPlaybackEvent for phase contract, `errorReason` vocabulary,
1147
+ * and full payload details.
1148
+ *
1149
+ * @since SDK 1.6.0 (gateway v1.3.9.2+ required)
1150
+ */
1151
+ onAudioPlayback(handler) {
1152
+ return this.callEvents.onType('audio:playback', handler);
1153
+ }
1154
+ /**
1155
+ * Subscribe to `tts:playback` events — the canonical signal for
1156
+ * {@link injectTts} lifecycle (start / complete / canceled / failed).
1157
+ *
1158
+ * Mirrors {@link onAudioPlayback} for the streaming-PCM injection path.
1159
+ * Strictly more informative than the legacy {@link onTtsComplete}:
1160
+ *
1161
+ * - `onTtsComplete` fires for *every* terminal phase but exposes only
1162
+ * `linkedId` — no way to distinguish complete from canceled
1163
+ * (e.g. preempted by a new `injectTts`) or failed (e.g. `channel_lost`).
1164
+ * - `onTtsPlayback` carries `injectId` (correlation across sequential
1165
+ * injects in the same call), `phase` (4-way), `durationMs`
1166
+ * (deterministic — gateway ticker is exactly 20ms paced), and
1167
+ * `errorReason` (cancel cause / error class).
1168
+ *
1169
+ * @example
1170
+ * ```typescript
1171
+ * // Chain TTS prompts and wait for the *real* end of each.
1172
+ * const r1 = await gw.injectTts(linkedId, greetingAudio());
1173
+ * const done = new Promise<void>((resolve) => {
1174
+ * const unsub = gw.onTtsPlayback((ev) => {
1175
+ * if (ev.injectId !== r1.injectId) return;
1176
+ * if (ev.phase === 'complete' || ev.phase === 'canceled' || ev.phase === 'failed') {
1177
+ * unsub();
1178
+ * resolve();
1179
+ * }
1180
+ * });
1181
+ * });
1182
+ * await done;
1183
+ * const r2 = await gw.injectTts(linkedId, menuAudio()); // safe to start now
1184
+ * ```
1185
+ *
1186
+ * **Pre-1.6.1 fallback** for SDK consumers — older SDKs / older gateways
1187
+ * won't see `tts:playback`. Use a `hasattr`-style feature check if
1188
+ * supporting both:
1189
+ * ```typescript
1190
+ * if ('onTtsPlayback' in gw) {
1191
+ * gw.onTtsPlayback(handler);
1192
+ * } else {
1193
+ * gw.onTtsComplete((ev) => handler({ ...ev, phase: 'complete' } as any));
1194
+ * }
1195
+ * ```
1196
+ *
1197
+ * @see TtsPlaybackEvent for phase contract, `errorReason` vocabulary,
1198
+ * and full payload details.
1199
+ *
1200
+ * @since SDK 1.6.1 (gateway v1.3.9.3+ required)
1201
+ */
1202
+ onTtsPlayback(handler) {
1203
+ return this.callEvents.onType('tts:playback', handler);
1204
+ }
976
1205
  // ─── Session Management ─────────────────────────────────────────────────
977
1206
  /** List all currently active call sessions */
978
1207
  async listSessions() {