@framers/agentos 0.1.75 → 0.1.77

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 (152) hide show
  1. package/README.md +148 -38
  2. package/dist/api/agent.d.ts +13 -3
  3. package/dist/api/agent.d.ts.map +1 -1
  4. package/dist/api/agent.js +1 -0
  5. package/dist/api/agent.js.map +1 -1
  6. package/dist/api/generateImage.d.ts +11 -2
  7. package/dist/api/generateImage.d.ts.map +1 -1
  8. package/dist/api/generateImage.js +2 -2
  9. package/dist/api/generateImage.js.map +1 -1
  10. package/dist/api/generateText.d.ts +13 -3
  11. package/dist/api/generateText.d.ts.map +1 -1
  12. package/dist/api/generateText.js +2 -2
  13. package/dist/api/generateText.js.map +1 -1
  14. package/dist/api/model.d.ts +53 -0
  15. package/dist/api/model.d.ts.map +1 -1
  16. package/dist/api/model.js +58 -0
  17. package/dist/api/model.js.map +1 -1
  18. package/dist/api/provider-defaults.d.ts +40 -0
  19. package/dist/api/provider-defaults.d.ts.map +1 -0
  20. package/dist/api/provider-defaults.js +73 -0
  21. package/dist/api/provider-defaults.js.map +1 -0
  22. package/dist/api/streamText.js +2 -2
  23. package/dist/api/streamText.js.map +1 -1
  24. package/dist/core/agency/AgentCommunicationBus.d.ts +1 -0
  25. package/dist/core/agency/AgentCommunicationBus.d.ts.map +1 -1
  26. package/dist/core/agency/AgentCommunicationBus.js +62 -8
  27. package/dist/core/agency/AgentCommunicationBus.js.map +1 -1
  28. package/dist/core/agency/IAgentCommunicationBus.d.ts +1 -1
  29. package/dist/core/agency/IAgentCommunicationBus.d.ts.map +1 -1
  30. package/dist/orchestration/runtime/LoopController.d.ts +10 -10
  31. package/dist/orchestration/runtime/LoopController.d.ts.map +1 -1
  32. package/dist/orchestration/runtime/LoopController.js +1 -1
  33. package/dist/orchestration/runtime/LoopController.js.map +1 -1
  34. package/dist/orchestration/runtime/index.d.ts +1 -1
  35. package/dist/orchestration/runtime/index.d.ts.map +1 -1
  36. package/dist/orchestration/runtime/index.js.map +1 -1
  37. package/dist/speech/FallbackProxy.d.ts +104 -0
  38. package/dist/speech/FallbackProxy.d.ts.map +1 -0
  39. package/dist/speech/FallbackProxy.js +151 -0
  40. package/dist/speech/FallbackProxy.js.map +1 -0
  41. package/dist/speech/SpeechProviderResolver.d.ts +103 -0
  42. package/dist/speech/SpeechProviderResolver.d.ts.map +1 -0
  43. package/dist/speech/SpeechProviderResolver.js +256 -0
  44. package/dist/speech/SpeechProviderResolver.js.map +1 -0
  45. package/dist/speech/SpeechRuntime.d.ts +23 -1
  46. package/dist/speech/SpeechRuntime.d.ts.map +1 -1
  47. package/dist/speech/SpeechRuntime.js +82 -8
  48. package/dist/speech/SpeechRuntime.js.map +1 -1
  49. package/dist/speech/index.d.ts +6 -0
  50. package/dist/speech/index.d.ts.map +1 -1
  51. package/dist/speech/index.js +6 -0
  52. package/dist/speech/index.js.map +1 -1
  53. package/dist/speech/providerCatalog.d.ts.map +1 -1
  54. package/dist/speech/providerCatalog.js +15 -1
  55. package/dist/speech/providerCatalog.js.map +1 -1
  56. package/dist/speech/providers/AssemblyAISTTProvider.d.ts +49 -0
  57. package/dist/speech/providers/AssemblyAISTTProvider.d.ts.map +1 -0
  58. package/dist/speech/providers/AssemblyAISTTProvider.js +151 -0
  59. package/dist/speech/providers/AssemblyAISTTProvider.js.map +1 -0
  60. package/dist/speech/providers/AzureSpeechSTTProvider.d.ts +48 -0
  61. package/dist/speech/providers/AzureSpeechSTTProvider.d.ts.map +1 -0
  62. package/dist/speech/providers/AzureSpeechSTTProvider.js +90 -0
  63. package/dist/speech/providers/AzureSpeechSTTProvider.js.map +1 -0
  64. package/dist/speech/providers/AzureSpeechTTSProvider.d.ts +60 -0
  65. package/dist/speech/providers/AzureSpeechTTSProvider.d.ts.map +1 -0
  66. package/dist/speech/providers/AzureSpeechTTSProvider.js +127 -0
  67. package/dist/speech/providers/AzureSpeechTTSProvider.js.map +1 -0
  68. package/dist/speech/providers/DeepgramBatchSTTProvider.d.ts +55 -0
  69. package/dist/speech/providers/DeepgramBatchSTTProvider.d.ts.map +1 -0
  70. package/dist/speech/providers/DeepgramBatchSTTProvider.js +102 -0
  71. package/dist/speech/providers/DeepgramBatchSTTProvider.js.map +1 -0
  72. package/dist/speech/types.d.ts +35 -0
  73. package/dist/speech/types.d.ts.map +1 -1
  74. package/dist/voice/CallManager.d.ts +1 -1
  75. package/dist/voice/CallManager.d.ts.map +1 -1
  76. package/dist/voice/CallManager.js +9 -0
  77. package/dist/voice/CallManager.js.map +1 -1
  78. package/dist/voice/MediaStreamParser.d.ts +83 -0
  79. package/dist/voice/MediaStreamParser.d.ts.map +1 -0
  80. package/dist/voice/MediaStreamParser.js +2 -0
  81. package/dist/voice/MediaStreamParser.js.map +1 -0
  82. package/dist/voice/TelephonyStreamTransport.d.ts +112 -0
  83. package/dist/voice/TelephonyStreamTransport.d.ts.map +1 -0
  84. package/dist/voice/TelephonyStreamTransport.js +208 -0
  85. package/dist/voice/TelephonyStreamTransport.js.map +1 -0
  86. package/dist/voice/index.d.ts +10 -0
  87. package/dist/voice/index.d.ts.map +1 -1
  88. package/dist/voice/index.js +11 -0
  89. package/dist/voice/index.js.map +1 -1
  90. package/dist/voice/parsers/PlivoMediaStreamParser.d.ts +43 -0
  91. package/dist/voice/parsers/PlivoMediaStreamParser.d.ts.map +1 -0
  92. package/dist/voice/parsers/PlivoMediaStreamParser.js +92 -0
  93. package/dist/voice/parsers/PlivoMediaStreamParser.js.map +1 -0
  94. package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts +51 -0
  95. package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts.map +1 -0
  96. package/dist/voice/parsers/TelnyxMediaStreamParser.js +103 -0
  97. package/dist/voice/parsers/TelnyxMediaStreamParser.js.map +1 -0
  98. package/dist/voice/parsers/TwilioMediaStreamParser.d.ts +50 -0
  99. package/dist/voice/parsers/TwilioMediaStreamParser.d.ts.map +1 -0
  100. package/dist/voice/parsers/TwilioMediaStreamParser.js +144 -0
  101. package/dist/voice/parsers/TwilioMediaStreamParser.js.map +1 -0
  102. package/dist/voice/providers/plivo.d.ts +77 -0
  103. package/dist/voice/providers/plivo.d.ts.map +1 -0
  104. package/dist/voice/providers/plivo.js +180 -0
  105. package/dist/voice/providers/plivo.js.map +1 -0
  106. package/dist/voice/providers/telnyx.d.ts +93 -0
  107. package/dist/voice/providers/telnyx.d.ts.map +1 -0
  108. package/dist/voice/providers/telnyx.js +193 -0
  109. package/dist/voice/providers/telnyx.js.map +1 -0
  110. package/dist/voice/providers/twilio.d.ts +79 -0
  111. package/dist/voice/providers/twilio.d.ts.map +1 -0
  112. package/dist/voice/providers/twilio.js +191 -0
  113. package/dist/voice/providers/twilio.js.map +1 -0
  114. package/dist/voice/twiml.d.ts +69 -0
  115. package/dist/voice/twiml.d.ts.map +1 -0
  116. package/dist/voice/twiml.js +92 -0
  117. package/dist/voice/twiml.js.map +1 -0
  118. package/dist/voice/types.d.ts +9 -1
  119. package/dist/voice/types.d.ts.map +1 -1
  120. package/dist/voice-pipeline/AcousticEndpointDetector.d.ts +90 -0
  121. package/dist/voice-pipeline/AcousticEndpointDetector.d.ts.map +1 -0
  122. package/dist/voice-pipeline/AcousticEndpointDetector.js +123 -0
  123. package/dist/voice-pipeline/AcousticEndpointDetector.js.map +1 -0
  124. package/dist/voice-pipeline/HardCutBargeinHandler.d.ts +67 -0
  125. package/dist/voice-pipeline/HardCutBargeinHandler.d.ts.map +1 -0
  126. package/dist/voice-pipeline/HardCutBargeinHandler.js +55 -0
  127. package/dist/voice-pipeline/HardCutBargeinHandler.js.map +1 -0
  128. package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts +128 -0
  129. package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts.map +1 -0
  130. package/dist/voice-pipeline/HeuristicEndpointDetector.js +240 -0
  131. package/dist/voice-pipeline/HeuristicEndpointDetector.js.map +1 -0
  132. package/dist/voice-pipeline/SoftFadeBargeinHandler.d.ts +96 -0
  133. package/dist/voice-pipeline/SoftFadeBargeinHandler.d.ts.map +1 -0
  134. package/dist/voice-pipeline/SoftFadeBargeinHandler.js +69 -0
  135. package/dist/voice-pipeline/SoftFadeBargeinHandler.js.map +1 -0
  136. package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts +122 -0
  137. package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts.map +1 -0
  138. package/dist/voice-pipeline/VoicePipelineOrchestrator.js +317 -0
  139. package/dist/voice-pipeline/VoicePipelineOrchestrator.js.map +1 -0
  140. package/dist/voice-pipeline/WebSocketStreamTransport.d.ts +148 -0
  141. package/dist/voice-pipeline/WebSocketStreamTransport.d.ts.map +1 -0
  142. package/dist/voice-pipeline/WebSocketStreamTransport.js +207 -0
  143. package/dist/voice-pipeline/WebSocketStreamTransport.js.map +1 -0
  144. package/dist/voice-pipeline/index.d.ts +13 -0
  145. package/dist/voice-pipeline/index.d.ts.map +1 -0
  146. package/dist/voice-pipeline/index.js +13 -0
  147. package/dist/voice-pipeline/index.js.map +1 -0
  148. package/dist/voice-pipeline/types.d.ts +905 -0
  149. package/dist/voice-pipeline/types.d.ts.map +1 -0
  150. package/dist/voice-pipeline/types.js +23 -0
  151. package/dist/voice-pipeline/types.js.map +1 -0
  152. package/package.json +6 -1
