@voctiv/agent-sdk 0.2.16 → 0.3.1

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
@@ -81,6 +81,7 @@ The [`examples/`](./examples/) folder contains copy-paste-ready scripts:
81
81
  | [schedule-call-with-defaults.ts](./examples/schedule-call-with-defaults.ts) | `platform.call()` without explicit recall — CMS defaults from `context` |
82
82
  | [after-call-continuation.ts](./examples/after-call-continuation.ts) | `onSuccessCall` / `onFailedCall` vs recall (mutually exclusive) |
83
83
  | [read-recall-from-params.ts](./examples/read-recall-from-params.ts) | `parseRecallDelaySeconds()` / `parseRecallCount()` on legacy params |
84
+ | [custom-media-providers.ts](./examples/custom-media-providers.ts) | `defineMediaProviders` + custom ASR/TTS via `createAsr` / `createTts` |
84
85
 
85
86
  ### Quick recall example
86
87
 
@@ -116,6 +117,8 @@ const maxAttempts = parseRecallCount(context.dialogParams?.recall_count);
116
117
 
117
118
  `defineScript(fn)` marks the default export as the script entry point. It returns the same function and exists to give TypeScript the correct `ScriptContext` shape.
118
119
 
120
+ `defineMediaProviders(def)` marks a named `mediaProviders` export for custom ASR/TTS factories (trusted packages only). See [Custom ASR / TTS Providers](#custom-asr--tts-providers).
121
+
119
122
  **Three different “context” names:**
120
123
 
121
124
  | Name | Meaning |
@@ -136,7 +139,8 @@ const maxAttempts = parseRecallCount(context.dialogParams?.recall_count);
136
139
  - `channel.type` is `"sip"` for telephony and `"ws"` for WebSocket/script-manager sessions. Headless sessions currently expose a synthetic `"ws"` channel; check `context.headless` to detect them.
137
140
  - `channel.params` is the merged runtime parameter map. Treat unknown keys as host-specific.
138
141
  - `channel.createAsr()` creates an ASR handle.
139
- - `channel.audio` controls TTS, raw playback, pre-synthesis, and mixer queues.
142
+ - `channel.createTts()` returns a TTS handle (`tts.say` / `tts.say$` / `tts.presay`) with a reused SSL / WebSocket connection.
143
+ - `channel.audio` controls channel-level TTS, raw playback, pre-synthesis, and mixer queues.
140
144
  - `channel.sip` controls SIP state, pre-answer media, DTMF, hold/mute/hangup, outbound calls, and bridging.
141
145
  - `channel.llm` talks to the Omni LLM backend.
142
146
  - `channel.events` exposes speech, interrupt, termination, WS data message, and media error observables.
@@ -460,7 +464,9 @@ While a bridge is active, `channel.audio.say()` still sends audio only to the A-
460
464
 
461
465
  ## ASR, VAD, And Smart Turn
462
466
 
463
- Create ASR with `channel.createAsr(config?)`.
467
+ Create ASR with `channel.createAsr(config?)`. Prefer creating it once at dialog start so the
468
+ host can warm the ASR TCP/WebSocket (one SSL handshake). A later `createAsr` with the same
469
+ resolved vendor/credentials reuses that channel; `destroy()` closes it.
464
470
 
465
471
  ```ts
466
472
  const asr = await channel.createAsr({
@@ -490,7 +496,7 @@ const asr = await channel.createAsr({
490
496
  - `error$`: runtime errors from the ASR provider (see [Error Handling](#error-handling)).
491
497
  - `pause()` / `resume()` to stop or resume forwarding new audio frames.
492
498
  - `finalize()` to force the current utterance to flush.
493
- - `destroy()` to close connector streams and subscriptions.
499
+ - `destroy()` to close the warm TCP/WS connector and subscriptions.
494
500
 
495
501
  SIP sessions use the call-level telephony VAD when it is available. WS sessions create one VAD/SmartTurn instance for the socket session on the first `createAsr()` call. Headless sessions return an inert ASR handle with empty observables.
496
502
 
@@ -548,8 +554,73 @@ When both `name` (platform key) and explicit `data` are provided, `data` values
548
554
  All audio playback goes through **`channel.audio`** (`ChannelAudio`). There are no top-level
549
555
  `channel.say()` / `channel.play()` shortcuts on `MediaChannel`.
550
556
 
557
+ Create a reusable TTS session with `channel.createTts(config?)` — same pattern as `createAsr`.
558
+ Call `tts.say` / `tts.say$` / `tts.presay` on the handle so synthesis reuses the warmed SSL / streaming WebSocket.
559
+
560
+ Custom engines from a logic package are documented in
561
+ [Custom ASR / TTS Providers](#custom-asr--tts-providers).
562
+
563
+ ```ts
564
+ const tts = await channel.createTts({
565
+ vendor: 'elevenlabs',
566
+ name: 'elevenlabs-main',
567
+ });
568
+
569
+ await tts.say('Hello', {
570
+ ttsStrategy: 'streaming',
571
+ alias: 'greeting',
572
+ });
573
+
574
+ // Track queue / speaking / done per sentence for one say$ call:
575
+ tts.say$('One. Two.', { alias: 'reply', queue: 0 }).subscribe({
576
+ next: (e) => {
577
+ if (e.state === 'queued') {
578
+ // e.text — full utterance (string) or '' until stream tokens arrive
579
+ }
580
+ if (e.state === 'speaking') {
581
+ // e.sentenceText / e.sentenceIndex — sentence starting playback
582
+ // e.itemAlias — e.g. reply-0
583
+ }
584
+ if (e.state === 'done') {
585
+ // that sentence finished; e.sentenceText / e.sentenceIndex / e.itemAlias
586
+ }
587
+ if (e.state === 'cancelled') {
588
+ // audio.stop / destroy; e.text so far
589
+ }
590
+ },
591
+ complete: () => {
592
+ // whole say$ finished (all sentences)
593
+ },
594
+ error: (err) => {
595
+ // MediaError — synthesis/playback failed
596
+ },
597
+ });
598
+
599
+ // Later turns reuse the same WebSocket:
600
+ await tts.say(tokenStream, {
601
+ ttsStrategy: 'streaming',
602
+ alias: 'reply-2',
603
+ });
604
+
605
+ tts.destroy();
606
+ ```
607
+
608
+ `tts.say()` stays a `Promise` (await until finished). `tts.say$()` returns an `Observable`
609
+ of utterance lifecycle events for that call only (`queued` → (`speaking` → `done`)×N /
610
+ `cancelled`, then complete). `done` is per sentence/phrase finishing playback; use the
611
+ Observable `complete` callback for the end of the whole `say$` call. Synthesis failures
612
+ terminate the Observable via **error** (`MediaError`), and are also mirrored on
613
+ `tts.error$` / `channel.events.error$`. `channel.audio.say` remains Promise-only.
614
+
615
+ You can still use `channel.audio.say(..., { tts })` if you prefer the channel API; a matching
616
+ pre-warmed session is also reused when vendor+config align.
617
+
551
618
  | Method | Purpose |
552
619
  | --- | --- |
620
+ | `channel.createTts(config?)` | Pre-warm a TTS connector / streaming socket; returns `TtsHandle` |
621
+ | `tts.say(textOrObservable, options?)` | Synthesize via the handle's cached connection (`Promise`) |
622
+ | `tts.say$(textOrObservable, options?)` | Same path with per-utterance status events (`Observable`) |
623
+ | `tts.presay(text, options?)` | Pre-synthesize into the host TTS cache via the handle |
553
624
  | `channel.audio.say(textOrObservable, options?)` | Synthesize text with TTS and play on a mixer queue |
554
625
  | `channel.audio.play(source, options?)` | Play raw audio (URL, path, or platform phrase record) |
555
626
  | `channel.audio.presay(text, options?)` | Pre-synthesize TTS into the host cache (no playback) |
@@ -709,6 +780,202 @@ Shared by `say()`, `play()`, and (where noted) `presay()`:
709
780
 
710
781
  `play()` ignores `tts*` and `cache` for raw audio. `preload()` only accepts `cache` overrides.
711
782
 
783
+ ## Custom ASR / TTS Providers
784
+
785
+ Trusted logic packages can ship their own ASR/TTS engines next to `defineScript`. The host
786
+ `require`s a static **`export const mediaProviders`** **outside** the script sandbox (same
787
+ process privileges as the API). Use this only for packages you trust.
788
+
789
+ Mid-script `registerAsr` / `registerTts` is **not** supported — declare vendors at module load.
790
+
791
+ ### Export shape
792
+
793
+ ```ts
794
+ import {
795
+ defineScript,
796
+ defineMediaProviders,
797
+ type MediaConnectorContext,
798
+ type MediaProviderShared,
799
+ type ScriptAsrConnector,
800
+ type ScriptTtsConnector,
801
+ } from '@voctiv/agent-sdk';
802
+ import { Subject } from 'rxjs';
803
+ import { Readable } from 'stream';
804
+
805
+ export const mediaProviders = defineMediaProviders({
806
+ // Optional: one object per dialog, shared by ASR + TTS factories
807
+ createShared: (ctx) => ({
808
+ dialogUuid: ctx.dialogUuid,
809
+ dispose() { /* release app state */ },
810
+ }),
811
+ asr: {
812
+ 'my-asr': (ctx, shared) => new MyAsr(ctx, shared),
813
+ },
814
+ tts: {
815
+ 'my-tts': (ctx, shared) => new MyTts(ctx, shared),
816
+ },
817
+ });
818
+
819
+ export default defineScript(async ({ channel }) => {
820
+ const asr = await channel.createAsr({
821
+ vendor: 'my-asr',
822
+ language: 'ru-RU',
823
+ data: { api_key: process.env.MY_ASR_KEY! },
824
+ });
825
+ const tts = await channel.createTts({
826
+ vendor: 'my-tts',
827
+ data: {
828
+ api_key: process.env.MY_TTS_KEY!,
829
+ voice_id: '…',
830
+ output_format: 'pcm_16000', // preferred for telephony
831
+ },
832
+ });
833
+
834
+ await tts.say('Hello from a custom connector.', {
835
+ alias: 'greet',
836
+ ttsStrategy: 'streaming', // used when supportsStreaming() === true
837
+ });
838
+
839
+ tts.say$('One. Two.', { alias: 'reply' }).subscribe((ev) => {
840
+ // queued | speaking | done | cancelled — same events as builtin TTS
841
+ });
842
+
843
+ // Reuse the warm handle:
844
+ await channel.audio.say('Again', { tts });
845
+
846
+ asr.destroy();
847
+ tts.destroy();
848
+ });
849
+ ```
850
+
851
+ `defineMediaProviders` is an identity helper for typing. The host looks up
852
+ `module.exports.mediaProviders` (or `default.mediaProviders`) on the script entry file.
853
+
854
+ Full stub: [`examples/custom-media-providers.ts`](./examples/custom-media-providers.ts).
855
+
856
+ ### Implement ASR (`ScriptAsrConnector`)
857
+
858
+ The host pushes **PCM S16LE mono 16 kHz** frames into `send()`. Emit partials on
859
+ `transcription$` and finals on both `transcription$` (`isFinal: true`) and `result$`.
860
+
861
+ | Member | Role |
862
+ | --- | --- |
863
+ | `transcription$` | `{ text, isFinal }` partials and finals |
864
+ | `result$` | Final utterance strings (drives `AsrHandle.result$`) |
865
+ | `error$` | Vendor / transport failures |
866
+ | `send(audio)` | Accept inbound PCM (`ArrayBuffer` / `Buffer`) |
867
+ | `speech(active)` | Optional VAD gate from the host (`true` = utterance open) |
868
+ | `finalize()` | End-of-utterance nudge (flush / commit) |
869
+ | `isOpen()` | Whether the vendor socket is ready |
870
+ | `close()` | Tear down; complete Subjects |
871
+
872
+ ```ts
873
+ class MyAsr implements ScriptAsrConnector {
874
+ readonly transcription$ = new Subject<{ text: string; isFinal: boolean }>();
875
+ readonly result$ = new Subject<string>();
876
+ readonly error$ = new Subject<{ message: string; code?: number }>();
877
+
878
+ constructor(
879
+ private readonly ctx: MediaConnectorContext,
880
+ private readonly shared: MediaProviderShared | undefined,
881
+ ) {
882
+ // ctx.config — flattened createAsr data + channel asrConfig
883
+ // ctx.dialogUuid, ctx.role, ctx.debug$
884
+ }
885
+
886
+ isOpen() { return true; }
887
+ send(audio: ArrayBufferLike) { /* forward PCM to vendor */ }
888
+ speech(_active: boolean) {}
889
+ finalize() {
890
+ const text = '…';
891
+ this.transcription$.next({ text, isFinal: true });
892
+ this.result$.next(text);
893
+ }
894
+ close() {
895
+ this.transcription$.complete();
896
+ this.result$.complete();
897
+ this.error$.complete();
898
+ }
899
+ }
900
+ ```
901
+
902
+ Factory `throw` during create → host degraded ASR handle (same as builtin). Prefer connecting
903
+ lazily in `send()`; the host does not call a separate `connect()` on custom connectors.
904
+
905
+ ### Implement TTS (`ScriptTtsConnector`)
906
+
907
+ **One class per vendor** covers batch HTTP and optional streaming WebSocket. Do **not**
908
+ register a separate streaming map.
909
+
910
+ | Member | Role |
911
+ | --- | --- |
912
+ | `supportsStreaming()` | `true` → host may use WS path for `ttsStrategy: 'streaming'` |
913
+ | `textToSpeechStream(text, ctx?)` | Batch/HTTP synthesis → `Readable` of audio bytes |
914
+ | `audio$` / `done$` | Streaming audio chunks and end-of-generation |
915
+ | `open` / `startGeneration` / `sendText` / `flush` | Streaming lifecycle |
916
+ | `sendSeparatorFlush?()` | Optional sentence separator flush |
917
+ | `close()` | Soft-close sockets for **reuse** (do not complete Subjects if `open()` may run again) |
918
+
919
+ ```ts
920
+ class MyTts implements ScriptTtsConnector {
921
+ readonly audio$ = new Subject<Buffer>();
922
+ readonly done$ = new Subject<void>();
923
+
924
+ supportsStreaming() {
925
+ return true; // or false for HTTP-only
926
+ }
927
+
928
+ async textToSpeechStream(rawtext: string, _ctx?: { previousText?: string; nextText?: string }) {
929
+ // Return PCM (preferred) or MP3/OGG. Hint format via createTts data:
930
+ // output_format: 'pcm_16000' | 'mp3_…' or audioFormat: 'pcm' | 'mp3'
931
+ return Readable.from([/* bytes */]);
932
+ }
933
+
934
+ async open() { /* open long-lived WS */ }
935
+ async startGeneration() { /* BOS / new utterance */ }
936
+ sendText(chunk: string) { /* stream tokens */ }
937
+ flush() { /* EOS; later emit done$ */ }
938
+ close() { /* close WS; keep Subjects alive for fingerprint reuse */ }
939
+ }
940
+ ```
941
+
942
+ - `supportsStreaming() === false` → streaming strategy falls back to sentence/full HTTP path.
943
+ - Default audio assumption for custom vendors is **PCM** unless `output_format` / `audioFormat`
944
+ indicates a compressed format (`mp3`, `ogg`, …).
945
+
946
+ ### Using custom vendors in the script
947
+
948
+ ```ts
949
+ const asr = await channel.createAsr({ vendor: 'my-asr', data: { … } });
950
+ const tts = await channel.createTts({ vendor: 'my-tts', data: { … } });
951
+
952
+ await tts.say('Hi', { alias: 'greet' });
953
+ await tts.presay('Warm cache');
954
+ tts.say$('Next', { alias: 'reply', ttsStrategy: 'streaming' }).subscribe(…);
955
+
956
+ await channel.audio.say('Reuse', { tts }); // same warm session
957
+ ```
958
+
959
+ Vendor keys must be **multi-character** names. Builtin single-letter codes
960
+ (`A`, `D`, `E`, `ES`, `G`, `V`, `W`, `W2`, …) **cannot** be overridden.
961
+
962
+ ### Warm reuse vs `createShared` vs PCM cache
963
+
964
+ | Layer | What it caches | Scope |
965
+ | --- | --- | --- |
966
+ | Factory + session registries | One connector instance per `dialog + vendor + config fingerprint` (TCP/WS) | Host automatic |
967
+ | `createShared` | Your app/vendor state shared by ASR↔TTS factories | One object per dialog |
968
+ | `PlayOptions.cache` / `presay` | Synthesized PCM files | Host TTS file cache |
969
+
970
+ Call `createAsr` / `createTts` early to warm sockets. Repeated `say` with the same handle (or
971
+ matching fingerprint) must **not** open a new TCP/WS per utterance.
972
+
973
+ ### Security
974
+
975
+ - Host `require` of `mediaProviders` runs with API privileges — **trusted packages only**.
976
+ - Entry path is restricted to the script root (path traversal denied).
977
+ - Optional host allowlists may further restrict which packages may export providers.
978
+
712
979
  ## TTS Credentials And Vendor Parameters
713
980
 
714
981
  ### Direct TTS Vendor Parameters
@@ -850,7 +1117,7 @@ channel.events.error$.subscribe((err) => {
850
1117
  | --- | --- | --- |
851
1118
  | `source` | `'asr' \| 'tts' \| 'sip' \| 'channel' \| 'llm'` | Which subsystem produced the error. |
852
1119
  | `phase` | `'create' \| 'start' \| 'stream' \| 'playback' \| 'finalize' \| 'destroy'?` | Lifecycle phase where the error happened. |
853
- | `operation` | `string?` | Public SDK operation, e.g. `createAsr`, `audio.say`, or `audio.play`. |
1120
+ | `operation` | `string?` | Public SDK operation, e.g. `createAsr`, `createTts`, `audio.say`, or `audio.play`. |
854
1121
  | `recoverable` | `boolean?` | Whether the runtime can keep the session alive after this error. |
855
1122
  | `handleId` | `string?` | ASR handle id when the error belongs to a recognizer instance. |
856
1123
  | `queue` | `number?` | Mixer queue index when the error belongs to an audio operation. |
@@ -1476,6 +1743,7 @@ Important fields:
1476
1743
  - `context.dialogUuid`: current dialog UUID.
1477
1744
  - `context.callerId` / `context.msisdn`: caller identity.
1478
1745
  - `context.destinationNumber`: called number.
1746
+ - `context.trunkId` / `context.trunkName`: LE trunk for this dialog/call (snapshot; name from `trunk` table).
1479
1747
  - `context.language` / `context.lang`: language selected for the run.
1480
1748
  - `context.flag`: business flag.
1481
1749
  - `context.initialData`: shallow snapshot of params at script start.
@@ -1528,6 +1796,7 @@ Headless channels are for offline, queue, or messaging sessions:
1528
1796
  - SIP methods are no-ops, except `makeCall()` and `bridge()`, which throw: there is no real leg to
1529
1797
  create, and a silent no-op would hide the mistake.
1530
1798
  - `createAsr()` returns an inert handle whose observables complete immediately.
1799
+ - `createTts()` returns an inert handle (no vendor connection is opened).
1531
1800
  - LLM, NLU, messaging, platform calls, dialog state, and `env$` still work.
1532
1801
 
1533
1802
  Use `context.headless` plus `getScriptPhase(context)` when a script must behave differently without a
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  * When the host loads platform credential catalogs, **`channel.params.authentication_data`**
14
14
  * may contain named ASR/TTS key rows for the current dialog agent and company. Use:
15
15
  * - {@link import('./types/asr-handle').AsrConfig.name} or **`data.name`** on **`createAsr`**
16
+ * - {@link import('./types/tts-handle').TtsConfig.name} or **`data.name`** on **`createTts`**
16
17
  * - {@link import('./types/mixer').PlayOptions.name} or **`ttsConfig.name`** on **`say`/`play`/`presay`**
17
18
  *
18
19
  * Channel defaults **`defaultAsrName`** / **`defaultTtsName`** apply when **`name`** is omitted.
@@ -29,6 +30,8 @@
29
30
  */
30
31
  export { defineScript } from './define-script';
31
32
  export type { ScriptContext, ScriptFn } from './define-script';
33
+ export { defineMediaProviders } from './types/media-providers';
34
+ export type { MediaProvidersDefinition, MediaConnectorContext, MediaProviderShared, AsrProviderFactory, TtsProviderFactory, ScriptAsrConnector, ScriptAsrConnectorError, ScriptTtsConnector, TtsSynthesisContext as ScriptTtsSynthesisContext, } from './types/media-providers';
32
35
  export type { ScriptDialogContext, ScriptPhase, ScriptRunTime, ScriptResult, PersistedScriptResult, ScriptError, AgentContext, AgentEnvSetOptions, StorageContextApi, } from './types/script-context';
33
36
  export { getScriptPhase } from './types/script-context';
34
37
  export type { NluScriptApi, PlatformApi, DialogApi, ScheduleCallOptions, SendMessageOptions, InboundMessage, MessagingApi, } from './types/platform';
@@ -39,6 +42,7 @@ export type { ChannelLlm, LlmOptions, LlmStreamChunk, ExtractOptions, Persistent
39
42
  export type { ChannelSip, SipState, SipProgressEvent, SipInviteHeaders, ParsedSdpDetails, } from './types/sip';
40
43
  export type { MediaError } from './types/errors';
41
44
  export type { AsrHandle, AsrConfig, AsrVadConfig, AsrSmartTurnConfig } from './types/asr-handle';
45
+ export type { TtsHandle, TtsConfig, TtsSayOptions, TtsPresayOptions, TtsUtteranceEvent, TtsUtteranceCancelReason, } from './types/tts-handle';
42
46
  export type { MixerQueueControl, PlayOptions, PresayOptions, PreloadOptions, TtsStrategy, TtsVendor } from './types/mixer';
43
47
  export type { LegacyPhraseRecord, LegacyGetRecordsParams, CacheOptions, } from './types/legacy-phrase';
44
48
  export { LEGACY_PHRASE_RECORD_BRAND, isLegacyPhraseRecord, } from './types/legacy-phrase';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE/D,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,UAAU,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACjG,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3H,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,SAAS,EACT,OAAO,EACP,SAAS,EACT,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,IAAI,yBAAyB,GACjD,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,UAAU,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACjG,YAAY,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3H,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,SAAS,EACT,OAAO,EACP,SAAS,EACT,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@
14
14
  * When the host loads platform credential catalogs, **`channel.params.authentication_data`**
15
15
  * may contain named ASR/TTS key rows for the current dialog agent and company. Use:
16
16
  * - {@link import('./types/asr-handle').AsrConfig.name} or **`data.name`** on **`createAsr`**
17
+ * - {@link import('./types/tts-handle').TtsConfig.name} or **`data.name`** on **`createTts`**
17
18
  * - {@link import('./types/mixer').PlayOptions.name} or **`ttsConfig.name`** on **`say`/`play`/`presay`**
18
19
  *
19
20
  * Channel defaults **`defaultAsrName`** / **`defaultTtsName`** apply when **`name`** is omitted.
@@ -29,9 +30,11 @@
29
30
  * and live SIP INFO ({@link import('./types/events').SipInfo} on `sipInfo$`). See **`README.md`** → SIP Signalling Metadata.
30
31
  */
31
32
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.parseRecallDelaySeconds = exports.parseRecallCount = exports.isLegacyPhraseRecord = exports.LEGACY_PHRASE_RECORD_BRAND = exports.TranscriptionRole = exports.getScriptPhase = exports.defineScript = void 0;
33
+ exports.parseRecallDelaySeconds = exports.parseRecallCount = exports.isLegacyPhraseRecord = exports.LEGACY_PHRASE_RECORD_BRAND = exports.TranscriptionRole = exports.getScriptPhase = exports.defineMediaProviders = exports.defineScript = void 0;
33
34
  var define_script_1 = require("./define-script");
34
35
  Object.defineProperty(exports, "defineScript", { enumerable: true, get: function () { return define_script_1.defineScript; } });
36
+ var media_providers_1 = require("./types/media-providers");
37
+ Object.defineProperty(exports, "defineMediaProviders", { enumerable: true, get: function () { return media_providers_1.defineMediaProviders; } });
35
38
  var script_context_1 = require("./types/script-context");
36
39
  Object.defineProperty(exports, "getScriptPhase", { enumerable: true, get: function () { return script_context_1.getScriptPhase; } });
37
40
  var logger_1 = require("./types/logger");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;AAEH,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAerB,yDAAwD;AAA/C,gHAAA,cAAc,OAAA;AAavB,yCAAmD;AAA1C,2GAAA,iBAAiB,OAAA;AAgC1B,uDAG+B;AAF7B,2HAAA,0BAA0B,OAAA;AAC1B,qHAAA,oBAAoB,OAAA;AAUtB,+CAA2E;AAAlE,gHAAA,gBAAgB,OAAA;AAAE,uHAAA,uBAAuB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;;;AAEH,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAGrB,2DAA+D;AAAtD,uHAAA,oBAAoB,OAAA;AAyB7B,yDAAwD;AAA/C,gHAAA,cAAc,OAAA;AAavB,yCAAmD;AAA1C,2GAAA,iBAAiB,OAAA;AAwC1B,uDAG+B;AAF7B,2HAAA,0BAA0B,OAAA;AAC1B,qHAAA,oBAAoB,OAAA;AAUtB,+CAA2E;AAAlE,gHAAA,gBAAgB,OAAA;AAAE,uHAAA,uBAAuB,OAAA"}
@@ -102,9 +102,13 @@ export interface AsrConfig {
102
102
  /**
103
103
  * Live speech recognition session returned by {@link import('./media-channel').MediaChannel.createAsr}.
104
104
  *
105
+ * Call **`createAsr` early** to warm the ASR TCP/WebSocket (SSL handshake once per
106
+ * dialog + vendor + credentials). A second `createAsr` with the same resolved config
107
+ * reuses that channel instead of opening another socket. Call **`destroy()`** when done
108
+ * (e.g. on `channel.events.terminated$`) to release the connector.
109
+ *
105
110
  * Subscribe to **`partial$`** / **`result$`** for transcripts; wire **`speechStart$`** /
106
- * **`speechEnd$`** / **`interrupt$`** for barge-in and UI. Call **`destroy()`** when done
107
- * (e.g. on `channel.events.terminated$`) to release connector and subscriptions.
111
+ * **`speechEnd$`** / **`interrupt$`** for barge-in and UI.
108
112
  *
109
113
  * If connector creation fails, SIP/WS return a degraded handle: VAD observables still
110
114
  * mirror the channel where possible, but `partial$` and `result$` do not emit real STT.
@@ -1 +1 @@
1
- {"version":3,"file":"asr-handle.d.ts","sourceRoot":"","sources":["../../src/types/asr-handle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oGAAoG;IACpG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,sEAAsE;IACtE,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClE,kEAAkE;IAClE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACxC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,6FAA6F;IAC7F,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAE7C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAExC,0FAA0F;IAC1F,KAAK,IAAI,IAAI,CAAC;IACd,kCAAkC;IAClC,MAAM,IAAI,IAAI,CAAC;IACf,kFAAkF;IAClF,QAAQ,IAAI,IAAI,CAAC;IACjB,8FAA8F;IAC9F,OAAO,IAAI,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"asr-handle.d.ts","sourceRoot":"","sources":["../../src/types/asr-handle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oGAAoG;IACpG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,sEAAsE;IACtE,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClE,kEAAkE;IAClE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACxC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,6FAA6F;IAC7F,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAE7C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAExC,0FAA0F;IAC1F,KAAK,IAAI,IAAI,CAAC;IACd,kCAAkC;IAClC,MAAM,IAAI,IAAI,CAAC;IACf,kFAAkF;IAClF,QAAQ,IAAI,IAAI,CAAC;IACjB,8FAA8F;IAC9F,OAAO,IAAI,IAAI,CAAC;CACjB"}
@@ -1,5 +1,6 @@
1
1
  import type { Observable } from 'rxjs';
2
2
  import type { AsrConfig, AsrHandle } from './asr-handle';
3
+ import type { TtsConfig, TtsHandle } from './tts-handle';
3
4
  import type { DataMessage } from './events';
4
5
  import type { MixerQueueControl, PlayOptions, PresayOptions, PreloadOptions } from './mixer';
5
6
  import type { LegacyPhraseRecord } from './legacy-phrase';
@@ -153,7 +154,7 @@ export interface MediaChannel {
153
154
  * Relevant to ASR/TTS when **Voctiv platform** compatibility is on (host-dependent keys), for example:
154
155
  * - **`asrVendor`**, **`ttsVendor`**, **`asrConfig`**, **`ttsConfig`**
155
156
  * - **`defaultAsrName`**, **`defaultTtsName`**: default **`key_storage.name`** when the script
156
- * omits **`name`** on {@link AsrConfig} / {@link PlayOptions}
157
+ * omits **`name`** on {@link AsrConfig} / {@link TtsConfig} / {@link PlayOptions}
157
158
  * - **`authentication_data`**: may include **`legacyAsrKeysByName`**, **`legacyTtsKeysByName`**
158
159
  * (built from LE DB for this dialog's agent + company)
159
160
  *
@@ -161,11 +162,13 @@ export interface MediaChannel {
161
162
  */
162
163
  readonly params: Record<string, unknown>;
163
164
  /**
164
- * Create a speech recognizer for this session.
165
+ * Create (or warm) a speech recognizer for this session so recognition can reuse one
166
+ * TCP/WebSocket (one SSL handshake) for the dialog + vendor + credentials.
165
167
  *
166
168
  * SIP channels feed remote RTP audio. WS channels feed socket `audio` frames and can
167
169
  * create a per-session VAD on first ASR creation. Headless channels return an inert
168
- * handle with empty observables.
170
+ * handle with empty observables. A second call with the same resolved config returns
171
+ * the existing warm handle.
169
172
  *
170
173
  * @param config - Optional {@link AsrConfig}: **`vendor`**, **`name`** (storage row), **`language`**,
171
174
  * **`data`** overlays, VAD / smart-turn tuning.
@@ -173,6 +176,24 @@ export interface MediaChannel {
173
176
  * If connector creation fails, SIP/WS return a degraded handle with VAD observables but no STT results.
174
177
  */
175
178
  createAsr(config?: AsrConfig): Promise<AsrHandle>;
179
+ /**
180
+ * Create (or warm) a TTS connector for this session so later `audio.say` / `audio.presay`
181
+ * can reuse the SSL / WebSocket connection.
182
+ *
183
+ * For streaming-capable vendors (e.g. ElevenLabs with `ttsStrategy: 'streaming'`), the host
184
+ * opens the streaming socket during this call. For batch HTTP vendors, the connector instance
185
+ * is registered in the dialog-scoped factory (keep-alive pool).
186
+ *
187
+ * Prefer calling {@link TtsHandle.say} / {@link TtsHandle.presay} on the returned handle
188
+ * (same pattern as {@link AsrHandle}). You may also pass the handle as {@link PlayOptions.tts}
189
+ * to `channel.audio.say` / `presay`, or omit it when a later `say` resolves to the same
190
+ * vendor+config — the host will reuse a matching session.
191
+ *
192
+ * @param config - Optional {@link TtsConfig}: **`vendor`**, **`name`** (storage row), **`data`** overlays.
193
+ * @returns A handle you should {@link TtsHandle.destroy} when you no longer need the connection.
194
+ * If connector creation fails, SIP/WS return a degraded handle (synthesis falls back to ephemeral).
195
+ */
196
+ createTts(config?: TtsConfig): Promise<TtsHandle>;
176
197
  /** Push synthetic ASR results (testing / WS debug). No-op on headless channels. */
177
198
  readonly textInput: TextInput;
178
199
  readonly audio: ChannelAudio;
@@ -1 +1 @@
1
- {"version":3,"file":"media-channel.d.ts","sourceRoot":"","sources":["../../src/types/media-channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"media-channel.d.ts","sourceRoot":"","sources":["../../src/types/media-channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { Observable, Subject } from 'rxjs';
2
+ import type { Readable } from 'stream';
3
+ /**
4
+ * Context passed to custom ASR/TTS factories from {@link defineMediaProviders}.
5
+ * Populated by the host outside the script sandbox.
6
+ */
7
+ export interface MediaConnectorContext {
8
+ id: string;
9
+ config: Record<string, string>;
10
+ dialogUuid: string;
11
+ role?: string;
12
+ debug$: Subject<string>;
13
+ }
14
+ export interface ScriptAsrConnectorError {
15
+ message: string;
16
+ code?: number;
17
+ }
18
+ /**
19
+ * Host ASR connector contract for custom providers (same surface as runtime AsrConnector).
20
+ */
21
+ export interface ScriptAsrConnector {
22
+ transcription$: Subject<{
23
+ text: string;
24
+ isFinal: boolean;
25
+ }>;
26
+ result$: Subject<string>;
27
+ error$: Subject<ScriptAsrConnectorError>;
28
+ isOpen(): boolean;
29
+ send(audio: ArrayBufferLike): void;
30
+ speech(active: boolean): void;
31
+ finalize(): void;
32
+ close(): void;
33
+ }
34
+ export type TtsSynthesisContext = {
35
+ previousText?: string;
36
+ nextText?: string;
37
+ };
38
+ /**
39
+ * Unified TTS connector: batch HTTP + optional streaming WebSocket methods.
40
+ */
41
+ export interface ScriptTtsConnector {
42
+ supportsStreaming(): boolean;
43
+ textToSpeechStream(rawtext: string, ctx?: TtsSynthesisContext): Promise<Readable>;
44
+ readonly audio$: Subject<Buffer>;
45
+ readonly done$: Subject<void>;
46
+ open(): Promise<void>;
47
+ startGeneration(): Promise<void>;
48
+ sendText(chunk: string): void;
49
+ flush(): void;
50
+ sendSeparatorFlush?(): void;
51
+ close(): void;
52
+ }
53
+ /** Optional session object shared by ASR and TTS factories for one dialog. */
54
+ export type MediaProviderShared = {
55
+ dispose?: () => void;
56
+ close?: () => void;
57
+ } & Record<string, unknown>;
58
+ export type AsrProviderFactory = (ctx: MediaConnectorContext, shared: MediaProviderShared | undefined) => ScriptAsrConnector;
59
+ export type TtsProviderFactory = (ctx: MediaConnectorContext, shared: MediaProviderShared | undefined) => ScriptTtsConnector;
60
+ export interface MediaProvidersDefinition {
61
+ createShared?: (ctx: {
62
+ dialogUuid: string;
63
+ debug$: Subject<string>;
64
+ }) => MediaProviderShared;
65
+ asr?: Record<string, AsrProviderFactory>;
66
+ tts?: Record<string, TtsProviderFactory>;
67
+ }
68
+ /**
69
+ * Mark a named export as custom media providers (identity helper).
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * export const mediaProviders = defineMediaProviders({
74
+ * createShared: (ctx) => new MySession(ctx),
75
+ * asr: { 'my-asr': (ctx, shared) => new MyAsr(ctx, shared) },
76
+ * tts: { 'my-tts': (ctx, shared) => new MyTts(ctx, shared) },
77
+ * });
78
+ * ```
79
+ */
80
+ export declare function defineMediaProviders(def: MediaProvidersDefinition): MediaProvidersDefinition;
81
+ /** @internal helper type for hosts that mirror connector subjects */
82
+ export type SubjectLike<T> = Subject<T> | Observable<T>;
83
+ //# sourceMappingURL=media-providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-providers.d.ts","sourceRoot":"","sources":["../../src/types/media-providers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineMediaProviders = defineMediaProviders;
4
+ /**
5
+ * Mark a named export as custom media providers (identity helper).
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * export const mediaProviders = defineMediaProviders({
10
+ * createShared: (ctx) => new MySession(ctx),
11
+ * asr: { 'my-asr': (ctx, shared) => new MyAsr(ctx, shared) },
12
+ * tts: { 'my-tts': (ctx, shared) => new MyTts(ctx, shared) },
13
+ * });
14
+ * ```
15
+ */
16
+ function defineMediaProviders(def) {
17
+ return def;
18
+ }
19
+ //# sourceMappingURL=media-providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-providers.js","sourceRoot":"","sources":["../../src/types/media-providers.ts"],"names":[],"mappings":";;AAmGA,oDAIC;AAhBD;;;;;;;;;;;GAWG;AACH,SAAgB,oBAAoB,CAClC,GAA6B;IAE7B,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import type { CacheOptions } from './legacy-phrase';
3
+ import type { TtsHandle } from './tts-handle';
3
4
  /**
4
5
  * How TTS audio is chunked and fed to the mixer.
5
6
  *
@@ -74,8 +75,16 @@ export interface PlayOptions {
74
75
  /**
75
76
  * Force a specific TTS vendor for this call, overriding **`channel.params.ttsVendor`**.
76
77
  * Ignored for **`play()`** when the source is raw audio (no synthesis).
78
+ * When {@link tts} is set, the handle's resolved vendor/config take precedence.
77
79
  */
78
80
  ttsVendor?: TtsVendor;
81
+ /**
82
+ * Pre-warmed TTS session from {@link import('./media-channel').MediaChannel.createTts}.
83
+ * Reuses the cached connector / streaming WebSocket so synthesis skips a fresh SSL handshake.
84
+ * When set, the handle's resolved vendor and connector config are used (overrides
85
+ * {@link ttsVendor} / {@link name} / {@link ttsConfig} for credential resolution).
86
+ */
87
+ tts?: TtsHandle;
79
88
  /**
80
89
  * logic-executor **`key_storage.name`**: use **`authentication_data.legacyTtsKeysByName[name]`**
81
90
  * for credentials. Overrides **`defaultTtsName`** on the channel.
@@ -107,6 +116,11 @@ export interface PlayOptions {
107
116
  */
108
117
  export interface PresayOptions {
109
118
  ttsVendor?: TtsVendor;
119
+ /**
120
+ * Pre-warmed TTS session from {@link import('./media-channel').MediaChannel.createTts}.
121
+ * Same reuse semantics as {@link PlayOptions.tts}.
122
+ */
123
+ tts?: TtsHandle;
110
124
  name?: string;
111
125
  ttsConfig?: Record<string, unknown>;
112
126
  ttsStrategy?: TtsStrategy;
@@ -1 +1 @@
1
- {"version":3,"file":"mixer.d.ts","sourceRoot":"","sources":["../../src/types/mixer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,QAAQ,GACR,OAAO,GACP,UAAU,GACV,UAAU,GACV,eAAe,GACf,aAAa,GACb,KAAK,GACL,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,IAAI,GAAG,YAAY,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mFAAmF;IACnF,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,mFAAmF;IACnF,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IAEf,mEAAmE;IACnE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,yFAAyF;IACzF,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3C;oFACgF;IAChF,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAEvC;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uDAAuD;IACvD,KAAK,IAAI,IAAI,CAAC;CACf"}
1
+ {"version":3,"file":"mixer.d.ts","sourceRoot":"","sources":["../../src/types/mixer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,QAAQ,GACR,OAAO,GACP,UAAU,GACV,UAAU,GACV,eAAe,GACf,aAAa,GACb,KAAK,GACL,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,IAAI,GAAG,YAAY,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mFAAmF;IACnF,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,mFAAmF;IACnF,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IAEf,mEAAmE;IACnE,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,yFAAyF;IACzF,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3C;oFACgF;IAChF,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAEvC;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uDAAuD;IACvD,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -59,6 +59,21 @@ export interface ScriptDialogContext {
59
59
  callerId: string;
60
60
  /** Called number (DID / destination for inbound calls). */
61
61
  destinationNumber: string;
62
+ /**
63
+ * LE trunk id for this dialog/call — snapshot at script start.
64
+ *
65
+ * Resolved from `call.trunk_id`, inbound `X-Trunk-Id`, `dialog.params.trunk_id`,
66
+ * then `agent.trunk_id`. Omitted when no trunk is configured.
67
+ */
68
+ trunkId?: number;
69
+ /**
70
+ * LE `trunk.name` for {@link trunkId}, resolved by the host at script start.
71
+ *
72
+ * Available in online and headless runs when the platform trunk table is reachable.
73
+ * Not a SIP wire header — for inbound id-only signalling use
74
+ * `channel.sip.inviteSipHeaders['X-Trunk-Id']`.
75
+ */
76
+ trunkName?: string;
62
77
  /** Script record ID in the system. */
63
78
  scriptId: string;
64
79
  /** Human-readable script name. */
@@ -1 +1 @@
1
- {"version":3,"file":"script-context.d.ts","sourceRoot":"","sources":["../../src/types/script-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"script-context.d.ts","sourceRoot":"","sources":["../../src/types/script-context.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"script-context.js","sourceRoot":"","sources":["../../src/types/script-context.ts"],"names":[],"mappings":";;AA6QA,wCAcC;AApCD,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC;IAC9C,iBAAiB;IACjB,oBAAoB;IACpB,cAAc;CACf,CAAC,CAAC;AACH,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC;IAC7C,gBAAgB;IAChB,mBAAmB;CACpB,CAAC,CAAC;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,OAA4B;IACzD,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAEvC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAE1D,IAAI,+BAA+B,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACzE,IAAI,8BAA8B,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACvE,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,EAAE,KAAK,yBAAyB,IAAI,OAAO,CAAC,cAAc;QAC5D,OAAO,WAAW,CAAC;IAErB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAEnE,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"script-context.js","sourceRoot":"","sources":["../../src/types/script-context.ts"],"names":[],"mappings":";;AA4RA,wCAcC;AApCD,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC;IAC9C,iBAAiB;IACjB,oBAAoB;IACpB,cAAc;CACf,CAAC,CAAC;AACH,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC;IAC7C,gBAAgB;IAChB,mBAAmB;CACpB,CAAC,CAAC;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,OAA4B;IACzD,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAEvC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAE1D,IAAI,+BAA+B,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACzE,IAAI,8BAA8B,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACvE,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,EAAE,KAAK,yBAAyB,IAAI,OAAO,CAAC,cAAc;QAC5D,OAAO,WAAW,CAAC;IAErB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAEnE,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,194 @@
1
+ import type { Observable } from 'rxjs';
2
+ import type { MediaError } from './errors';
3
+ import type { PlayOptions, PresayOptions } from './mixer';
4
+ /**
5
+ * Arguments for {@link import('./media-channel').MediaChannel.createTts}.
6
+ *
7
+ * Mirrors {@link import('./asr-handle').AsrConfig} credential selection for TTS:
8
+ * when Voctiv platform compatibility is on, **`name`** selects a row from
9
+ * **`authentication_data.legacyTtsKeysByName`**. You may also set the same selector
10
+ * as **`data.name`** (stripped before vendor params are built).
11
+ *
12
+ * Call **`createTts`** early in the dialog to open / warm the vendor connection
13
+ * (HTTP keep-alive pool or streaming WebSocket) so later {@link TtsHandle.say}
14
+ * / {@link TtsHandle.say$} / {@link TtsHandle.presay} calls reuse it instead of
15
+ * paying SSL handshake latency on every utterance.
16
+ */
17
+ export interface TtsConfig {
18
+ /**
19
+ * TTS vendor / engine hint, e.g. `"elevenlabs"`, `"google"`, `"azure"`, `"voctiv"`.
20
+ * Resolved via ScriptEngine vendor aliases. If you set **`name`** but omit **`vendor`**,
21
+ * the runtime may infer vendor from the key row's **`platform`** in the catalog.
22
+ */
23
+ vendor?: string;
24
+ /**
25
+ * logic-executor **`key_storage.name`** for this dialog's agent + company. Selects credentials
26
+ * from **`authentication_data.legacyTtsKeysByName[name]`** when Voctiv platform PostgreSQL key auth is enabled.
27
+ * Overrides channel **`defaultTtsName`**.
28
+ */
29
+ name?: string;
30
+ /**
31
+ * Vendor-specific connection parameters (voice id, model, `output_format`, nested JSON, …).
32
+ * Merged last over channel defaults and catalog credentials so the script can override
33
+ * per session. Primitives are stringified; objects and arrays are JSON-serialized.
34
+ *
35
+ * Do not rely on **`name`** here for third-party "model name" fields — the runtime consumes
36
+ * it as the storage row selector and removes it before vendor config is built.
37
+ */
38
+ data?: Record<string, unknown>;
39
+ }
40
+ /**
41
+ * Playback options for {@link TtsHandle.say} / {@link TtsHandle.say$}.
42
+ *
43
+ * Vendor / credentials come from {@link import('./media-channel').MediaChannel.createTts};
44
+ * only mixer and strategy fields apply here.
45
+ */
46
+ export type TtsSayOptions = Omit<PlayOptions, 'tts' | 'ttsVendor' | 'name' | 'ttsConfig'>;
47
+ /**
48
+ * Options for {@link TtsHandle.presay}.
49
+ *
50
+ * Vendor / credentials come from {@link import('./media-channel').MediaChannel.createTts}.
51
+ */
52
+ export type TtsPresayOptions = Omit<PresayOptions, 'tts' | 'ttsVendor' | 'name' | 'ttsConfig'>;
53
+ /** Why a tracked utterance was cancelled before natural completion. */
54
+ export type TtsUtteranceCancelReason = 'stop' | 'destroy';
55
+ /**
56
+ * Lifecycle events for one {@link TtsHandle.say$} invocation.
57
+ *
58
+ * Typical sequence (sentence strategy):
59
+ * `queued` → (`speaking` → `done`)×N then Observable **complete**.
60
+ * `done` means one sentence/phrase finished playback (not the whole `say$` call).
61
+ * Single-item / streaming strategy: one `speaking` → one `done` then **complete**.
62
+ * On barge-in / `audio.stop`: `queued` → (`speaking`?) → `cancelled` then **complete**.
63
+ * On synthesis failure: `queued` → (`speaking`?) then the Observable **errors** with
64
+ * {@link MediaError} (also mirrored on {@link TtsHandle.error$} / `channel.events.error$`).
65
+ */
66
+ export type TtsUtteranceEvent = {
67
+ state: 'queued';
68
+ alias: string;
69
+ queue: number;
70
+ /**
71
+ * Full utterance text known so far.
72
+ * Plain string input: complete text. Token stream: grows as chunks arrive
73
+ * (initial `queued` may have `text: ''`).
74
+ */
75
+ text: string;
76
+ } | {
77
+ state: 'speaking';
78
+ alias: string;
79
+ queue: number;
80
+ /** Full utterance text accumulated so far (stream) or the whole input (string). */
81
+ text: string;
82
+ /**
83
+ * Text of the sentence/segment currently starting playback when the host
84
+ * uses sentence-split aliases (`alias-0`, `alias-1`, …).
85
+ * For a single-item utterance (streaming strategy / exact alias) this equals {@link text}.
86
+ */
87
+ sentenceText: string;
88
+ /** Index of the sentence segment (`0` for `alias-0`), when applicable. */
89
+ sentenceIndex?: number;
90
+ /** Concrete mixer item alias (may be `alias-0` for sentence-split TTS). */
91
+ itemAlias?: string;
92
+ } | {
93
+ state: 'done';
94
+ alias: string;
95
+ queue: number;
96
+ /** Full utterance text accumulated so far (stream) or the whole input (string). */
97
+ text: string;
98
+ /**
99
+ * Text of the sentence/segment that just finished playback.
100
+ * Same rules as {@link TtsUtteranceEvent} `speaking.sentenceText`.
101
+ */
102
+ sentenceText: string;
103
+ /** Index of the sentence segment (`0` for `alias-0`), when applicable. */
104
+ sentenceIndex?: number;
105
+ /** Concrete mixer item alias that finished. */
106
+ itemAlias?: string;
107
+ } | {
108
+ state: 'cancelled';
109
+ alias: string;
110
+ queue: number;
111
+ reason: TtsUtteranceCancelReason;
112
+ /** Accumulated text at cancel time. */
113
+ text: string;
114
+ };
115
+ /**
116
+ * Pre-warmed TTS session returned by {@link import('./media-channel').MediaChannel.createTts}.
117
+ *
118
+ * Use **`say`** / **`say$`** / **`presay`** on this handle (same idea as
119
+ * {@link import('./asr-handle').AsrHandle} methods) so synthesis reuses the cached
120
+ * connector / streaming WebSocket. Call **`destroy()`** when done
121
+ * (e.g. on `channel.events.terminated$`) to release the session.
122
+ *
123
+ * You may still pass the handle as {@link import('./mixer').PlayOptions.tts} to
124
+ * `channel.audio.say` / `presay` if needed.
125
+ *
126
+ * If connector creation fails, SIP/WS return a degraded handle: `say`/`say$`/`presay` fall back
127
+ * to an ephemeral connection, and the creation failure is reported on
128
+ * {@link import('./media-channel').ChannelEvents.error$}.
129
+ *
130
+ * ```ts
131
+ * const tts = await channel.createTts({ name: 'elevenlabs-main' });
132
+ * tts.error$.subscribe(err => console.log('TTS error:', err.message));
133
+ *
134
+ * await tts.say('Hello', { alias: 'greeting' });
135
+ *
136
+ * tts.say$('Next', { alias: 'reply' }).subscribe({
137
+ * next: (e) => { if (e.state === 'speaking') console.log('now playing', e.alias); },
138
+ * error: (err) => console.log('TTS failed', err.message),
139
+ * });
140
+ *
141
+ * tts.destroy();
142
+ * ```
143
+ */
144
+ export interface TtsHandle {
145
+ /** Opaque id for this pre-warmed TTS session. */
146
+ readonly id: string;
147
+ /**
148
+ * Runtime errors from the TTS provider for this session (auth failures, disconnects, etc.).
149
+ *
150
+ * A degraded handle (returned when connector creation itself failed) has an inert `error$`
151
+ * that never emits — the creation failure is reported on {@link import('./media-channel').ChannelEvents.error$} instead.
152
+ */
153
+ readonly error$: Observable<MediaError>;
154
+ /**
155
+ * Synthesize and play text on a mixer queue, reusing this session's connector.
156
+ *
157
+ * Resolves when playback of this invocation has finished (or was aborted).
158
+ * For per-utterance lifecycle (`queued` / `speaking` / `done` / …) use {@link say$}.
159
+ */
160
+ say(input: string | Observable<string>, options?: TtsSayOptions): Promise<void>;
161
+ /**
162
+ * Same synthesis path as {@link say}, but emits {@link TtsUtteranceEvent} for this utterance.
163
+ *
164
+ * Only available on handles from {@link import('./media-channel').MediaChannel.createTts}
165
+ * (not on `channel.audio.say`). Emits `done` per finished sentence; Observable **completes**
166
+ * when the whole call ends (or after `cancelled`). Synthesis failures go to the Observable
167
+ * **error** channel as {@link MediaError}.
168
+ *
169
+ * ```ts
170
+ * tts.say$('One. Two.', { alias: 'greet', queue: 0 }).subscribe({
171
+ * next: (e) => {
172
+ * switch (e.state) {
173
+ * case 'queued': break; // e.text — full string (or '' for live stream)
174
+ * case 'speaking': break; // e.sentenceText — sentence starting playback
175
+ * case 'done': break; // e.sentenceText — that sentence finished
176
+ * case 'cancelled': break; // stop / destroy
177
+ * }
178
+ * },
179
+ * complete: () => {}, // whole say$ finished
180
+ * error: (err: MediaError) => console.log('TTS failed', err.message),
181
+ * });
182
+ * ```
183
+ */
184
+ say$(input: string | Observable<string>, options?: TtsSayOptions): Observable<TtsUtteranceEvent>;
185
+ /**
186
+ * Pre-synthesize text into the host TTS cache using this session's connector.
187
+ *
188
+ * Same behaviour as {@link import('./media-channel').ChannelAudio.presay}.
189
+ */
190
+ presay(text: string, options?: TtsPresayOptions): Promise<void>;
191
+ /** Tear down the cached connector / streaming socket. Idempotent-safe on well-behaved hosts. */
192
+ destroy(): void;
193
+ }
194
+ //# sourceMappingURL=tts-handle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts-handle.d.ts","sourceRoot":"","sources":["../../src/types/tts-handle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=tts-handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts-handle.js","sourceRoot":"","sources":["../../src/types/tts-handle.ts"],"names":[],"mappings":""}
@@ -11,6 +11,7 @@ Each file exports one `defineScript` handler. The host **always** invokes that s
11
11
  | [schedule-call-with-defaults.ts](./schedule-call-with-defaults.ts) | `platform.call()` using CMS defaults from `context` |
12
12
  | [after-call-continuation.ts](./after-call-continuation.ts) | `onSuccessCall` / `onFailedCall` + `getScriptPhase()` |
13
13
  | [read-recall-from-params.ts](./read-recall-from-params.ts) | `parseRecallDelaySeconds()` / `parseRecallCount()` |
14
+ | [custom-media-providers.ts](./custom-media-providers.ts) | `defineMediaProviders` + `createAsr` / `createTts` / `say$` |
14
15
 
15
16
  ## Recall flow
16
17
 
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Custom ASR / TTS from a trusted logic package.
3
+ *
4
+ * Export `mediaProviders` next to `defineScript`. The host loads that export
5
+ * outside the sandbox and wires vendors into `createAsr` / `createTts` with the
6
+ * same warm TCP/WS reuse as built-in engines.
7
+ *
8
+ * Batch and streaming TTS share one class (`supportsStreaming()` + streaming
9
+ * lifecycle methods). Do not register a separate streaming map.
10
+ */
11
+ import { Readable } from 'stream';
12
+ import { Subject } from 'rxjs';
13
+ import {
14
+ defineScript,
15
+ defineMediaProviders,
16
+ type MediaConnectorContext,
17
+ type MediaProviderShared,
18
+ type ScriptAsrConnector,
19
+ type ScriptTtsConnector,
20
+ } from '@voctiv/agent-sdk';
21
+
22
+ type SharedSession = MediaProviderShared & {
23
+ turns: number;
24
+ };
25
+
26
+ class EchoAsr implements ScriptAsrConnector {
27
+ readonly transcription$ = new Subject<{ text: string; isFinal: boolean }>();
28
+ readonly result$ = new Subject<string>();
29
+ readonly error$ = new Subject<{ message: string; code?: number }>();
30
+
31
+ constructor(
32
+ private readonly ctx: MediaConnectorContext,
33
+ private readonly shared: SharedSession | undefined,
34
+ ) {}
35
+
36
+ isOpen(): boolean {
37
+ return true;
38
+ }
39
+
40
+ send(_audio: ArrayBufferLike): void {
41
+ // Forward PCM to your vendor here.
42
+ }
43
+
44
+ speech(_active: boolean): void {}
45
+
46
+ finalize(): void {
47
+ const text = 'heard';
48
+ this.transcription$.next({ text, isFinal: true });
49
+ this.result$.next(text);
50
+ if (this.shared) this.shared.turns += 1;
51
+ }
52
+
53
+ close(): void {
54
+ this.transcription$.complete();
55
+ this.result$.complete();
56
+ this.error$.complete();
57
+ }
58
+ }
59
+
60
+ class BatchOrStreamTts implements ScriptTtsConnector {
61
+ readonly audio$ = new Subject<Buffer>();
62
+ readonly done$ = new Subject<void>();
63
+
64
+ constructor(
65
+ private readonly ctx: MediaConnectorContext,
66
+ private readonly shared: SharedSession | undefined,
67
+ ) {}
68
+
69
+ /** Return true when this connector also owns a long-lived streaming socket. */
70
+ supportsStreaming(): boolean {
71
+ return false;
72
+ }
73
+
74
+ async textToSpeechStream(rawtext: string): Promise<Readable> {
75
+ void this.ctx;
76
+ void this.shared;
77
+ // Replace with HTTP keep-alive synthesis that returns a PCM stream.
78
+ return Readable.from([Buffer.from(rawtext, 'utf8')]);
79
+ }
80
+
81
+ async open(): Promise<void> {}
82
+ async startGeneration(): Promise<void> {}
83
+ sendText(_chunk: string): void {}
84
+ flush(): void {}
85
+ close(): void {
86
+ // Soft-close streaming sockets for reuse; do not complete Subjects if the
87
+ // host may call open() again on the same fingerprint.
88
+ }
89
+ }
90
+
91
+ export const mediaProviders = defineMediaProviders({
92
+ createShared: (): SharedSession => ({
93
+ turns: 0,
94
+ dispose() {
95
+ /* release vendor app state for this dialog */
96
+ },
97
+ }),
98
+ asr: {
99
+ 'my-asr': (ctx, shared) => new EchoAsr(ctx, shared as SharedSession),
100
+ },
101
+ tts: {
102
+ 'my-tts': (ctx, shared) =>
103
+ new BatchOrStreamTts(ctx, shared as SharedSession),
104
+ },
105
+ });
106
+
107
+ export default defineScript(async ({ channel, logger }) => {
108
+ channel.sip.answer();
109
+
110
+ const asr = await channel.createAsr({ vendor: 'my-asr' });
111
+ const tts = await channel.createTts({ vendor: 'my-tts' });
112
+
113
+ await tts.say('Hello from a custom TTS connector.');
114
+
115
+ tts.say$('One. Two.', { alias: 'reply' }).subscribe({
116
+ next: (ev) => {
117
+ logger.log('tts utterance', { state: ev.state, alias: ev.itemAlias });
118
+ },
119
+ error: (err) => logger.error('tts failed', err),
120
+ });
121
+
122
+ // Same warm handle via audio.say:
123
+ await channel.audio.say('Reuse handle', { tts });
124
+
125
+ asr.destroy();
126
+ tts.destroy();
127
+ channel.sip.hangup();
128
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voctiv/agent-sdk",
3
- "version": "0.2.16",
3
+ "version": "0.3.1",
4
4
  "description": "Voctiv TypeScript agent SDK: defineScript and platform types for the voice/dialog scripting runtime.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "",