@framers/agentos 0.1.111 → 0.1.113
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/dist/api/strategies/debate.d.ts +12 -1
- package/dist/api/strategies/debate.d.ts.map +1 -1
- package/dist/api/strategies/debate.js +41 -5
- package/dist/api/strategies/debate.js.map +1 -1
- package/dist/api/strategies/hierarchical.d.ts +15 -1
- package/dist/api/strategies/hierarchical.d.ts.map +1 -1
- package/dist/api/strategies/hierarchical.js +51 -7
- package/dist/api/strategies/hierarchical.js.map +1 -1
- package/dist/api/strategies/index.d.ts +26 -4
- package/dist/api/strategies/index.d.ts.map +1 -1
- package/dist/api/strategies/index.js +26 -4
- package/dist/api/strategies/index.js.map +1 -1
- package/dist/api/strategies/parallel.d.ts +15 -4
- package/dist/api/strategies/parallel.d.ts.map +1 -1
- package/dist/api/strategies/parallel.js +53 -16
- package/dist/api/strategies/parallel.js.map +1 -1
- package/dist/api/strategies/review-loop.d.ts +15 -1
- package/dist/api/strategies/review-loop.d.ts.map +1 -1
- package/dist/api/strategies/review-loop.js +36 -10
- package/dist/api/strategies/review-loop.js.map +1 -1
- package/dist/api/strategies/sequential.d.ts +11 -1
- package/dist/api/strategies/sequential.d.ts.map +1 -1
- package/dist/api/strategies/sequential.js +39 -8
- package/dist/api/strategies/sequential.js.map +1 -1
- package/dist/api/strategies/shared.d.ts +71 -7
- package/dist/api/strategies/shared.d.ts.map +1 -1
- package/dist/api/strategies/shared.js +89 -10
- package/dist/api/strategies/shared.js.map +1 -1
- package/dist/api/types.d.ts +54 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/memory/facade/Memory.d.ts.map +1 -1
- package/dist/memory/facade/Memory.js +8 -0
- package/dist/memory/facade/Memory.js.map +1 -1
- package/dist/memory/facade/types.d.ts +10 -0
- package/dist/memory/facade/types.d.ts.map +1 -1
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +5 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/observation/MemoryObserver.d.ts +63 -1
- package/dist/memory/observation/MemoryObserver.d.ts.map +1 -1
- package/dist/memory/observation/MemoryObserver.js +115 -4
- package/dist/memory/observation/MemoryObserver.js.map +1 -1
- package/dist/memory/observation/ObservationCompressor.d.ts +88 -0
- package/dist/memory/observation/ObservationCompressor.d.ts.map +1 -0
- package/dist/memory/observation/ObservationCompressor.js +207 -0
- package/dist/memory/observation/ObservationCompressor.js.map +1 -0
- package/dist/memory/observation/ObservationReflector.d.ts +82 -0
- package/dist/memory/observation/ObservationReflector.d.ts.map +1 -0
- package/dist/memory/observation/ObservationReflector.js +212 -0
- package/dist/memory/observation/ObservationReflector.js.map +1 -0
- package/dist/memory/observation/temporal.d.ts +54 -0
- package/dist/memory/observation/temporal.d.ts.map +1 -0
- package/dist/memory/observation/temporal.js +115 -0
- package/dist/memory/observation/temporal.js.map +1 -0
- package/dist/orchestration/builders/VoiceNodeBuilder.d.ts +82 -25
- package/dist/orchestration/builders/VoiceNodeBuilder.d.ts.map +1 -1
- package/dist/orchestration/builders/VoiceNodeBuilder.js +86 -26
- package/dist/orchestration/builders/VoiceNodeBuilder.js.map +1 -1
- package/dist/orchestration/events/GraphEvent.d.ts +67 -5
- package/dist/orchestration/events/GraphEvent.d.ts.map +1 -1
- package/dist/orchestration/events/GraphEvent.js.map +1 -1
- package/dist/orchestration/runtime/VoiceNodeExecutor.d.ts +102 -25
- package/dist/orchestration/runtime/VoiceNodeExecutor.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceNodeExecutor.js +133 -38
- package/dist/orchestration/runtime/VoiceNodeExecutor.js.map +1 -1
- package/dist/orchestration/runtime/VoiceTransportAdapter.d.ts +94 -32
- package/dist/orchestration/runtime/VoiceTransportAdapter.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceTransportAdapter.js +82 -28
- package/dist/orchestration/runtime/VoiceTransportAdapter.js.map +1 -1
- package/dist/orchestration/runtime/VoiceTurnCollector.d.ts +73 -20
- package/dist/orchestration/runtime/VoiceTurnCollector.d.ts.map +1 -1
- package/dist/orchestration/runtime/VoiceTurnCollector.js +84 -23
- package/dist/orchestration/runtime/VoiceTurnCollector.js.map +1 -1
- package/dist/voice/CallManager.d.ts.map +1 -1
- package/dist/voice/CallManager.js +9 -1
- package/dist/voice/CallManager.js.map +1 -1
- package/dist/voice/MediaStreamParser.d.ts +115 -6
- package/dist/voice/MediaStreamParser.d.ts.map +1 -1
- package/dist/voice/MediaStreamParser.js +44 -0
- package/dist/voice/MediaStreamParser.js.map +1 -1
- package/dist/voice/TelephonyStreamTransport.d.ts +112 -20
- package/dist/voice/TelephonyStreamTransport.d.ts.map +1 -1
- package/dist/voice/TelephonyStreamTransport.js +136 -30
- package/dist/voice/TelephonyStreamTransport.js.map +1 -1
- package/dist/voice/parsers/PlivoMediaStreamParser.d.ts +64 -6
- package/dist/voice/parsers/PlivoMediaStreamParser.d.ts.map +1 -1
- package/dist/voice/parsers/PlivoMediaStreamParser.js +67 -6
- package/dist/voice/parsers/PlivoMediaStreamParser.js.map +1 -1
- package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts +55 -8
- package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts.map +1 -1
- package/dist/voice/parsers/TelnyxMediaStreamParser.js +60 -9
- package/dist/voice/parsers/TelnyxMediaStreamParser.js.map +1 -1
- package/dist/voice/parsers/TwilioMediaStreamParser.d.ts +73 -11
- package/dist/voice/parsers/TwilioMediaStreamParser.d.ts.map +1 -1
- package/dist/voice/parsers/TwilioMediaStreamParser.js +81 -12
- package/dist/voice/parsers/TwilioMediaStreamParser.js.map +1 -1
- package/dist/voice/providers/plivo.d.ts +108 -12
- package/dist/voice/providers/plivo.d.ts.map +1 -1
- package/dist/voice/providers/plivo.js +106 -9
- package/dist/voice/providers/plivo.js.map +1 -1
- package/dist/voice/providers/telnyx.d.ts +110 -20
- package/dist/voice/providers/telnyx.d.ts.map +1 -1
- package/dist/voice/providers/telnyx.js +111 -20
- package/dist/voice/providers/telnyx.js.map +1 -1
- package/dist/voice/providers/twilio.d.ts +91 -13
- package/dist/voice/providers/twilio.d.ts.map +1 -1
- package/dist/voice/providers/twilio.js +94 -14
- package/dist/voice/providers/twilio.js.map +1 -1
- package/dist/voice/twiml.d.ts +70 -12
- package/dist/voice/twiml.d.ts.map +1 -1
- package/dist/voice/twiml.js +70 -12
- package/dist/voice/twiml.js.map +1 -1
- package/dist/voice/types.d.ts +142 -15
- package/dist/voice/types.d.ts.map +1 -1
- package/dist/voice/types.js +34 -3
- package/dist/voice/types.js.map +1 -1
- package/package.json +1 -1
package/dist/voice/twiml.d.ts
CHANGED
|
@@ -2,8 +2,26 @@
|
|
|
2
2
|
* @fileoverview TwiML and XML generation helpers for telephony providers.
|
|
3
3
|
*
|
|
4
4
|
* Generates provider-specific XML/TwiML response payloads for Twilio, Telnyx,
|
|
5
|
-
* and Plivo. All text content and attribute values are XML-escaped
|
|
6
|
-
* injection or malformed markup.
|
|
5
|
+
* and Plivo. All text content and attribute values are XML-escaped via
|
|
6
|
+
* {@link escapeXml} to prevent injection or malformed markup.
|
|
7
|
+
*
|
|
8
|
+
* ## XSS / injection prevention
|
|
9
|
+
*
|
|
10
|
+
* Every dynamic value (URLs, text content, voice names) passes through
|
|
11
|
+
* {@link escapeXml} before being interpolated into the XML template. This
|
|
12
|
+
* replaces the five XML-sensitive characters with their named entity
|
|
13
|
+
* equivalents:
|
|
14
|
+
*
|
|
15
|
+
* | Character | Entity |
|
|
16
|
+
* |-----------|-----------|
|
|
17
|
+
* | `<` | `<` |
|
|
18
|
+
* | `>` | `>` |
|
|
19
|
+
* | `&` | `&` |
|
|
20
|
+
* | `"` | `"` |
|
|
21
|
+
* | `'` | `'` |
|
|
22
|
+
*
|
|
23
|
+
* This ensures that user-controlled input (caller names, agent-generated
|
|
24
|
+
* messages, etc.) cannot break out of an attribute or inject child elements.
|
|
7
25
|
*
|
|
8
26
|
* @module @framers/agentos/voice/twiml
|
|
9
27
|
*/
|
|
@@ -11,27 +29,44 @@
|
|
|
11
29
|
* Generate TwiML for Twilio conversation mode using a bidirectional media stream.
|
|
12
30
|
*
|
|
13
31
|
* The returned markup instructs Twilio to open a WebSocket to `streamUrl` and
|
|
14
|
-
* stream audio in both directions for the duration of the call.
|
|
32
|
+
* stream audio in both directions for the duration of the call. Twilio will
|
|
33
|
+
* send mu-law 8 kHz audio chunks as JSON `media` events on the WebSocket.
|
|
15
34
|
*
|
|
16
|
-
* @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss
|
|
17
|
-
* @param token - Optional bearer token appended as a `?token=` query parameter
|
|
35
|
+
* @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss://api.example.com/stream`).
|
|
36
|
+
* @param token - Optional bearer token appended as a `?token=` query parameter
|
|
37
|
+
* for authenticating the WebSocket connection.
|
|
18
38
|
* @returns A complete TwiML XML document string.
|
|
19
39
|
*
|
|
20
40
|
* @example
|
|
21
41
|
* ```typescript
|
|
22
|
-
*
|
|
42
|
+
* // Without auth token:
|
|
43
|
+
* twilioConversationTwiml('wss://api.example.com/call');
|
|
44
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Connect><Stream url="wss://api.example.com/call" /></Connect></Response>'
|
|
45
|
+
*
|
|
46
|
+
* // With auth token:
|
|
47
|
+
* twilioConversationTwiml('wss://api.example.com/call', 'jwt-token-here');
|
|
48
|
+
* // => '<?xml version="1.0" ...><Response><Connect><Stream url="wss://api.example.com/call?token=jwt-token-here" /></Connect></Response>'
|
|
23
49
|
* ```
|
|
24
50
|
*/
|
|
25
51
|
export declare function twilioConversationTwiml(streamUrl: string, token?: string): string;
|
|
26
52
|
/**
|
|
27
|
-
* Generate TwiML for Twilio notify mode
|
|
53
|
+
* Generate TwiML for Twilio notify mode -- synthesise `text` over the call then hang up.
|
|
28
54
|
*
|
|
29
55
|
* Useful for delivering one-shot announcements (e.g. voicemail greetings, error
|
|
30
|
-
* messages) without establishing a full media stream.
|
|
56
|
+
* messages, appointment reminders) without establishing a full media stream.
|
|
31
57
|
*
|
|
32
|
-
* @param text - The message to speak to the caller.
|
|
58
|
+
* @param text - The message to speak to the caller. XML-escaped automatically.
|
|
33
59
|
* @param voice - Optional Twilio voice name (e.g. `'Polly.Joanna'`, `'alice'`).
|
|
34
60
|
* @returns A complete TwiML XML document string.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* twilioNotifyTwiml('Your appointment is confirmed.');
|
|
65
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Say>Your appointment is confirmed.</Say><Hangup/></Response>'
|
|
66
|
+
*
|
|
67
|
+
* twilioNotifyTwiml('Hello', 'Polly.Joanna');
|
|
68
|
+
* // => '...><Say voice="Polly.Joanna">Hello</Say><Hangup/></Response>'
|
|
69
|
+
* ```
|
|
35
70
|
*/
|
|
36
71
|
export declare function twilioNotifyTwiml(text: string, voice?: string): string;
|
|
37
72
|
/**
|
|
@@ -43,27 +78,50 @@ export declare function twilioNotifyTwiml(text: string, voice?: string): string;
|
|
|
43
78
|
*
|
|
44
79
|
* @param streamUrl - WebSocket URL Telnyx should stream audio to.
|
|
45
80
|
* @returns A complete XML document string.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* telnyxStreamXml('wss://api.example.com/telnyx-stream');
|
|
85
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream url="wss://api.example.com/telnyx-stream" /></Response>'
|
|
86
|
+
* ```
|
|
46
87
|
*/
|
|
47
88
|
export declare function telnyxStreamXml(streamUrl: string): string;
|
|
48
89
|
/**
|
|
49
90
|
* Generate Plivo bidirectional streaming XML.
|
|
50
91
|
*
|
|
51
92
|
* Instructs Plivo to open a bidirectional WebSocket stream and keep the call
|
|
52
|
-
* alive for the duration of the stream session.
|
|
93
|
+
* alive for the duration of the stream session. The stream URL is placed as
|
|
94
|
+
* element text content (not an attribute) per the Plivo XML spec.
|
|
53
95
|
*
|
|
54
96
|
* @param streamUrl - WebSocket URL Plivo should connect to.
|
|
55
97
|
* @returns A complete Plivo XML document string.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* plivoStreamXml('wss://api.example.com/plivo-stream');
|
|
102
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream bidirectional="true" keepCallAlive="true">wss://api.example.com/plivo-stream</Stream></Response>'
|
|
103
|
+
* ```
|
|
56
104
|
*/
|
|
57
105
|
export declare function plivoStreamXml(streamUrl: string): string;
|
|
58
106
|
/**
|
|
59
107
|
* Generate Plivo speak + hangup XML.
|
|
60
108
|
*
|
|
61
109
|
* Synthesises `text` to the caller using Plivo's TTS engine and immediately
|
|
62
|
-
* hangs up after playback completes.
|
|
110
|
+
* hangs up after playback completes. Equivalent to Twilio's `<Say>...<Hangup/>`
|
|
111
|
+
* but uses Plivo's `<Speak>` element name.
|
|
63
112
|
*
|
|
64
|
-
* @param text - The message to speak to the caller.
|
|
113
|
+
* @param text - The message to speak to the caller. XML-escaped automatically.
|
|
65
114
|
* @param voice - Optional Plivo voice name (e.g. `'WOMAN'`, `'Polly.Joanna'`).
|
|
66
115
|
* @returns A complete Plivo XML document string.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* plivoNotifyXml('Your order has shipped.');
|
|
120
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Speak>Your order has shipped.</Speak><Hangup/></Response>'
|
|
121
|
+
*
|
|
122
|
+
* plivoNotifyXml('Hello', 'WOMAN');
|
|
123
|
+
* // => '...><Speak voice="WOMAN">Hello</Speak><Hangup/></Response>'
|
|
124
|
+
* ```
|
|
67
125
|
*/
|
|
68
126
|
export declare function plivoNotifyXml(text: string, voice?: string): string;
|
|
69
127
|
//# sourceMappingURL=twiml.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twiml.d.ts","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"twiml.d.ts","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGtE;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzD;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGnE"}
|
package/dist/voice/twiml.js
CHANGED
|
@@ -2,8 +2,26 @@
|
|
|
2
2
|
* @fileoverview TwiML and XML generation helpers for telephony providers.
|
|
3
3
|
*
|
|
4
4
|
* Generates provider-specific XML/TwiML response payloads for Twilio, Telnyx,
|
|
5
|
-
* and Plivo. All text content and attribute values are XML-escaped
|
|
6
|
-
* injection or malformed markup.
|
|
5
|
+
* and Plivo. All text content and attribute values are XML-escaped via
|
|
6
|
+
* {@link escapeXml} to prevent injection or malformed markup.
|
|
7
|
+
*
|
|
8
|
+
* ## XSS / injection prevention
|
|
9
|
+
*
|
|
10
|
+
* Every dynamic value (URLs, text content, voice names) passes through
|
|
11
|
+
* {@link escapeXml} before being interpolated into the XML template. This
|
|
12
|
+
* replaces the five XML-sensitive characters with their named entity
|
|
13
|
+
* equivalents:
|
|
14
|
+
*
|
|
15
|
+
* | Character | Entity |
|
|
16
|
+
* |-----------|-----------|
|
|
17
|
+
* | `<` | `<` |
|
|
18
|
+
* | `>` | `>` |
|
|
19
|
+
* | `&` | `&` |
|
|
20
|
+
* | `"` | `"` |
|
|
21
|
+
* | `'` | `'` |
|
|
22
|
+
*
|
|
23
|
+
* This ensures that user-controlled input (caller names, agent-generated
|
|
24
|
+
* messages, etc.) cannot break out of an attribute or inject child elements.
|
|
7
25
|
*
|
|
8
26
|
* @module @framers/agentos/voice/twiml
|
|
9
27
|
*/
|
|
@@ -15,15 +33,23 @@ import { escapeXml } from './telephony-audio.js';
|
|
|
15
33
|
* Generate TwiML for Twilio conversation mode using a bidirectional media stream.
|
|
16
34
|
*
|
|
17
35
|
* The returned markup instructs Twilio to open a WebSocket to `streamUrl` and
|
|
18
|
-
* stream audio in both directions for the duration of the call.
|
|
36
|
+
* stream audio in both directions for the duration of the call. Twilio will
|
|
37
|
+
* send mu-law 8 kHz audio chunks as JSON `media` events on the WebSocket.
|
|
19
38
|
*
|
|
20
|
-
* @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss
|
|
21
|
-
* @param token - Optional bearer token appended as a `?token=` query parameter
|
|
39
|
+
* @param streamUrl - WebSocket URL Twilio should connect to (e.g. `wss://api.example.com/stream`).
|
|
40
|
+
* @param token - Optional bearer token appended as a `?token=` query parameter
|
|
41
|
+
* for authenticating the WebSocket connection.
|
|
22
42
|
* @returns A complete TwiML XML document string.
|
|
23
43
|
*
|
|
24
44
|
* @example
|
|
25
45
|
* ```typescript
|
|
26
|
-
*
|
|
46
|
+
* // Without auth token:
|
|
47
|
+
* twilioConversationTwiml('wss://api.example.com/call');
|
|
48
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Connect><Stream url="wss://api.example.com/call" /></Connect></Response>'
|
|
49
|
+
*
|
|
50
|
+
* // With auth token:
|
|
51
|
+
* twilioConversationTwiml('wss://api.example.com/call', 'jwt-token-here');
|
|
52
|
+
* // => '<?xml version="1.0" ...><Response><Connect><Stream url="wss://api.example.com/call?token=jwt-token-here" /></Connect></Response>'
|
|
27
53
|
* ```
|
|
28
54
|
*/
|
|
29
55
|
export function twilioConversationTwiml(streamUrl, token) {
|
|
@@ -31,14 +57,23 @@ export function twilioConversationTwiml(streamUrl, token) {
|
|
|
31
57
|
return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Connect><Stream url="${escapeXml(url)}" /></Connect></Response>`;
|
|
32
58
|
}
|
|
33
59
|
/**
|
|
34
|
-
* Generate TwiML for Twilio notify mode
|
|
60
|
+
* Generate TwiML for Twilio notify mode -- synthesise `text` over the call then hang up.
|
|
35
61
|
*
|
|
36
62
|
* Useful for delivering one-shot announcements (e.g. voicemail greetings, error
|
|
37
|
-
* messages) without establishing a full media stream.
|
|
63
|
+
* messages, appointment reminders) without establishing a full media stream.
|
|
38
64
|
*
|
|
39
|
-
* @param text - The message to speak to the caller.
|
|
65
|
+
* @param text - The message to speak to the caller. XML-escaped automatically.
|
|
40
66
|
* @param voice - Optional Twilio voice name (e.g. `'Polly.Joanna'`, `'alice'`).
|
|
41
67
|
* @returns A complete TwiML XML document string.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* twilioNotifyTwiml('Your appointment is confirmed.');
|
|
72
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Say>Your appointment is confirmed.</Say><Hangup/></Response>'
|
|
73
|
+
*
|
|
74
|
+
* twilioNotifyTwiml('Hello', 'Polly.Joanna');
|
|
75
|
+
* // => '...><Say voice="Polly.Joanna">Hello</Say><Hangup/></Response>'
|
|
76
|
+
* ```
|
|
42
77
|
*/
|
|
43
78
|
export function twilioNotifyTwiml(text, voice) {
|
|
44
79
|
const voiceAttr = voice ? ` voice="${escapeXml(voice)}"` : '';
|
|
@@ -56,6 +91,12 @@ export function twilioNotifyTwiml(text, voice) {
|
|
|
56
91
|
*
|
|
57
92
|
* @param streamUrl - WebSocket URL Telnyx should stream audio to.
|
|
58
93
|
* @returns A complete XML document string.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* telnyxStreamXml('wss://api.example.com/telnyx-stream');
|
|
98
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream url="wss://api.example.com/telnyx-stream" /></Response>'
|
|
99
|
+
* ```
|
|
59
100
|
*/
|
|
60
101
|
export function telnyxStreamXml(streamUrl) {
|
|
61
102
|
return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream url="${escapeXml(streamUrl)}" /></Response>`;
|
|
@@ -67,10 +108,17 @@ export function telnyxStreamXml(streamUrl) {
|
|
|
67
108
|
* Generate Plivo bidirectional streaming XML.
|
|
68
109
|
*
|
|
69
110
|
* Instructs Plivo to open a bidirectional WebSocket stream and keep the call
|
|
70
|
-
* alive for the duration of the stream session.
|
|
111
|
+
* alive for the duration of the stream session. The stream URL is placed as
|
|
112
|
+
* element text content (not an attribute) per the Plivo XML spec.
|
|
71
113
|
*
|
|
72
114
|
* @param streamUrl - WebSocket URL Plivo should connect to.
|
|
73
115
|
* @returns A complete Plivo XML document string.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* plivoStreamXml('wss://api.example.com/plivo-stream');
|
|
120
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream bidirectional="true" keepCallAlive="true">wss://api.example.com/plivo-stream</Stream></Response>'
|
|
121
|
+
* ```
|
|
74
122
|
*/
|
|
75
123
|
export function plivoStreamXml(streamUrl) {
|
|
76
124
|
return `<?xml version="1.0" encoding="UTF-8"?>\n<Response><Stream bidirectional="true" keepCallAlive="true">${escapeXml(streamUrl)}</Stream></Response>`;
|
|
@@ -79,11 +127,21 @@ export function plivoStreamXml(streamUrl) {
|
|
|
79
127
|
* Generate Plivo speak + hangup XML.
|
|
80
128
|
*
|
|
81
129
|
* Synthesises `text` to the caller using Plivo's TTS engine and immediately
|
|
82
|
-
* hangs up after playback completes.
|
|
130
|
+
* hangs up after playback completes. Equivalent to Twilio's `<Say>...<Hangup/>`
|
|
131
|
+
* but uses Plivo's `<Speak>` element name.
|
|
83
132
|
*
|
|
84
|
-
* @param text - The message to speak to the caller.
|
|
133
|
+
* @param text - The message to speak to the caller. XML-escaped automatically.
|
|
85
134
|
* @param voice - Optional Plivo voice name (e.g. `'WOMAN'`, `'Polly.Joanna'`).
|
|
86
135
|
* @returns A complete Plivo XML document string.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* plivoNotifyXml('Your order has shipped.');
|
|
140
|
+
* // => '<?xml version="1.0" encoding="UTF-8"?>\n<Response><Speak>Your order has shipped.</Speak><Hangup/></Response>'
|
|
141
|
+
*
|
|
142
|
+
* plivoNotifyXml('Hello', 'WOMAN');
|
|
143
|
+
* // => '...><Speak voice="WOMAN">Hello</Speak><Hangup/></Response>'
|
|
144
|
+
* ```
|
|
87
145
|
*/
|
|
88
146
|
export function plivoNotifyXml(text, voice) {
|
|
89
147
|
const voiceAttr = voice ? ` voice="${escapeXml(voice)}"` : '';
|
package/dist/voice/twiml.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twiml.js","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"twiml.js","sourceRoot":"","sources":["../../src/voice/twiml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;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;;;;;;;;;;;;;;;;;;GAkBG;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;;;;;;;;;;;;;;;GAeG;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;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,uGAAuG,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC;AAC3J,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;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"}
|
package/dist/voice/types.d.ts
CHANGED
|
@@ -5,27 +5,85 @@
|
|
|
5
5
|
* providers (Twilio, Telnyx, Plivo). This module defines the call lifecycle
|
|
6
6
|
* state machine, event types, and configuration.
|
|
7
7
|
*
|
|
8
|
+
* ## Call lifecycle state machine
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* ┌──────────────────────────────────────────────┐
|
|
12
|
+
* │ Terminal states │
|
|
13
|
+
* │ completed | hangup-user | hangup-bot │
|
|
14
|
+
* │ timeout | error | failed | no-answer │
|
|
15
|
+
* │ busy | voicemail │
|
|
16
|
+
* └───────────────────────────────────────▲──────┘
|
|
17
|
+
* │ (from any non-terminal)
|
|
18
|
+
* initiated ──► ringing ──► answered ──► active ──► speaking ◄──► listening
|
|
19
|
+
* (monotonic forward-only) (can cycle)
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
8
22
|
* Modeled after OpenClaw's voice-call extension architecture with adaptations
|
|
9
23
|
* for the AgentOS extension pack pattern.
|
|
10
24
|
*
|
|
11
25
|
* @module @framers/agentos/voice/types
|
|
12
26
|
*/
|
|
13
27
|
/**
|
|
14
|
-
* Supported telephony providers.
|
|
28
|
+
* Supported telephony providers.
|
|
29
|
+
*
|
|
30
|
+
* The explicit literals enable autocomplete and exhaustiveness checking while
|
|
31
|
+
* the `(string & {})` arm keeps the type open for future providers without
|
|
32
|
+
* requiring a code change.
|
|
15
33
|
*/
|
|
16
34
|
export type VoiceProviderName = 'twilio' | 'telnyx' | 'plivo' | 'mock' | (string & {});
|
|
17
35
|
/**
|
|
18
|
-
* States a voice call can be in.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
36
|
+
* States a voice call can be in.
|
|
37
|
+
*
|
|
38
|
+
* Transitions follow a monotonic order
|
|
39
|
+
* (`initiated` -> `ringing` -> `answered` -> `active` -> `speaking`/`listening`),
|
|
40
|
+
* except `speaking` <-> `listening` which can cycle during conversation turns.
|
|
41
|
+
* Terminal states can be reached from **any** non-terminal state.
|
|
42
|
+
*
|
|
43
|
+
* ## Non-terminal states (forward-only progression)
|
|
44
|
+
* - `initiated` -- Call record created, provider request sent.
|
|
45
|
+
* - `ringing` -- Provider confirmed the destination phone is ringing.
|
|
46
|
+
* - `answered` -- Callee picked up; media channel not yet established.
|
|
47
|
+
* - `active` -- Bidirectional media stream is established.
|
|
48
|
+
*
|
|
49
|
+
* ## Conversation cycling states (can alternate freely)
|
|
50
|
+
* - `speaking` -- Agent TTS is playing audio to the caller.
|
|
51
|
+
* - `listening` -- Agent STT is listening for caller speech.
|
|
52
|
+
*
|
|
53
|
+
* ## Terminal states (once reached, no further transitions)
|
|
54
|
+
* - `completed` -- Normal call completion (both parties done).
|
|
55
|
+
* - `hangup-user` -- The remote caller hung up.
|
|
56
|
+
* - `hangup-bot` -- The agent initiated the hangup.
|
|
57
|
+
* - `timeout` -- Call exceeded `maxDurationSeconds`.
|
|
58
|
+
* - `error` -- Unrecoverable error during the call.
|
|
59
|
+
* - `failed` -- Provider could not place the call at all.
|
|
60
|
+
* - `no-answer` -- Callee did not pick up within the ring timeout.
|
|
61
|
+
* - `busy` -- Callee line is busy.
|
|
62
|
+
* - `voicemail` -- Answering machine / voicemail detected.
|
|
22
63
|
*/
|
|
23
64
|
export type CallState = 'initiated' | 'ringing' | 'answered' | 'active' | 'speaking' | 'listening' | 'completed' | 'hangup-user' | 'hangup-bot' | 'timeout' | 'error' | 'failed' | 'no-answer' | 'busy' | 'voicemail';
|
|
24
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Set of terminal call states -- once reached, no further transitions are
|
|
67
|
+
* allowed by the {@link CallManager} state machine.
|
|
68
|
+
*
|
|
69
|
+
* Used for guard checks: `if (TERMINAL_CALL_STATES.has(call.state)) return;`
|
|
70
|
+
*/
|
|
25
71
|
export declare const TERMINAL_CALL_STATES: Set<CallState>;
|
|
26
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* States that can cycle during multi-turn conversations.
|
|
74
|
+
*
|
|
75
|
+
* The state machine allows free transitions between these two states so that
|
|
76
|
+
* the agent can alternate between speaking and listening without violating
|
|
77
|
+
* monotonic ordering.
|
|
78
|
+
*/
|
|
27
79
|
export declare const CONVERSATION_STATES: Set<CallState>;
|
|
28
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* Non-terminal state order for monotonic transition enforcement.
|
|
82
|
+
*
|
|
83
|
+
* The {@link CallManager} only allows a forward transition when
|
|
84
|
+
* `STATE_ORDER.indexOf(newState) > STATE_ORDER.indexOf(currentState)`.
|
|
85
|
+
* This prevents impossible regressions like `answered` -> `ringing`.
|
|
86
|
+
*/
|
|
29
87
|
export declare const STATE_ORDER: readonly CallState[];
|
|
30
88
|
/**
|
|
31
89
|
* How the agent interacts during a call:
|
|
@@ -38,7 +96,7 @@ export type CallMode = 'notify' | 'conversation';
|
|
|
38
96
|
*/
|
|
39
97
|
export type CallDirection = 'outbound' | 'inbound';
|
|
40
98
|
/**
|
|
41
|
-
* Inbound call policy
|
|
99
|
+
* Inbound call policy -- how the agent handles incoming calls.
|
|
42
100
|
* - `disabled`: Reject all inbound calls.
|
|
43
101
|
* - `allowlist`: Only accept from allowed numbers.
|
|
44
102
|
* - `pairing`: Accept and pair with agent owner.
|
|
@@ -59,7 +117,7 @@ export interface TranscriptEntry {
|
|
|
59
117
|
/** Opaque call identifier. */
|
|
60
118
|
export type CallId = string;
|
|
61
119
|
/**
|
|
62
|
-
* Full record of a voice call
|
|
120
|
+
* Full record of a voice call -- used for tracking, persistence, and status queries.
|
|
63
121
|
*/
|
|
64
122
|
export interface CallRecord {
|
|
65
123
|
/** Unique call identifier (UUID). */
|
|
@@ -97,9 +155,22 @@ export interface CallRecord {
|
|
|
97
155
|
}
|
|
98
156
|
/**
|
|
99
157
|
* Normalized webhook event from any telephony provider.
|
|
100
|
-
*
|
|
158
|
+
*
|
|
159
|
+
* Uses a discriminated union on the `kind` field so consumers can narrow
|
|
160
|
+
* with a `switch (event.kind)` and get full type safety for each variant's
|
|
161
|
+
* payload.
|
|
162
|
+
*
|
|
163
|
+
* Provider-specific webhook formats (Twilio form-encoded, Telnyx JSON,
|
|
164
|
+
* Plivo URL-encoded/JSON) are all mapped into these canonical shapes by
|
|
165
|
+
* each provider's {@link IVoiceCallProvider.parseWebhookEvent} implementation.
|
|
101
166
|
*/
|
|
102
167
|
export type NormalizedCallEvent = NormalizedCallRinging | NormalizedCallAnswered | NormalizedCallCompleted | NormalizedCallFailed | NormalizedCallBusy | NormalizedCallNoAnswer | NormalizedCallVoicemail | NormalizedCallHangupUser | NormalizedCallError | NormalizedTranscript | NormalizedSpeechStart | NormalizedMediaStreamConnected | NormalizedDtmfReceived;
|
|
168
|
+
/**
|
|
169
|
+
* Common fields shared by every normalized event variant.
|
|
170
|
+
*
|
|
171
|
+
* These fields enable idempotent processing ({@link eventId}), call record
|
|
172
|
+
* lookup ({@link providerCallId}), and chronological ordering ({@link timestamp}).
|
|
173
|
+
*/
|
|
103
174
|
interface NormalizedEventBase {
|
|
104
175
|
/** Provider-assigned event ID for idempotency. */
|
|
105
176
|
eventId: string;
|
|
@@ -108,57 +179,113 @@ interface NormalizedEventBase {
|
|
|
108
179
|
/** Unix timestamp (ms). */
|
|
109
180
|
timestamp: number;
|
|
110
181
|
}
|
|
182
|
+
/** The destination phone is ringing. */
|
|
111
183
|
export interface NormalizedCallRinging extends NormalizedEventBase {
|
|
112
184
|
kind: 'call-ringing';
|
|
113
185
|
}
|
|
186
|
+
/** The callee answered the call. */
|
|
114
187
|
export interface NormalizedCallAnswered extends NormalizedEventBase {
|
|
115
188
|
kind: 'call-answered';
|
|
116
189
|
}
|
|
190
|
+
/** The call completed normally. */
|
|
117
191
|
export interface NormalizedCallCompleted extends NormalizedEventBase {
|
|
118
192
|
kind: 'call-completed';
|
|
193
|
+
/** Call duration in seconds, if reported by the provider. */
|
|
119
194
|
duration?: number;
|
|
120
195
|
}
|
|
196
|
+
/** The provider could not place or maintain the call. */
|
|
121
197
|
export interface NormalizedCallFailed extends NormalizedEventBase {
|
|
122
198
|
kind: 'call-failed';
|
|
199
|
+
/** Human-readable failure reason from the provider. */
|
|
123
200
|
reason?: string;
|
|
124
201
|
}
|
|
202
|
+
/** The callee's line is busy. */
|
|
125
203
|
export interface NormalizedCallBusy extends NormalizedEventBase {
|
|
126
204
|
kind: 'call-busy';
|
|
127
205
|
}
|
|
206
|
+
/** The callee did not answer within the ring timeout. */
|
|
128
207
|
export interface NormalizedCallNoAnswer extends NormalizedEventBase {
|
|
129
208
|
kind: 'call-no-answer';
|
|
130
209
|
}
|
|
210
|
+
/** Voicemail / answering machine detected (via AMD or similar). */
|
|
131
211
|
export interface NormalizedCallVoicemail extends NormalizedEventBase {
|
|
132
212
|
kind: 'call-voicemail';
|
|
133
213
|
}
|
|
214
|
+
/** The remote caller (user) hung up the call. */
|
|
134
215
|
export interface NormalizedCallHangupUser extends NormalizedEventBase {
|
|
135
216
|
kind: 'call-hangup-user';
|
|
136
217
|
}
|
|
218
|
+
/** An unrecoverable error occurred during the call. */
|
|
137
219
|
export interface NormalizedCallError extends NormalizedEventBase {
|
|
138
220
|
kind: 'call-error';
|
|
221
|
+
/** Error description. */
|
|
139
222
|
error: string;
|
|
140
223
|
}
|
|
224
|
+
/** A speech-to-text transcript segment (partial or final). */
|
|
141
225
|
export interface NormalizedTranscript extends NormalizedEventBase {
|
|
142
226
|
kind: 'transcript';
|
|
227
|
+
/** The transcribed text. */
|
|
143
228
|
text: string;
|
|
229
|
+
/** Whether this is a finalized transcript (vs. in-progress partial). */
|
|
144
230
|
isFinal: boolean;
|
|
145
231
|
}
|
|
232
|
+
/** The caller started speaking (voice activity detection trigger). */
|
|
146
233
|
export interface NormalizedSpeechStart extends NormalizedEventBase {
|
|
147
234
|
kind: 'speech-start';
|
|
148
235
|
}
|
|
236
|
+
/** A bidirectional media stream WebSocket has connected successfully. */
|
|
149
237
|
export interface NormalizedMediaStreamConnected extends NormalizedEventBase {
|
|
150
238
|
kind: 'media-stream-connected';
|
|
239
|
+
/** Provider-assigned stream identifier for routing audio frames. */
|
|
151
240
|
streamSid: string;
|
|
152
241
|
}
|
|
153
|
-
/**
|
|
242
|
+
/**
|
|
243
|
+
* DTMF (Dual-Tone Multi-Frequency) digit received during a call.
|
|
244
|
+
*
|
|
245
|
+
* DTMF events do NOT trigger a call state transition -- the call remains in
|
|
246
|
+
* its current state (typically `listening` or `active`). They are relayed as
|
|
247
|
+
* informational events so higher-level logic (e.g., IVR menus, PIN entry)
|
|
248
|
+
* can react to caller key-presses.
|
|
249
|
+
*
|
|
250
|
+
* ## Provider behavior differences
|
|
251
|
+
* - **Twilio**: DTMF arrives both via `<Gather>` webhook callbacks (as `Digits`
|
|
252
|
+
* param) and via the media stream WebSocket (as `dtmf` events with duration).
|
|
253
|
+
* - **Telnyx**: DTMF arrives only via `call.dtmf.received` HTTP webhooks --
|
|
254
|
+
* never over the media stream WebSocket.
|
|
255
|
+
* - **Plivo**: DTMF arrives via `<GetDigits>` XML callback (as `Digits` param)
|
|
256
|
+
* in webhook POST bodies.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* if (event.kind === 'call-dtmf') {
|
|
261
|
+
* console.log(`User pressed ${event.digit} for ${event.durationMs}ms`);
|
|
262
|
+
* }
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
154
265
|
export interface NormalizedDtmfReceived extends NormalizedEventBase {
|
|
155
266
|
kind: 'call-dtmf';
|
|
156
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* The digit pressed by the caller.
|
|
269
|
+
*
|
|
270
|
+
* Standard DTMF digits: `'0'`-`'9'`, `'*'`, `'#'`.
|
|
271
|
+
* Extended DTMF (rarely supported): `'A'`-`'D'`.
|
|
272
|
+
*/
|
|
157
273
|
digit: string;
|
|
158
|
-
/**
|
|
274
|
+
/**
|
|
275
|
+
* How long the key was pressed in milliseconds, when available.
|
|
276
|
+
*
|
|
277
|
+
* Not all providers report duration -- Twilio's media stream includes it,
|
|
278
|
+
* but Telnyx and Plivo webhook payloads typically omit it.
|
|
279
|
+
*/
|
|
159
280
|
durationMs?: number;
|
|
160
281
|
}
|
|
161
|
-
/**
|
|
282
|
+
/**
|
|
283
|
+
* Raw webhook context passed to provider verification.
|
|
284
|
+
*
|
|
285
|
+
* Encapsulates everything a provider needs to verify a webhook's authenticity
|
|
286
|
+
* and parse its payload, without coupling to any specific HTTP framework
|
|
287
|
+
* (Express, Fastify, Koa, etc.).
|
|
288
|
+
*/
|
|
162
289
|
export interface WebhookContext {
|
|
163
290
|
/** HTTP method (usually POST). */
|
|
164
291
|
method: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"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"}
|
package/dist/voice/types.js
CHANGED
|
@@ -5,12 +5,31 @@
|
|
|
5
5
|
* providers (Twilio, Telnyx, Plivo). This module defines the call lifecycle
|
|
6
6
|
* state machine, event types, and configuration.
|
|
7
7
|
*
|
|
8
|
+
* ## Call lifecycle state machine
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* ┌──────────────────────────────────────────────┐
|
|
12
|
+
* │ Terminal states │
|
|
13
|
+
* │ completed | hangup-user | hangup-bot │
|
|
14
|
+
* │ timeout | error | failed | no-answer │
|
|
15
|
+
* │ busy | voicemail │
|
|
16
|
+
* └───────────────────────────────────────▲──────┘
|
|
17
|
+
* │ (from any non-terminal)
|
|
18
|
+
* initiated ──► ringing ──► answered ──► active ──► speaking ◄──► listening
|
|
19
|
+
* (monotonic forward-only) (can cycle)
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
8
22
|
* Modeled after OpenClaw's voice-call extension architecture with adaptations
|
|
9
23
|
* for the AgentOS extension pack pattern.
|
|
10
24
|
*
|
|
11
25
|
* @module @framers/agentos/voice/types
|
|
12
26
|
*/
|
|
13
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Set of terminal call states -- once reached, no further transitions are
|
|
29
|
+
* allowed by the {@link CallManager} state machine.
|
|
30
|
+
*
|
|
31
|
+
* Used for guard checks: `if (TERMINAL_CALL_STATES.has(call.state)) return;`
|
|
32
|
+
*/
|
|
14
33
|
export const TERMINAL_CALL_STATES = new Set([
|
|
15
34
|
'completed',
|
|
16
35
|
'hangup-user',
|
|
@@ -22,9 +41,21 @@ export const TERMINAL_CALL_STATES = new Set([
|
|
|
22
41
|
'busy',
|
|
23
42
|
'voicemail',
|
|
24
43
|
]);
|
|
25
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* States that can cycle during multi-turn conversations.
|
|
46
|
+
*
|
|
47
|
+
* The state machine allows free transitions between these two states so that
|
|
48
|
+
* the agent can alternate between speaking and listening without violating
|
|
49
|
+
* monotonic ordering.
|
|
50
|
+
*/
|
|
26
51
|
export const CONVERSATION_STATES = new Set(['speaking', 'listening']);
|
|
27
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Non-terminal state order for monotonic transition enforcement.
|
|
54
|
+
*
|
|
55
|
+
* The {@link CallManager} only allows a forward transition when
|
|
56
|
+
* `STATE_ORDER.indexOf(newState) > STATE_ORDER.indexOf(currentState)`.
|
|
57
|
+
* This prevents impossible regressions like `answered` -> `ringing`.
|
|
58
|
+
*/
|
|
28
59
|
export const STATE_ORDER = [
|
|
29
60
|
'initiated',
|
|
30
61
|
'ringing',
|
package/dist/voice/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/voice/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAyEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAY;IACrD,WAAW;IACX,aAAa;IACb,YAAY;IACZ,SAAS;IACT,OAAO;IACP,QAAQ;IACR,WAAW;IACX,MAAM;IACN,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C,WAAW;IACX,SAAS;IACT,UAAU;IACV,QAAQ;IACR,UAAU;IACV,WAAW;CACZ,CAAC"}
|