@@ -0,0 +1,191 @@
1
+ /**
2
+ * @fileoverview Twilio telephony provider for AgentOS voice calls.
3
+ *
4
+ * Implements {@link IVoiceCallProvider} using the Twilio REST API v2010-04-01.
5
+ * Webhook verification uses HMAC-SHA1 per Twilio's security documentation.
6
+ *
7
+ * @module @framers/agentos/voice/providers/twilio
8
+ */
9
+ import { createHmac } from 'node:crypto';
10
+ import { randomUUID } from 'node:crypto';
11
+ // ============================================================================
12
+ // TwilioVoiceProvider
13
+ // ============================================================================
14
+ /**
15
+ * Twilio voice call provider.
16
+ *
17
+ * Uses the Twilio REST API 2010-04-01 for outbound call control and
18
+ * HMAC-SHA1 for inbound webhook signature verification.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const provider = new TwilioVoiceProvider({
23
+ * accountSid: process.env.TWILIO_ACCOUNT_SID!,
24
+ * authToken: process.env.TWILIO_AUTH_TOKEN!,
25
+ * });
26
+ * ```
27
+ */
28
+ export class TwilioVoiceProvider {
29
+ constructor(config) {
30
+ this.name = 'twilio';
31
+ this.config = config;
32
+ this.baseUrl = 'https://api.twilio.com/2010-04-01';
33
+ this.authHeader =
34
+ 'Basic ' +
35
+ Buffer.from(`${config.accountSid}:${config.authToken}`).toString('base64');
36
+ this.fetch = config.fetchImpl ?? globalThis.fetch;
37
+ }
38
+ // ── Webhook ───────────────────────────────────────────────────────────────
39
+ /**
40
+ * Verify an incoming Twilio webhook request using HMAC-SHA1.
41
+ *
42
+ * Twilio constructs the signed data by appending all POST params (sorted
43
+ * alphabetically) as key+value pairs directly to the full request URL.
44
+ */
45
+ verifyWebhook(ctx) {
46
+ const signature = ctx.headers['x-twilio-signature'];
47
+ if (!signature || Array.isArray(signature)) {
48
+ return { valid: false, error: 'Missing x-twilio-signature header' };
49
+ }
50
+ // Build the signed data string
51
+ const bodyParams = new URLSearchParams(ctx.body.toString());
52
+ const sorted = [...bodyParams.entries()].sort(([a], [b]) => a.localeCompare(b));
53
+ let data = ctx.url;
54
+ for (const [key, value] of sorted) {
55
+ data += key + value;
56
+ }
57
+ const expected = createHmac('sha1', this.config.authToken)
58
+ .update(data)
59
+ .digest('base64');
60
+ const valid = expected === signature;
61
+ return {
62
+ valid,
63
+ ...(valid ? {} : { error: 'Signature mismatch' }),
64
+ };
65
+ }
66
+ /**
67
+ * Parse a Twilio webhook body into normalized {@link NormalizedCallEvent}s.
68
+ *
69
+ * Handles call status transitions (ringing, in-progress, completed, failed,
70
+ * busy, no-answer, canceled) and DTMF input.
71
+ */
72
+ parseWebhookEvent(ctx) {
73
+ const params = new URLSearchParams(ctx.body.toString());
74
+ const callSid = params.get('CallSid') ?? '';
75
+ const callStatus = params.get('CallStatus') ?? '';
76
+ const digits = params.get('Digits');
77
+ const timestamp = Date.now();
78
+ const events = [];
79
+ /** Helper: shared base fields. */
80
+ const base = () => ({
81
+ eventId: randomUUID(),
82
+ providerCallId: callSid,
83
+ timestamp,
84
+ });
85
+ switch (callStatus) {
86
+ case 'ringing':
87
+ events.push({ ...base(), kind: 'call-ringing' });
88
+ break;
89
+ case 'in-progress':
90
+ events.push({ ...base(), kind: 'call-answered' });
91
+ break;
92
+ case 'completed':
93
+ events.push({ ...base(), kind: 'call-completed' });
94
+ break;
95
+ case 'failed':
96
+ events.push({ ...base(), kind: 'call-failed' });
97
+ break;
98
+ case 'busy':
99
+ events.push({ ...base(), kind: 'call-busy' });
100
+ break;
101
+ case 'no-answer':
102
+ events.push({ ...base(), kind: 'call-no-answer' });
103
+ break;
104
+ case 'canceled':
105
+ events.push({ ...base(), kind: 'call-hangup-user' });
106
+ break;
107
+ default:
108
+ // initiated / queued / etc. — no normalized event emitted
109
+ break;
110
+ }
111
+ // DTMF digit input
112
+ if (digits != null && digits !== '') {
113
+ events.push({
114
+ ...base(),
115
+ kind: 'call-dtmf',
116
+ digit: digits,
117
+ });
118
+ }
119
+ return { events };
120
+ }
121
+ // ── Call Control ──────────────────────────────────────────────────────────
122
+ /**
123
+ * Initiate an outbound call via the Twilio Calls API.
124
+ *
125
+ * Posts to `/Accounts/{accountSid}/Calls.json` with form-encoded body.
126
+ * All four status callback events (initiated, ringing, answered, completed)
127
+ * are requested.
128
+ */
129
+ async initiateCall(input) {
130
+ const url = `${this.baseUrl}/Accounts/${this.config.accountSid}/Calls.json`;
131
+ const body = [
132
+ `To=${encodeURIComponent(input.toNumber)}`,
133
+ `From=${encodeURIComponent(input.fromNumber)}`,
134
+ `Url=${encodeURIComponent(input.webhookUrl)}`,
135
+ `StatusCallback=${encodeURIComponent(input.statusCallbackUrl ?? '')}`,
136
+ `StatusCallbackEvent=initiated`,
137
+ `StatusCallbackEvent=ringing`,
138
+ `StatusCallbackEvent=answered`,
139
+ `StatusCallbackEvent=completed`,
140
+ ].join('&');
141
+ const response = await this.fetch(url, {
142
+ method: 'POST',
143
+ headers: {
144
+ Authorization: this.authHeader,
145
+ 'Content-Type': 'application/x-www-form-urlencoded',
146
+ },
147
+ body,
148
+ });
149
+ if (!response.ok) {
150
+ const text = await response.text().catch(() => String(response.status));
151
+ return { providerCallId: '', success: false, error: `Twilio error ${response.status}: ${text}` };
152
+ }
153
+ const data = (await response.json());
154
+ return { providerCallId: data.sid, success: true };
155
+ }
156
+ /**
157
+ * Hang up an active call by posting `Status=completed`.
158
+ */
159
+ async hangupCall(input) {
160
+ const url = `${this.baseUrl}/Accounts/${this.config.accountSid}/Calls/${input.providerCallId}.json`;
161
+ await this.fetch(url, {
162
+ method: 'POST',
163
+ headers: {
164
+ Authorization: this.authHeader,
165
+ 'Content-Type': 'application/x-www-form-urlencoded',
166
+ },
167
+ body: 'Status=completed',
168
+ });
169
+ }
170
+ /**
171
+ * Inject TTS into a live call using a TwiML `<Say>` verb.
172
+ *
173
+ * Sends a `Twiml` parameter containing a minimal `<Response><Say>` document.
174
+ * The optional `voice` attribute maps to Twilio's built-in voice names
175
+ * (e.g., `alice`, `Polly.Joanna`).
176
+ */
177
+ async playTts(input) {
178
+ const url = `${this.baseUrl}/Accounts/${this.config.accountSid}/Calls/${input.providerCallId}.json`;
179
+ const voiceAttr = input.voice ? ` voice="${input.voice}"` : '';
180
+ const twiml = `<Response><Say${voiceAttr}>${input.text}</Say></Response>`;
181
+ await this.fetch(url, {
182
+ method: 'POST',
183
+ headers: {
184
+ Authorization: this.authHeader,
185
+ 'Content-Type': 'application/x-www-form-urlencoded',
186
+ },
187
+ body: `Twiml=${encodeURIComponent(twiml)}`,
188
+ });
189
+ }
190
+ }
191
+ //# sourceMappingURL=twilio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twilio.js","sourceRoot":"","sources":["../../../src/voice/providers/twilio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @fileoverview TwiML and XML generation helpers for telephony providers.
3
+ *
4
+ * Generates provider-specific XML/TwiML response payloads for Twilio, Telnyx,
5
+ * and Plivo. All text content and attribute values are XML-escaped to prevent
6
+ * injection or malformed markup.
7
+ *
8
+ * @module @framers/agentos/voice/twiml
9
+ */
10
+ /**
11
+ * Generate TwiML for Twilio conversation mode using a bidirectional media stream.
12
+ *
13
+ * The returned markup instructs Twilio to open a WebSocket to `streamUrl` and
14
+ * stream audio in both directions for the duration of the call.
15
+ *
16
+ * @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss://…/stream`).
17
+ * @param token - Optional bearer token appended as a `?token=` query parameter.
18
+ * @returns A complete TwiML XML document string.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * res.type('text/xml').send(twilioConversationTwiml('wss://api.example.com/call', jwtToken));
23
+ * ```
24
+ */
25
+ export declare function twilioConversationTwiml(streamUrl: string, token?: string): string;
26
+ /**
27
+ * Generate TwiML for Twilio notify mode — synthesise `text` over the call then hang up.
28
+ *
29
+ * Useful for delivering one-shot announcements (e.g. voicemail greetings, error
30
+ * messages) without establishing a full media stream.
31
+ *
32
+ * @param text - The message to speak to the caller.
33
+ * @param voice - Optional Twilio voice name (e.g. `'Polly.Joanna'`, `'alice'`).
34
+ * @returns A complete TwiML XML document string.
35
+ */
36
+ export declare function twilioNotifyTwiml(text: string, voice?: string): string;
37
+ /**
38
+ * Generate a Telnyx streaming XML response.
39
+ *
40
+ * Telnyx primarily uses a REST API for call control, but this helper produces
41
+ * an XML acknowledgment document wrapping the stream URL for webhook responses
42
+ * that require XML.
43
+ *
44
+ * @param streamUrl - WebSocket URL Telnyx should stream audio to.
45
+ * @returns A complete XML document string.
46
+ */
47
+ export declare function telnyxStreamXml(streamUrl: string): string;
48
+ /**
49
+ * Generate Plivo bidirectional streaming XML.
50
+ *
51
+ * Instructs Plivo to open a bidirectional WebSocket stream and keep the call
52
+ * alive for the duration of the stream session.
53
+ *
54
+ * @param streamUrl - WebSocket URL Plivo should connect to.
55
+ * @returns A complete Plivo XML document string.
56
+ */
57
+ export declare function plivoStreamXml(streamUrl: string): string;
58
+ /**
59
+ * Generate Plivo speak + hangup XML.
60
+ *
61
+ * Synthesises `text` to the caller using Plivo's TTS engine and immediately
62
+ * hangs up after playback completes.
63
+ *
64
+ * @param text - The message to speak to the caller.
65
+ * @param voice - Optional Plivo voice name (e.g. `'WOMAN'`, `'Polly.Joanna'`).
66
+ * @returns A complete Plivo XML document string.
67
+ */
68
+ export declare function plivoNotifyXml(text: string, voice?: string): string;
69
+ //# sourceMappingURL=twiml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twiml.d.ts","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGtE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGnE"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @fileoverview TwiML and XML generation helpers for telephony providers.
3
+ *
4
+ * Generates provider-specific XML/TwiML response payloads for Twilio, Telnyx,
5
+ * and Plivo. All text content and attribute values are XML-escaped to prevent
6
+ * injection or malformed markup.
7
+ *
8
+ * @module @framers/agentos/voice/twiml
9
+ */
10
+ import { escapeXml } from './telephony-audio.js';
11
+ // ============================================================================
12
+ // Twilio TwiML
13
+ // ============================================================================
14
+ /**
15
+ * Generate TwiML for Twilio conversation mode using a bidirectional media stream.
16
+ *
17
+ * The returned markup instructs Twilio to open a WebSocket to `streamUrl` and
18
+ * stream audio in both directions for the duration of the call.
19
+ *
20
+ * @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss://…/stream`).
21
+ * @param token - Optional bearer token appended as a `?token=` query parameter.
22
+ * @returns A complete TwiML XML document string.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * res.type('text/xml').send(twilioConversationTwiml('wss://api.example.com/call', jwtToken));
27
+ * ```
28
+ */
29
+ export function twilioConversationTwiml(streamUrl, token) {
30
+ const url = token ? `${streamUrl}?token=${token}` : streamUrl;
31
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Connect><Stream url="${escapeXml(url)}" /></Connect></Response>`;
32
+ }
33
+ /**
34
+ * Generate TwiML for Twilio notify mode — synthesise `text` over the call then hang up.
35
+ *
36
+ * Useful for delivering one-shot announcements (e.g. voicemail greetings, error
37
+ * messages) without establishing a full media stream.
38
+ *
39
+ * @param text - The message to speak to the caller.
40
+ * @param voice - Optional Twilio voice name (e.g. `'Polly.Joanna'`, `'alice'`).
41
+ * @returns A complete TwiML XML document string.
42
+ */
43
+ export function twilioNotifyTwiml(text, voice) {
44
+ const voiceAttr = voice ? ` voice="${escapeXml(voice)}"` : '';
45
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Say${voiceAttr}>${escapeXml(text)}</Say><Hangup/></Response>`;
46
+ }
47
+ // ============================================================================
48
+ // Telnyx XML
49
+ // ============================================================================
50
+ /**
51
+ * Generate a Telnyx streaming XML response.
52
+ *
53
+ * Telnyx primarily uses a REST API for call control, but this helper produces
54
+ * an XML acknowledgment document wrapping the stream URL for webhook responses
55
+ * that require XML.
56
+ *
57
+ * @param streamUrl - WebSocket URL Telnyx should stream audio to.
58
+ * @returns A complete XML document string.
59
+ */
60
+ export function telnyxStreamXml(streamUrl) {
61
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream url="${escapeXml(streamUrl)}" /></Response>`;
62
+ }
63
+ // ============================================================================
64
+ // Plivo XML
65
+ // ============================================================================
66
+ /**
67
+ * Generate Plivo bidirectional streaming XML.
68
+ *
69
+ * Instructs Plivo to open a bidirectional WebSocket stream and keep the call
70
+ * alive for the duration of the stream session.
71
+ *
72
+ * @param streamUrl - WebSocket URL Plivo should connect to.
73
+ * @returns A complete Plivo XML document string.
74
+ */
75
+ export function plivoStreamXml(streamUrl) {
76
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream bidirectional="true" keepCallAlive="true">${escapeXml(streamUrl)}</Stream></Response>`;
77
+ }
78
+ /**
79
+ * Generate Plivo speak + hangup XML.
80
+ *
81
+ * Synthesises `text` to the caller using Plivo's TTS engine and immediately
82
+ * hangs up after playback completes.
83
+ *
84
+ * @param text - The message to speak to the caller.
85
+ * @param voice - Optional Plivo voice name (e.g. `'WOMAN'`, `'Polly.Joanna'`).
86
+ * @returns A complete Plivo XML document string.
87
+ */
88
+ export function plivoNotifyXml(text, voice) {
89
+ const voiceAttr = voice ? ` voice="${escapeXml(voice)}"` : '';
90
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Speak${voiceAttr}>${escapeXml(text)}</Speak><Hangup/></Response>`;
91
+ }
92
+ //# sourceMappingURL=twiml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twiml.js","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB,EAAE,KAAc;IACvE,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,OAAO,2EAA2E,SAAS,CAAC,GAAG,CAAC,2BAA2B,CAAC;AAC9H,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAc;IAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,yDAAyD,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC;AAC3H,CAAC;AAED,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,OAAO,kEAAkE,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC;AACjH,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,uGAAuG,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC;AAC3J,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAc;IACzD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,2DAA2D,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,8BAA8B,CAAC;AAC/H,CAAC"}
@@ -99,7 +99,7 @@ export interface CallRecord {
99
99
  * Normalized webhook event from any telephony provider.
100
100
  * Uses a discriminated union on the `kind` field.
101
101
  */
102
- export type NormalizedCallEvent = NormalizedCallRinging | NormalizedCallAnswered | NormalizedCallCompleted | NormalizedCallFailed | NormalizedCallBusy | NormalizedCallNoAnswer | NormalizedCallVoicemail | NormalizedCallHangupUser | NormalizedCallError | NormalizedTranscript | NormalizedSpeechStart | NormalizedMediaStreamConnected;
102
+ export type NormalizedCallEvent = NormalizedCallRinging | NormalizedCallAnswered | NormalizedCallCompleted | NormalizedCallFailed | NormalizedCallBusy | NormalizedCallNoAnswer | NormalizedCallVoicemail | NormalizedCallHangupUser | NormalizedCallError | NormalizedTranscript | NormalizedSpeechStart | NormalizedMediaStreamConnected | NormalizedDtmfReceived;
103
103
  interface NormalizedEventBase {
104
104
  /** Provider-assigned event ID for idempotency. */
105
105
  eventId: string;
@@ -150,6 +150,14 @@ export interface NormalizedMediaStreamConnected extends NormalizedEventBase {
150
150
  kind: 'media-stream-connected';
151
151
  streamSid: string;
152
152
  }
153
+ /** DTMF digit received during a call. */
154
+ export interface NormalizedDtmfReceived extends NormalizedEventBase {
155
+ kind: 'call-dtmf';
156
+ /** The digit pressed: '0'-'9', '*', '#' */
157
+ digit: string;
158
+ /** How long the key was pressed (ms), if available from provider */
159
+ durationMs?: number;
160
+ }
153
161
  /** Raw webhook context passed to provider verification. */
154
162
  export interface WebhookContext {
155
163
  /** HTTP method (usually POST). */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @module voice-pipeline/AcousticEndpointDetector
3
+ *
4
+ * Acoustic-only endpoint detector that wraps {@link SilenceDetector} to convert
5
+ * VAD events into turn-completion decisions. It ignores transcript content entirely
6
+ * and relies solely on the duration of post-speech silence to decide when the user
7
+ * has finished speaking.
8
+ *
9
+ * Emits:
10
+ * - `'turn_complete'` ({@link TurnCompleteEvent}) — silence exceeded the configured
11
+ * `utteranceEndThresholdMs` after the most recent `speech_end` VAD event.
12
+ * - `'speech_start'` () — re-emitted when a `speech_start` VAD event is received.
13
+ */
14
+ import { EventEmitter } from 'node:events';
15
+ import type { IEndpointDetector, VadEvent, TranscriptEvent } from './types.js';
16
+ /**
17
+ * Constructor options for {@link AcousticEndpointDetector}.
18
+ */
19
+ export interface AcousticEndpointDetectorConfig {
20
+ /**
21
+ * Silence duration after speech (ms) that triggers a "significant pause"
22
+ * notification on the underlying {@link SilenceDetector}. Does not directly
23
+ * cause `turn_complete` to fire, but is forwarded to the SilenceDetector.
24
+ * @defaultValue 1500
25
+ */
26
+ significantPauseThresholdMs?: number;
27
+ /**
28
+ * Silence duration after speech (ms) that triggers `turn_complete` with
29
+ * `reason: 'silence_timeout'`.
30
+ * @defaultValue 3000
31
+ */
32
+ utteranceEndThresholdMs?: number;
33
+ }
34
+ /**
35
+ * Purely acoustic endpoint detector.
36
+ *
37
+ * Delegates silence timing to a {@link SilenceDetector} instance. VAD
38
+ * `speech_end` events start the silence clock; `speech_start` events cancel
39
+ * any pending turn-complete emission. Transcript content is completely ignored.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * const detector = new AcousticEndpointDetector({ utteranceEndThresholdMs: 2000 });
44
+ * detector.on('turn_complete', (event) => console.log('Turn done:', event));
45
+ * detector.pushVadEvent({ type: 'speech_end', timestamp: Date.now() });
46
+ * ```
47
+ */
48
+ export declare class AcousticEndpointDetector extends EventEmitter implements IEndpointDetector {
49
+ /** @inheritdoc */
50
+ readonly mode: "acoustic";
51
+ /** Underlying silence-duration tracker. */
52
+ private readonly silenceDetector;
53
+ /**
54
+ * Timestamp (ms) when the current speech segment began. Tracked so that
55
+ * `durationMs` in the emitted {@link TurnCompleteEvent} can be computed.
56
+ */
57
+ private speechStartTimeMs;
58
+ /**
59
+ * Timestamp (ms) when the most recent `speech_end` VAD event was received.
60
+ * Used to calculate `durationMs` for the turn-complete event.
61
+ */
62
+ private speechEndTimeMs;
63
+ /**
64
+ * Creates a new AcousticEndpointDetector.
65
+ *
66
+ * @param config - Optional silence-threshold overrides.
67
+ */
68
+ constructor(config?: AcousticEndpointDetectorConfig);
69
+ /**
70
+ * Converts a {@link VadEvent} into the SilenceDetector's expected API calls.
71
+ *
72
+ * - `speech_start` — resets silence state and re-emits `'speech_start'` on self.
73
+ * - `speech_end` — starts the silence clock.
74
+ * - `silence` — treated as ongoing non-speech frames.
75
+ *
76
+ * @param event - Incoming VAD event.
77
+ */
78
+ pushVadEvent(event: VadEvent): void;
79
+ /**
80
+ * No-op — this detector is purely acoustic and does not use transcript content.
81
+ *
82
+ * @param _event - Ignored transcript event.
83
+ */
84
+ pushTranscript(_event: TranscriptEvent): void;
85
+ /**
86
+ * Resets all internal state and timers. Call at the start of each new turn.
87
+ */
88
+ reset(): void;
89
+ }
90
+ //# sourceMappingURL=AcousticEndpointDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcousticEndpointDetector.d.ts","sourceRoot":"","sources":["../../src/voice-pipeline/AcousticEndpointDetector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,iBAAiB,EACjB,QAAQ,EACR,eAAe,EAEhB,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAMD;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAyB,SAAQ,YAAa,YAAW,iBAAiB;IACrF,kBAAkB;IAClB,SAAgB,IAAI,EAAG,UAAU,CAAU;IAE3C,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAElD;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAuB;IAEhD;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAuB;IAI9C;;;;OAIG;gBACS,MAAM,GAAE,8BAAmC;IAgCvD;;;;;;;;OAQG;IACI,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAyB1C;;;;OAIG;IACI,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAIpD;;OAEG;IACI,KAAK,IAAI,IAAI;CAKrB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @module voice-pipeline/AcousticEndpointDetector
3
+ *
4
+ * Acoustic-only endpoint detector that wraps {@link SilenceDetector} to convert
5
+ * VAD events into turn-completion decisions. It ignores transcript content entirely
6
+ * and relies solely on the duration of post-speech silence to decide when the user
7
+ * has finished speaking.
8
+ *
9
+ * Emits:
10
+ * - `'turn_complete'` ({@link TurnCompleteEvent}) — silence exceeded the configured
11
+ * `utteranceEndThresholdMs` after the most recent `speech_end` VAD event.
12
+ * - `'speech_start'` () — re-emitted when a `speech_start` VAD event is received.
13
+ */
14
+ import { EventEmitter } from 'node:events';
15
+ import { SilenceDetector } from '../core/audio/SilenceDetector.js';
16
+ // ---------------------------------------------------------------------------
17
+ // Implementation
18
+ // ---------------------------------------------------------------------------
19
+ /**
20
+ * Purely acoustic endpoint detector.
21
+ *
22
+ * Delegates silence timing to a {@link SilenceDetector} instance. VAD
23
+ * `speech_end` events start the silence clock; `speech_start` events cancel
24
+ * any pending turn-complete emission. Transcript content is completely ignored.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const detector = new AcousticEndpointDetector({ utteranceEndThresholdMs: 2000 });
29
+ * detector.on('turn_complete', (event) => console.log('Turn done:', event));
30
+ * detector.pushVadEvent({ type: 'speech_end', timestamp: Date.now() });
31
+ * ```
32
+ */
33
+ export class AcousticEndpointDetector extends EventEmitter {
34
+ // ---------------------------------------------------------------------------
35
+ /**
36
+ * Creates a new AcousticEndpointDetector.
37
+ *
38
+ * @param config - Optional silence-threshold overrides.
39
+ */
40
+ constructor(config = {}) {
41
+ super();
42
+ /** @inheritdoc */
43
+ this.mode = 'acoustic';
44
+ /**
45
+ * Timestamp (ms) when the current speech segment began. Tracked so that
46
+ * `durationMs` in the emitted {@link TurnCompleteEvent} can be computed.
47
+ */
48
+ this.speechStartTimeMs = null;
49
+ /**
50
+ * Timestamp (ms) when the most recent `speech_end` VAD event was received.
51
+ * Used to calculate `durationMs` for the turn-complete event.
52
+ */
53
+ this.speechEndTimeMs = null;
54
+ const sdConfig = {
55
+ significantPauseThresholdMs: config.significantPauseThresholdMs ?? 1500,
56
+ utteranceEndThresholdMs: config.utteranceEndThresholdMs ?? 3000,
57
+ };
58
+ this.silenceDetector = new SilenceDetector(sdConfig);
59
+ // When SilenceDetector decides the utterance has ended, fire turn_complete.
60
+ this.silenceDetector.on('utterance_end_detected', (_silenceDurationMs) => {
61
+ const durationMs = this.speechStartTimeMs !== null && this.speechEndTimeMs !== null
62
+ ? this.speechEndTimeMs - this.speechStartTimeMs
63
+ : 0;
64
+ const event = {
65
+ transcript: '', // Acoustic mode has no transcript access
66
+ confidence: 0,
67
+ durationMs,
68
+ reason: 'silence_timeout',
69
+ };
70
+ this.emit('turn_complete', event);
71
+ });
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // IEndpointDetector
75
+ // ---------------------------------------------------------------------------
76
+ /**
77
+ * Converts a {@link VadEvent} into the SilenceDetector's expected API calls.
78
+ *
79
+ * - `speech_start` — resets silence state and re-emits `'speech_start'` on self.
80
+ * - `speech_end` — starts the silence clock.
81
+ * - `silence` — treated as ongoing non-speech frames.
82
+ *
83
+ * @param event - Incoming VAD event.
84
+ */
85
+ pushVadEvent(event) {
86
+ // Minimal VADResult stub — SilenceDetector's public methods only use it as
87
+ // a pass-through parameter and don't inspect its contents.
88
+ const vadResultStub = { timestamp: event.timestamp };
89
+ switch (event.type) {
90
+ case 'speech_start':
91
+ this.speechStartTimeMs = event.timestamp;
92
+ this.speechEndTimeMs = null;
93
+ this.silenceDetector.handleSpeechStart(vadResultStub);
94
+ this.emit('speech_start');
95
+ break;
96
+ case 'speech_end':
97
+ this.speechEndTimeMs = event.timestamp;
98
+ this.silenceDetector.handleSpeechEnd(vadResultStub, 0);
99
+ break;
100
+ case 'silence':
101
+ // Periodic silence heartbeat — pass as a non-speech frame.
102
+ this.silenceDetector.handleNoVoiceActivity(vadResultStub);
103
+ break;
104
+ }
105
+ }
106
+ /**
107
+ * No-op — this detector is purely acoustic and does not use transcript content.
108
+ *
109
+ * @param _event - Ignored transcript event.
110
+ */
111
+ pushTranscript(_event) {
112
+ // Intentional no-op: acoustic mode ignores linguistic content.
113
+ }
114
+ /**
115
+ * Resets all internal state and timers. Call at the start of each new turn.
116
+ */
117
+ reset() {
118
+ this.speechStartTimeMs = null;
119
+ this.speechEndTimeMs = null;
120
+ this.silenceDetector.reset();
121
+ }
122
+ }
123
+ //# sourceMappingURL=AcousticEndpointDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcousticEndpointDetector.js","sourceRoot":"","sources":["../../src/voice-pipeline/AcousticEndpointDetector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAA8B,MAAM,kCAAkC,CAAC;AAgC/F,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IAmBxD,8EAA8E;IAE9E;;;;OAIG;IACH,YAAY,SAAyC,EAAE;QACrD,KAAK,EAAE,CAAC;QA1BV,kBAAkB;QACF,SAAI,GAAG,UAAmB,CAAC;QAK3C;;;WAGG;QACK,sBAAiB,GAAkB,IAAI,CAAC;QAEhD;;;WAGG;QACK,oBAAe,GAAkB,IAAI,CAAC;QAY5C,MAAM,QAAQ,GAA0B;YACtC,2BAA2B,EAAE,MAAM,CAAC,2BAA2B,IAAI,IAAI;YACvE,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,IAAI,IAAI;SAChE,CAAC;QAEF,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;QAErD,4EAA4E;QAC5E,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,kBAA0B,EAAE,EAAE;YAC/E,MAAM,UAAU,GACd,IAAI,CAAC,iBAAiB,KAAK,IAAI,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;gBAC9D,CAAC,CAAC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB;gBAC/C,CAAC,CAAC,CAAC,CAAC;YAER,MAAM,KAAK,GAAsB;gBAC/B,UAAU,EAAE,EAAE,EAAI,yCAAyC;gBAC3D,UAAU,EAAE,CAAC;gBACb,UAAU;gBACV,MAAM,EAAE,iBAAiB;aAC1B,CAAC;YAEF,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,oBAAoB;IACpB,8EAA8E;IAE9E;;;;;;;;OAQG;IACI,YAAY,CAAC,KAAe;QACjC,2EAA2E;QAC3E,2DAA2D;QAC3D,MAAM,aAAa,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAW,CAAC;QAE9D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,cAAc;gBACjB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAC;gBACzC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACtD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC1B,MAAM;YAER,KAAK,YAAY;gBACf,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,SAAS,CAAC;gBACvC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;gBACvD,MAAM;YAER,KAAK,SAAS;gBACZ,2DAA2D;gBAC3D,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;gBAC1D,MAAM;QACV,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,cAAc,CAAC,MAAuB;QAC3C,+DAA+D;IACjE,CAAC;IAED;;OAEG;IACI,KAAK;QACV,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACF"}