@ariaflowagents/livekit-plugin-transport-twilio 0.9.0

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.
@@ -0,0 +1,137 @@
1
+ /**
2
+ * G.711 μ-law codec implementation for Twilio Media Streams.
3
+ *
4
+ * Twilio uses G.711 μ-law (mu-law) encoding at 8kHz.
5
+ * This codec provides bidirectional conversion between PCM Int16
6
+ * and μ-law encoded Uint8.
7
+ */
8
+ const MULAW_BIAS = 0x84;
9
+ const MULAW_CLIP = 32635;
10
+ /**
11
+ * μ-law compression table (precomputed for performance).
12
+ * Maps linear 14-bit samples to 8-bit μ-law values.
13
+ */
14
+ const MULAW_COMPRESS_TABLE = new Int8Array([
15
+ -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
16
+ -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1,
17
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19
+ -1, -1, -1, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0,
20
+ -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0,
21
+ -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0,
22
+ -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0,
23
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
26
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
27
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
28
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
29
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
30
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
31
+ ]);
32
+ /**
33
+ * μ-law expansion table (precomputed for performance).
34
+ * Maps 8-bit μ-law values to linear 16-bit PCM samples.
35
+ */
36
+ const MULAW_EXPAND_TABLE = new Int16Array([
37
+ -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
38
+ -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
39
+ -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
40
+ -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
41
+ -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
42
+ -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
43
+ -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
44
+ -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
45
+ -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
46
+ -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
47
+ -876, -844, -812, -780, -748, -716, -684, -652,
48
+ -620, -588, -556, -524, -492, -460, -428, -396,
49
+ -372, -356, -340, -324, -308, -292, -276, -260,
50
+ -244, -228, -212, -196, -180, -164, -148, -132,
51
+ -120, -112, -104, -96, -88, -80, -72, -64,
52
+ -56, -48, -40, -32, -24, -16, -8, 0,
53
+ 0, 8, 16, 24, 32, 40, 48, 56,
54
+ 64, 72, 80, 88, 96, 104, 112, 120,
55
+ 132, 148, 164, 180, 196, 212, 228, 244,
56
+ 260, 276, 292, 308, 324, 340, 356, 372,
57
+ 396, 428, 460, 492, 524, 556, 588, 620,
58
+ 652, 684, 716, 748, 780, 812, 844, 876,
59
+ 924, 988, 1052, 1116, 1180, 1244, 1308, 1372,
60
+ 1436, 1500, 1564, 1628, 1692, 1756, 1820, 1884,
61
+ 1980, 2108, 2236, 2364, 2492, 2620, 2748, 2876,
62
+ 3004, 3132, 3260, 3388, 3516, 3644, 3772, 3900,
63
+ 4092, 4348, 4604, 4860, 5116, 5372, 5628, 5884,
64
+ 6140, 6396, 6652, 6908, 7164, 7420, 7676, 7932,
65
+ 8316, 8828, 9340, 9852, 10364, 10876, 11388, 11900,
66
+ 12412, 12924, 13436, 13948, 14460, 14972, 15484, 15996,
67
+ 16764, 17788, 18812, 19836, 20860, 21884, 22908, 23932,
68
+ 24956, 25980, 27004, 28028, 29052, 30076, 31100, 32124,
69
+ ]);
70
+ /**
71
+ * Encode a PCM Int16 sample to μ-law Uint8.
72
+ *
73
+ * @param sample - 16-bit PCM sample (-32768 to 32767)
74
+ * @returns μ-law encoded byte (0-255)
75
+ */
76
+ export function mulawEncode(sample) {
77
+ // Add bias to center around zero
78
+ sample += MULAW_BIAS;
79
+ // Clip to valid range
80
+ if (sample > MULAW_CLIP)
81
+ sample = MULAW_CLIP;
82
+ if (sample < -MULAW_CLIP)
83
+ sample = -MULAW_CLIP;
84
+ // Convert to positive value
85
+ const sign = sample < 0 ? 0x80 : 0x00;
86
+ if (sign)
87
+ sample = -sample;
88
+ // Find exponent and mantissa
89
+ let exponent = 7;
90
+ for (let i = 0; i < 7; i++) {
91
+ if (sample <= (0x01 << (i + 1))) {
92
+ exponent = i;
93
+ break;
94
+ }
95
+ }
96
+ const mantissa = (sample >> (exponent + 1)) & 0x0F;
97
+ // Compress to 8-bit μ-law
98
+ const mulaw = ~(sign | (exponent << 4) | mantissa);
99
+ return mulaw & 0xFF;
100
+ }
101
+ /**
102
+ * Decode a μ-law Uint8 to PCM Int16.
103
+ *
104
+ * @param mulaw - μ-law encoded byte (0-255)
105
+ * @returns 16-bit PCM sample
106
+ */
107
+ export function mulawDecode(mulaw) {
108
+ // Expand using lookup table
109
+ return MULAW_EXPAND_TABLE[mulaw & 0xFF];
110
+ }
111
+ /**
112
+ * Encode an array of PCM samples to μ-law.
113
+ *
114
+ * @param pcm - Int16Array of PCM samples
115
+ * @returns Uint8Array of μ-law encoded bytes
116
+ */
117
+ export function mulawEncodeArray(pcm) {
118
+ const mulaw = new Uint8Array(pcm.length);
119
+ for (let i = 0; i < pcm.length; i++) {
120
+ mulaw[i] = mulawEncode(pcm[i]);
121
+ }
122
+ return mulaw;
123
+ }
124
+ /**
125
+ * Decode an array of μ-law bytes to PCM.
126
+ *
127
+ * @param mulaw - Uint8Array of μ-law encoded bytes
128
+ * @returns Int16Array of PCM samples
129
+ */
130
+ export function mulawDecodeArray(mulaw) {
131
+ const pcm = new Int16Array(mulaw.length);
132
+ for (let i = 0; i < mulaw.length; i++) {
133
+ pcm[i] = mulawDecode(mulaw[i]);
134
+ }
135
+ return pcm;
136
+ }
137
+ //# sourceMappingURL=g711.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"g711.js","sourceRoot":"","sources":["../../src/codec/g711.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB;;;GAGG;AACH,MAAM,oBAAoB,GAAG,IAAI,SAAS,CAAC;IACzC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC,EAAE,CAAC,EAA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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Twilio Media Streams Transport for AriaFlow Agents
3
+ *
4
+ * Enables AriaFlow voice agents to work with Twilio Media Streams API.
5
+ * Compatible with Cloudflare Workers, Node.js, and any WebSocket-enabled runtime.
6
+ *
7
+ * Features:
8
+ * - G.711 μ-law codec support (Twilio standard)
9
+ * - Automatic resampling (8kHz ↔ 24kHz)
10
+ * - Cloudflare Workers compatible
11
+ * - Session management integration
12
+ *
13
+ * Basic usage (Cloudflare Workers):
14
+ * ```typescript
15
+ * import { createTwilioWorker } from '@ariaflow/livekit-plugin-transport-twilio/cloudflare';
16
+ *
17
+ * export default createTwilioWorker({
18
+ * agent: () => createAriaFlowSession({...}),
19
+ * });
20
+ * ```
21
+ *
22
+ * Basic usage (Node.js/any WebSocket):
23
+ * ```typescript
24
+ * import { WebSocketServer } from 'ws';
25
+ * import { TwilioTransportAdapter } from '@ariaflow/livekit-plugin-transport-twilio';
26
+ * import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
27
+ *
28
+ * const wss = new WebSocketServer({ port: 8080 });
29
+ *
30
+ * wss.on('connection', (ws, req) => {
31
+ * const transport = new TwilioTransportAdapter({
32
+ * send: (msg) => ws.send(msg),
33
+ * });
34
+ *
35
+ * ws.on('message', (data) => {
36
+ * transport.handleMessage(data.toString());
37
+ * });
38
+ *
39
+ * const { agent, sessionOptions } = createAriaFlowSession({
40
+ * runtime: agentConfig,
41
+ * stt: new GeminiLiveSTT(),
42
+ * tts: new GeminiLiveTTS(),
43
+ * });
44
+ *
45
+ * await sessionManager.startSession(transport, agent, sessionOptions);
46
+ * });
47
+ * ```
48
+ *
49
+ * Basic usage (TwilioAgentServer):
50
+ * ```typescript
51
+ * import { TwilioAgentServer } from '@ariaflow/livekit-plugin-transport-twilio';
52
+ * import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
53
+ *
54
+ * const server = new TwilioAgentServer({ port: 8080 });
55
+ *
56
+ * server.onCall(async (callId, transport) => {
57
+ * const { agent, sessionOptions } = createAriaFlowSession({...});
58
+ * await server.startSession(callId, agent, sessionOptions);
59
+ * });
60
+ *
61
+ * await server.listen();
62
+ * ```
63
+ */
64
+ export { TwilioAgentServer } from './server.js';
65
+ export type { TwilioServerOptions } from './server.js';
66
+ export { TwilioTransportAdapter } from './transport_adapter.js';
67
+ export type { TwilioTransportOptions } from './transport_adapter.js';
68
+ export { TwilioAudioInput } from './audio_input.js';
69
+ export { TwilioAudioOutput } from './audio_output.js';
70
+ export { TwilioTextOutput } from './text_output.js';
71
+ export { parseTwilioMessage, isMediaEvent, extractMediaPayload, createClearMessage, createMarkMessage, } from './twilio_protocol.js';
72
+ export type { TwilioEvent, TwilioMediaEvent, TwilioConnectedEvent, TwilioStartEvent, TwilioStopEvent, TwilioMarkEvent, TwilioClearEvent, } from './twilio_protocol.js';
73
+ export { mulawEncodeArray, mulawDecodeArray } from '@ariaflow/livekit-plugin/codec/g711';
74
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Twilio Media Streams Transport for AriaFlow Agents
3
+ *
4
+ * Enables AriaFlow voice agents to work with Twilio Media Streams API.
5
+ * Compatible with Cloudflare Workers, Node.js, and any WebSocket-enabled runtime.
6
+ *
7
+ * Features:
8
+ * - G.711 μ-law codec support (Twilio standard)
9
+ * - Automatic resampling (8kHz ↔ 24kHz)
10
+ * - Cloudflare Workers compatible
11
+ * - Session management integration
12
+ *
13
+ * Basic usage (Cloudflare Workers):
14
+ * ```typescript
15
+ * import { createTwilioWorker } from '@ariaflow/livekit-plugin-transport-twilio/cloudflare';
16
+ *
17
+ * export default createTwilioWorker({
18
+ * agent: () => createAriaFlowSession({...}),
19
+ * });
20
+ * ```
21
+ *
22
+ * Basic usage (Node.js/any WebSocket):
23
+ * ```typescript
24
+ * import { WebSocketServer } from 'ws';
25
+ * import { TwilioTransportAdapter } from '@ariaflow/livekit-plugin-transport-twilio';
26
+ * import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
27
+ *
28
+ * const wss = new WebSocketServer({ port: 8080 });
29
+ *
30
+ * wss.on('connection', (ws, req) => {
31
+ * const transport = new TwilioTransportAdapter({
32
+ * send: (msg) => ws.send(msg),
33
+ * });
34
+ *
35
+ * ws.on('message', (data) => {
36
+ * transport.handleMessage(data.toString());
37
+ * });
38
+ *
39
+ * const { agent, sessionOptions } = createAriaFlowSession({
40
+ * runtime: agentConfig,
41
+ * stt: new GeminiLiveSTT(),
42
+ * tts: new GeminiLiveTTS(),
43
+ * });
44
+ *
45
+ * await sessionManager.startSession(transport, agent, sessionOptions);
46
+ * });
47
+ * ```
48
+ *
49
+ * Basic usage (TwilioAgentServer):
50
+ * ```typescript
51
+ * import { TwilioAgentServer } from '@ariaflow/livekit-plugin-transport-twilio';
52
+ * import { createAriaFlowSession } from '@ariaflow/livekit-plugin';
53
+ *
54
+ * const server = new TwilioAgentServer({ port: 8080 });
55
+ *
56
+ * server.onCall(async (callId, transport) => {
57
+ * const { agent, sessionOptions } = createAriaFlowSession({...});
58
+ * await server.startSession(callId, agent, sessionOptions);
59
+ * });
60
+ *
61
+ * await server.listen();
62
+ * ```
63
+ */
64
+ // Server
65
+ export { TwilioAgentServer } from './server.js';
66
+ // Core transport
67
+ export { TwilioTransportAdapter } from './transport_adapter.js';
68
+ // Audio I/O
69
+ export { TwilioAudioInput } from './audio_input.js';
70
+ export { TwilioAudioOutput } from './audio_output.js';
71
+ export { TwilioTextOutput } from './text_output.js';
72
+ // Protocol utilities
73
+ export { parseTwilioMessage, isMediaEvent, extractMediaPayload, createClearMessage, createMarkMessage, } from './twilio_protocol.js';
74
+ // Codec (re-exported from canonical source)
75
+ export { mulawEncodeArray, mulawDecodeArray } from '@ariaflow/livekit-plugin/codec/g711';
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,iBAAiB;AACjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,qBAAqB;AACrB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAW9B,4CAA4C;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { SessionManager, type AriaFlowVoiceSession } from '@ariaflow/livekit-plugin';
2
+ import type { voice } from '@livekit/agents';
3
+ import { TwilioTransportAdapter } from './transport_adapter.js';
4
+ /**
5
+ * Options for TwilioAgentServer
6
+ */
7
+ export interface TwilioServerOptions {
8
+ port?: number;
9
+ host?: string;
10
+ }
11
+ /**
12
+ * A WebSocket server that accepts Twilio Media Streams connections and creates agent sessions.
13
+ *
14
+ * Usage:
15
+ * const server = new TwilioAgentServer({ port: 8080 });
16
+ *
17
+ * server.onCall(async (callId, transport) => {
18
+ * const voiceSession = new AriaFlowVoiceSession({
19
+ * runtime: runtime,
20
+ * stt: new GeminiLiveSTT(),
21
+ * tts: new GeminiLiveTTS(),
22
+ * });
23
+ * await server.startSession(callId, voiceSession);
24
+ * });
25
+ *
26
+ * await server.listen();
27
+ */
28
+ export declare class TwilioAgentServer {
29
+ private options;
30
+ private wss;
31
+ private sessionManager;
32
+ private callHandler;
33
+ private callIdCounter;
34
+ constructor(options?: TwilioServerOptions);
35
+ onCall(handler: (callId: string, transport: TwilioTransportAdapter) => void | Promise<void>): void;
36
+ startSession(callId: string, voiceSession: AriaFlowVoiceSession): Promise<voice.AgentSession>;
37
+ private transports;
38
+ listen(): Promise<void>;
39
+ get sessions(): SessionManager;
40
+ close(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,iBAAiB;IAQhB,OAAO,CAAC,OAAO;IAP3B,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,WAAW,CAEH;IAChB,OAAO,CAAC,aAAa,CAAK;gBAEN,OAAO,GAAE,mBAAwB;IAErD,MAAM,CACJ,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnF,IAAI;IAID,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,oBAAoB,GACjC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;IAQ9B,OAAO,CAAC,UAAU,CAA6C;IAEzD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoF7B,IAAI,QAAQ,IAAI,cAAc,CAE7B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7B"}
package/dist/server.js ADDED
@@ -0,0 +1,125 @@
1
+ import { WebSocketServer as WSServer } from 'ws';
2
+ import { SessionManager } from '@ariaflow/livekit-plugin';
3
+ import { TwilioTransportAdapter } from './transport_adapter.js';
4
+ /**
5
+ * A WebSocket server that accepts Twilio Media Streams connections and creates agent sessions.
6
+ *
7
+ * Usage:
8
+ * const server = new TwilioAgentServer({ port: 8080 });
9
+ *
10
+ * server.onCall(async (callId, transport) => {
11
+ * const voiceSession = new AriaFlowVoiceSession({
12
+ * runtime: runtime,
13
+ * stt: new GeminiLiveSTT(),
14
+ * tts: new GeminiLiveTTS(),
15
+ * });
16
+ * await server.startSession(callId, voiceSession);
17
+ * });
18
+ *
19
+ * await server.listen();
20
+ */
21
+ export class TwilioAgentServer {
22
+ options;
23
+ wss = null;
24
+ sessionManager = new SessionManager();
25
+ callHandler = null;
26
+ callIdCounter = 0;
27
+ constructor(options = {}) {
28
+ this.options = options;
29
+ }
30
+ onCall(handler) {
31
+ this.callHandler = handler;
32
+ }
33
+ async startSession(callId, voiceSession) {
34
+ const transport = this.transports.get(callId);
35
+ if (!transport) {
36
+ throw new Error(`Transport not found for call: ${callId}`);
37
+ }
38
+ return this.sessionManager.startSession(transport, voiceSession);
39
+ }
40
+ transports = new Map();
41
+ async listen() {
42
+ const port = this.options.port ?? 8080;
43
+ const host = this.options.host ?? '0.0.0.0';
44
+ this.wss = new WSServer({ port, host });
45
+ this.wss.on('connection', async (ws, req) => {
46
+ const callId = `call-${++this.callIdCounter}`;
47
+ console.log(`[TwilioServer] New connection: ${callId}`);
48
+ const transport = new TwilioTransportAdapter({
49
+ id: callId,
50
+ send: (message) => {
51
+ if (ws.readyState === ws.OPEN) {
52
+ ws.send(message);
53
+ }
54
+ },
55
+ });
56
+ // Store transport
57
+ this.transports.set(callId, transport);
58
+ // Handle incoming messages from Twilio
59
+ ws.on('message', (data) => {
60
+ try {
61
+ const message = data.toString();
62
+ // Parse to detect start event
63
+ const event = JSON.parse(message);
64
+ // Log events
65
+ if (event.event === 'connected') {
66
+ console.log(`[TwilioServer] [${callId}] Connected to Twilio`);
67
+ }
68
+ else if (event.event === 'start') {
69
+ const streamSid = event.start?.streamSid ?? event.streamSid ?? '(missing)';
70
+ console.log(`[TwilioServer] [${callId}] Stream started: ${streamSid}`);
71
+ }
72
+ else if (event.event === 'stop') {
73
+ console.log(`[TwilioServer] [${callId}] Stream stopped`);
74
+ }
75
+ // Route to transport
76
+ transport.handleMessage(message);
77
+ // Trigger call handler on start event (when streamSid is available)
78
+ if (event.event === 'start' && this.callHandler) {
79
+ this.callHandler(callId, transport);
80
+ }
81
+ }
82
+ catch (error) {
83
+ console.error('[TwilioServer] Error handling message:', {
84
+ error: error instanceof Error ? error.message : String(error),
85
+ callId,
86
+ });
87
+ }
88
+ });
89
+ // Handle disconnect
90
+ ws.on('close', async () => {
91
+ console.log(`[TwilioServer] Connection closed: ${callId}`);
92
+ await this.sessionManager.closeSession(callId).catch((err) => {
93
+ console.error('[TwilioServer] Error closing session:', {
94
+ error: err instanceof Error ? err.message : String(err),
95
+ callId,
96
+ });
97
+ });
98
+ await transport.close();
99
+ this.transports.delete(callId);
100
+ });
101
+ // Handle errors
102
+ ws.on('error', (error) => {
103
+ console.error('[TwilioServer] WebSocket error:', {
104
+ error: error.message,
105
+ callId,
106
+ });
107
+ });
108
+ });
109
+ return new Promise((resolve) => {
110
+ this.wss.on('listening', () => {
111
+ resolve();
112
+ });
113
+ });
114
+ }
115
+ get sessions() {
116
+ return this.sessionManager;
117
+ }
118
+ async close() {
119
+ await this.sessionManager.closeAll();
120
+ if (this.wss) {
121
+ this.wss.close();
122
+ }
123
+ }
124
+ }
125
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,QAAQ,EAAkB,MAAM,IAAI,CAAC;AACjE,OAAO,EAAE,cAAc,EAA6B,MAAM,0BAA0B,CAAC;AAGrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAWhE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,iBAAiB;IAQR;IAPZ,GAAG,GAAoB,IAAI,CAAC;IAC5B,cAAc,GAAmB,IAAI,cAAc,EAAE,CAAC;IACtD,WAAW,GAER,IAAI,CAAC;IACR,aAAa,GAAG,CAAC,CAAC;IAE1B,YAAoB,UAA+B,EAAE;QAAjC,YAAO,GAAP,OAAO,CAA0B;IAAG,CAAC;IAEzD,MAAM,CACJ,OAAoF;QAEpF,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,MAAc,EACd,YAAkC;QAElC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACnE,CAAC;IAEO,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE/D,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;QAE5C,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAExC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,EAAa,EAAE,GAAoB,EAAE,EAAE;YACtE,MAAM,MAAM,GAAG,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;YAExD,MAAM,SAAS,GAAG,IAAI,sBAAsB,CAAC;gBAC3C,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;oBAChB,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;wBAC9B,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;YAEH,kBAAkB;YAClB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAEvC,uCAAuC;YACvC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE;gBAChC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAEhC,8BAA8B;oBAC9B,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAE/C,aAAa;oBACb,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;wBAChC,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,uBAAuB,CAAC,CAAC;oBAChE,CAAC;yBAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;wBACnC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,CAAC;wBAC3E,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,qBAAqB,SAAS,EAAE,CAAC,CAAC;oBACzE,CAAC;yBAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;wBAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,kBAAkB,CAAC,CAAC;oBAC3D,CAAC;oBAED,qBAAqB;oBACrB,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;oBAEjC,oEAAoE;oBACpE,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAChD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;oBACtC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE;wBACtD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;wBAC7D,MAAM;qBACP,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,oBAAoB;YACpB,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACxB,OAAO,CAAC,GAAG,CAAC,qCAAqC,MAAM,EAAE,CAAC,CAAC;gBAC3D,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC3D,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE;wBACrD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;wBACvD,MAAM;qBACP,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;gBACxB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YAEH,gBAAgB;YAChB,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE;oBAC/C,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,MAAM;iBACP,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,IAAI,CAAC,GAAI,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;gBAC7B,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Text output for Twilio Media Streams.
3
+ *
4
+ * Sends transcribed agent responses as text events to Twilio.
5
+ */
6
+ import { TextOutput, type TimedString } from '@ariaflow/livekit-plugin';
7
+ /**
8
+ * Sends agent text responses to Twilio Media Streams.
9
+ *
10
+ * Since Twilio Media Streams is primarily audio-focused, this
11
+ * implementation stores text for potential use in marks/metadata.
12
+ */
13
+ export declare class TwilioTextOutput extends TextOutput {
14
+ private closed;
15
+ private textBuffer;
16
+ private sendCallback;
17
+ constructor(nextInChain?: TextOutput);
18
+ /**
19
+ * Set the callback for sending marks to Twilio.
20
+ *
21
+ * @param callback - Function that sends mark name to WebSocket
22
+ */
23
+ setSendCallback(callback: (markName: string) => void): void;
24
+ captureText(text: string | TimedString): Promise<void>;
25
+ flush(): void;
26
+ close(): Promise<void>;
27
+ /**
28
+ * Get buffered text (for debugging or logging).
29
+ */
30
+ getBufferedText(): string[];
31
+ }
32
+ //# sourceMappingURL=text_output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text_output.d.ts","sourceRoot":"","sources":["../src/text_output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAiB,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvF;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAC9C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAgB;IAGlC,OAAO,CAAC,YAAY,CAAwC;gBAEhD,WAAW,CAAC,EAAE,UAAU;IAIpC;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB5D,KAAK,IAAI,IAAI;IAWP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;CAG5B"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Text output for Twilio Media Streams.
3
+ *
4
+ * Sends transcribed agent responses as text events to Twilio.
5
+ */
6
+ import { TextOutput, isTimedString } from '@ariaflow/livekit-plugin';
7
+ /**
8
+ * Sends agent text responses to Twilio Media Streams.
9
+ *
10
+ * Since Twilio Media Streams is primarily audio-focused, this
11
+ * implementation stores text for potential use in marks/metadata.
12
+ */
13
+ export class TwilioTextOutput extends TextOutput {
14
+ closed = false;
15
+ textBuffer = [];
16
+ // Callback to send marks to Twilio
17
+ sendCallback = () => { };
18
+ constructor(nextInChain) {
19
+ super(nextInChain);
20
+ }
21
+ /**
22
+ * Set the callback for sending marks to Twilio.
23
+ *
24
+ * @param callback - Function that sends mark name to WebSocket
25
+ */
26
+ setSendCallback(callback) {
27
+ this.sendCallback = callback;
28
+ }
29
+ async captureText(text) {
30
+ if (this.closed)
31
+ return;
32
+ const textContent = isTimedString(text) ? text.text : text;
33
+ this.textBuffer.push(textContent);
34
+ // Send as a mark event to Twilio (metadata only)
35
+ try {
36
+ this.sendCallback(`agent_response_${this.textBuffer.length}`);
37
+ }
38
+ catch (error) {
39
+ console.error('[TwilioTextOutput] Error sending mark:', {
40
+ error: error instanceof Error ? error.message : String(error),
41
+ textLength: textContent.length,
42
+ timestamp: new Date().toISOString(),
43
+ });
44
+ }
45
+ // Access protected nextInChain property
46
+ const next = this.nextInChain;
47
+ if (next) {
48
+ await next.captureText(text);
49
+ }
50
+ }
51
+ flush() {
52
+ if (this.closed)
53
+ return;
54
+ this.textBuffer = [];
55
+ // Access protected nextInChain property
56
+ const next = this.nextInChain;
57
+ if (next) {
58
+ next.flush();
59
+ }
60
+ }
61
+ async close() {
62
+ this.closed = true;
63
+ this.textBuffer = [];
64
+ }
65
+ /**
66
+ * Get buffered text (for debugging or logging).
67
+ */
68
+ getBufferedText() {
69
+ return [...this.textBuffer];
70
+ }
71
+ }
72
+ //# sourceMappingURL=text_output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text_output.js","sourceRoot":"","sources":["../src/text_output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAoB,MAAM,0BAA0B,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IACtC,MAAM,GAAY,KAAK,CAAC;IACxB,UAAU,GAAa,EAAE,CAAC;IAElC,mCAAmC;IAC3B,YAAY,GAA+B,GAAG,EAAE,GAAE,CAAC,CAAC;IAE5D,YAAY,WAAwB;QAClC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,QAAoC;QAClD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAA0B;QAC1C,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAExB,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAElC,iDAAiD;QACjD,IAAI,CAAC;YACH,IAAI,CAAC,YAAY,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE;gBACtD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7D,UAAU,EAAE,WAAW,CAAC,MAAM;gBAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;QACL,CAAC;QAED,wCAAwC;QACxC,MAAM,IAAI,GAAI,IAAY,CAAC,WAAW,CAAC;QACvC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QAErB,wCAAwC;QACxC,MAAM,IAAI,GAAI,IAAY,CAAC,WAAW,CAAC;QACvC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;CACF"}