@framers/agentos 0.1.75 → 0.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -34
- package/dist/core/agency/AgentCommunicationBus.d.ts +1 -0
- package/dist/core/agency/AgentCommunicationBus.d.ts.map +1 -1
- package/dist/core/agency/AgentCommunicationBus.js +62 -8
- package/dist/core/agency/AgentCommunicationBus.js.map +1 -1
- package/dist/core/agency/IAgentCommunicationBus.d.ts +1 -1
- package/dist/core/agency/IAgentCommunicationBus.d.ts.map +1 -1
- package/dist/orchestration/runtime/LoopController.d.ts +10 -10
- package/dist/orchestration/runtime/LoopController.d.ts.map +1 -1
- package/dist/orchestration/runtime/LoopController.js +1 -1
- package/dist/orchestration/runtime/LoopController.js.map +1 -1
- package/dist/orchestration/runtime/index.d.ts +1 -1
- package/dist/orchestration/runtime/index.d.ts.map +1 -1
- package/dist/orchestration/runtime/index.js.map +1 -1
- package/dist/speech/FallbackProxy.d.ts +104 -0
- package/dist/speech/FallbackProxy.d.ts.map +1 -0
- package/dist/speech/FallbackProxy.js +151 -0
- package/dist/speech/FallbackProxy.js.map +1 -0
- package/dist/speech/SpeechProviderResolver.d.ts +103 -0
- package/dist/speech/SpeechProviderResolver.d.ts.map +1 -0
- package/dist/speech/SpeechProviderResolver.js +256 -0
- package/dist/speech/SpeechProviderResolver.js.map +1 -0
- package/dist/speech/SpeechRuntime.d.ts +23 -1
- package/dist/speech/SpeechRuntime.d.ts.map +1 -1
- package/dist/speech/SpeechRuntime.js +82 -8
- package/dist/speech/SpeechRuntime.js.map +1 -1
- package/dist/speech/index.d.ts +6 -0
- package/dist/speech/index.d.ts.map +1 -1
- package/dist/speech/index.js +6 -0
- package/dist/speech/index.js.map +1 -1
- package/dist/speech/providerCatalog.d.ts.map +1 -1
- package/dist/speech/providerCatalog.js +15 -1
- package/dist/speech/providerCatalog.js.map +1 -1
- package/dist/speech/providers/AssemblyAISTTProvider.d.ts +49 -0
- package/dist/speech/providers/AssemblyAISTTProvider.d.ts.map +1 -0
- package/dist/speech/providers/AssemblyAISTTProvider.js +151 -0
- package/dist/speech/providers/AssemblyAISTTProvider.js.map +1 -0
- package/dist/speech/providers/AzureSpeechSTTProvider.d.ts +48 -0
- package/dist/speech/providers/AzureSpeechSTTProvider.d.ts.map +1 -0
- package/dist/speech/providers/AzureSpeechSTTProvider.js +90 -0
- package/dist/speech/providers/AzureSpeechSTTProvider.js.map +1 -0
- package/dist/speech/providers/AzureSpeechTTSProvider.d.ts +60 -0
- package/dist/speech/providers/AzureSpeechTTSProvider.d.ts.map +1 -0
- package/dist/speech/providers/AzureSpeechTTSProvider.js +127 -0
- package/dist/speech/providers/AzureSpeechTTSProvider.js.map +1 -0
- package/dist/speech/providers/DeepgramBatchSTTProvider.d.ts +55 -0
- package/dist/speech/providers/DeepgramBatchSTTProvider.d.ts.map +1 -0
- package/dist/speech/providers/DeepgramBatchSTTProvider.js +102 -0
- package/dist/speech/providers/DeepgramBatchSTTProvider.js.map +1 -0
- package/dist/speech/types.d.ts +35 -0
- package/dist/speech/types.d.ts.map +1 -1
- package/dist/voice/CallManager.d.ts +1 -1
- package/dist/voice/CallManager.d.ts.map +1 -1
- package/dist/voice/CallManager.js +9 -0
- package/dist/voice/CallManager.js.map +1 -1
- package/dist/voice/MediaStreamParser.d.ts +83 -0
- package/dist/voice/MediaStreamParser.d.ts.map +1 -0
- package/dist/voice/MediaStreamParser.js +2 -0
- package/dist/voice/MediaStreamParser.js.map +1 -0
- package/dist/voice/TelephonyStreamTransport.d.ts +112 -0
- package/dist/voice/TelephonyStreamTransport.d.ts.map +1 -0
- package/dist/voice/TelephonyStreamTransport.js +208 -0
- package/dist/voice/TelephonyStreamTransport.js.map +1 -0
- package/dist/voice/index.d.ts +10 -0
- package/dist/voice/index.d.ts.map +1 -1
- package/dist/voice/index.js +11 -0
- package/dist/voice/index.js.map +1 -1
- package/dist/voice/parsers/PlivoMediaStreamParser.d.ts +43 -0
- package/dist/voice/parsers/PlivoMediaStreamParser.d.ts.map +1 -0
- package/dist/voice/parsers/PlivoMediaStreamParser.js +92 -0
- package/dist/voice/parsers/PlivoMediaStreamParser.js.map +1 -0
- package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts +51 -0
- package/dist/voice/parsers/TelnyxMediaStreamParser.d.ts.map +1 -0
- package/dist/voice/parsers/TelnyxMediaStreamParser.js +103 -0
- package/dist/voice/parsers/TelnyxMediaStreamParser.js.map +1 -0
- package/dist/voice/parsers/TwilioMediaStreamParser.d.ts +50 -0
- package/dist/voice/parsers/TwilioMediaStreamParser.d.ts.map +1 -0
- package/dist/voice/parsers/TwilioMediaStreamParser.js +144 -0
- package/dist/voice/parsers/TwilioMediaStreamParser.js.map +1 -0
- package/dist/voice/providers/plivo.d.ts +77 -0
- package/dist/voice/providers/plivo.d.ts.map +1 -0
- package/dist/voice/providers/plivo.js +180 -0
- package/dist/voice/providers/plivo.js.map +1 -0
- package/dist/voice/providers/telnyx.d.ts +93 -0
- package/dist/voice/providers/telnyx.d.ts.map +1 -0
- package/dist/voice/providers/telnyx.js +193 -0
- package/dist/voice/providers/telnyx.js.map +1 -0
- package/dist/voice/providers/twilio.d.ts +79 -0
- package/dist/voice/providers/twilio.d.ts.map +1 -0
- package/dist/voice/providers/twilio.js +191 -0
- package/dist/voice/providers/twilio.js.map +1 -0
- package/dist/voice/twiml.d.ts +69 -0
- package/dist/voice/twiml.d.ts.map +1 -0
- package/dist/voice/twiml.js +92 -0
- package/dist/voice/twiml.js.map +1 -0
- package/dist/voice/types.d.ts +9 -1
- package/dist/voice/types.d.ts.map +1 -1
- package/dist/voice-pipeline/AcousticEndpointDetector.d.ts +90 -0
- package/dist/voice-pipeline/AcousticEndpointDetector.d.ts.map +1 -0
- package/dist/voice-pipeline/AcousticEndpointDetector.js +123 -0
- package/dist/voice-pipeline/AcousticEndpointDetector.js.map +1 -0
- package/dist/voice-pipeline/HardCutBargeinHandler.d.ts +67 -0
- package/dist/voice-pipeline/HardCutBargeinHandler.d.ts.map +1 -0
- package/dist/voice-pipeline/HardCutBargeinHandler.js +55 -0
- package/dist/voice-pipeline/HardCutBargeinHandler.js.map +1 -0
- package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts +128 -0
- package/dist/voice-pipeline/HeuristicEndpointDetector.d.ts.map +1 -0
- package/dist/voice-pipeline/HeuristicEndpointDetector.js +240 -0
- package/dist/voice-pipeline/HeuristicEndpointDetector.js.map +1 -0
- package/dist/voice-pipeline/SoftFadeBargeinHandler.d.ts +96 -0
- package/dist/voice-pipeline/SoftFadeBargeinHandler.d.ts.map +1 -0
- package/dist/voice-pipeline/SoftFadeBargeinHandler.js +69 -0
- package/dist/voice-pipeline/SoftFadeBargeinHandler.js.map +1 -0
- package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts +122 -0
- package/dist/voice-pipeline/VoicePipelineOrchestrator.d.ts.map +1 -0
- package/dist/voice-pipeline/VoicePipelineOrchestrator.js +317 -0
- package/dist/voice-pipeline/VoicePipelineOrchestrator.js.map +1 -0
- package/dist/voice-pipeline/WebSocketStreamTransport.d.ts +148 -0
- package/dist/voice-pipeline/WebSocketStreamTransport.d.ts.map +1 -0
- package/dist/voice-pipeline/WebSocketStreamTransport.js +207 -0
- package/dist/voice-pipeline/WebSocketStreamTransport.js.map +1 -0
- package/dist/voice-pipeline/index.d.ts +13 -0
- package/dist/voice-pipeline/index.d.ts.map +1 -0
- package/dist/voice-pipeline/index.js +13 -0
- package/dist/voice-pipeline/index.js.map +1 -0
- package/dist/voice-pipeline/types.d.ts +905 -0
- package/dist/voice-pipeline/types.d.ts.map +1 -0
- package/dist/voice-pipeline/types.js +23 -0
- package/dist/voice-pipeline/types.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/SoftFadeBargeinHandler
|
|
3
|
+
*
|
|
4
|
+
* Implements a three-tier soft-fade barge-in policy.
|
|
5
|
+
*
|
|
6
|
+
* Very short speech detections (< `ignoreMs`) are dismissed as noise.
|
|
7
|
+
* Medium-length detections trigger a fade-out pause so the user can speak
|
|
8
|
+
* without an abrupt cut. Long detections (>= `cancelMs`) stop playback
|
|
9
|
+
* outright and inject a conversation marker.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Barge-in handler that applies a three-tier soft-fade strategy.
|
|
13
|
+
*
|
|
14
|
+
* The handler maps the confirmed speech duration to one of three actions:
|
|
15
|
+
*
|
|
16
|
+
* | Speech duration | Action |
|
|
17
|
+
* |--------------------------|---------------------------------------------|
|
|
18
|
+
* | `< ignoreMs` | `ignore` — noise, continue TTS uninterrupted |
|
|
19
|
+
* | `>= ignoreMs < cancelMs` | `pause` with `fadeMs` fade-out |
|
|
20
|
+
* | `>= cancelMs` | `cancel` with `'[interrupted]'` marker |
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const handler = new SoftFadeBargeinHandler({ ignoreMs: 80, cancelMs: 1500, fadeMs: 150 });
|
|
25
|
+
* handler.handleBargein({ speechDurationMs: 500, ... }); // { type: 'pause', fadeMs: 150 }
|
|
26
|
+
* handler.handleBargein({ speechDurationMs: 1600, ... }); // { type: 'cancel', injectMarker: '[interrupted]' }
|
|
27
|
+
* handler.handleBargein({ speechDurationMs: 30, ... }); // { type: 'ignore' }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class SoftFadeBargeinHandler {
|
|
31
|
+
/**
|
|
32
|
+
* Constructs a new {@link SoftFadeBargeinHandler}.
|
|
33
|
+
*
|
|
34
|
+
* @param options - Optional configuration. Defaults to
|
|
35
|
+
* `{ ignoreMs: 100, cancelMs: 2000, fadeMs: 200 }`.
|
|
36
|
+
*/
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
/**
|
|
39
|
+
* The interruption strategy implemented by this handler.
|
|
40
|
+
* Always `'soft-fade'`.
|
|
41
|
+
*/
|
|
42
|
+
this.mode = 'soft-fade';
|
|
43
|
+
this.ignoreMs = options.ignoreMs ?? 100;
|
|
44
|
+
this.cancelMs = options.cancelMs ?? 2000;
|
|
45
|
+
this.fadeMs = options.fadeMs ?? 200;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Evaluate the barge-in context and return the pipeline action.
|
|
49
|
+
*
|
|
50
|
+
* Decision tree (evaluated in order):
|
|
51
|
+
* 1. `speechDurationMs < ignoreMs` → `{ type: 'ignore' }`
|
|
52
|
+
* 2. `speechDurationMs >= cancelMs` → `{ type: 'cancel', injectMarker: '[interrupted]' }`
|
|
53
|
+
* 3. Otherwise → `{ type: 'pause', fadeMs }`
|
|
54
|
+
*
|
|
55
|
+
* @param context - Snapshot of the barge-in state at the moment of detection.
|
|
56
|
+
* @returns The pipeline action to execute.
|
|
57
|
+
*/
|
|
58
|
+
handleBargein(context) {
|
|
59
|
+
const { speechDurationMs } = context;
|
|
60
|
+
if (speechDurationMs < this.ignoreMs) {
|
|
61
|
+
return { type: 'ignore' };
|
|
62
|
+
}
|
|
63
|
+
if (speechDurationMs >= this.cancelMs) {
|
|
64
|
+
return { type: 'cancel', injectMarker: '[interrupted]' };
|
|
65
|
+
}
|
|
66
|
+
return { type: 'pause', fadeMs: this.fadeMs };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=SoftFadeBargeinHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SoftFadeBargeinHandler.js","sourceRoot":"","sources":["../../src/voice-pipeline/SoftFadeBargeinHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,sBAAsB;IAsBjC;;;;;OAKG;IACH,YAAY,UAAyC,EAAE;QA3BvD;;;WAGG;QACM,SAAI,GAAG,WAAoB,CAAC;QAwBnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;IACtC,CAAC;IAED;;;;;;;;;;OAUG;IACH,aAAa,CAAC,OAAuB;QACnC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;QAErC,IAAI,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,gBAAgB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;QAC3D,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/VoicePipelineOrchestrator
|
|
3
|
+
*
|
|
4
|
+
* Central state machine that wires together transport, STT, endpoint detection,
|
|
5
|
+
* TTS, barge-in handling, and the agent session into a coordinated real-time
|
|
6
|
+
* voice conversation loop.
|
|
7
|
+
*
|
|
8
|
+
* State transitions:
|
|
9
|
+
* ```
|
|
10
|
+
* IDLE → startSession() → LISTENING
|
|
11
|
+
* LISTENING → turn_complete → PROCESSING
|
|
12
|
+
* PROCESSING → LLM tokens start → SPEAKING
|
|
13
|
+
* SPEAKING → TTS complete → LISTENING
|
|
14
|
+
* SPEAKING → barge-in → INTERRUPTING → LISTENING
|
|
15
|
+
* ANY → transport disconnect → CLOSED
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { EventEmitter } from 'node:events';
|
|
19
|
+
import type { IBargeinHandler, IDiarizationEngine, IEndpointDetector, IStreamTransport, IStreamingSTT, IStreamingTTS, IVoicePipelineAgentSession, PipelineState, VoicePipelineConfig, VoicePipelineSession } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Overrides for injecting pre-built components (primarily for testing).
|
|
22
|
+
* In production, components would be resolved from ExtensionManager.
|
|
23
|
+
*/
|
|
24
|
+
export interface VoicePipelineOverrides {
|
|
25
|
+
/** Pre-built streaming STT provider. */
|
|
26
|
+
streamingSTT?: IStreamingSTT;
|
|
27
|
+
/** Pre-built streaming TTS provider. */
|
|
28
|
+
streamingTTS?: IStreamingTTS;
|
|
29
|
+
/** Pre-built endpoint detector. */
|
|
30
|
+
endpointDetector?: IEndpointDetector;
|
|
31
|
+
/** Pre-built barge-in handler. */
|
|
32
|
+
bargeinHandler?: IBargeinHandler;
|
|
33
|
+
/** Pre-built diarization engine. */
|
|
34
|
+
diarizationEngine?: IDiarizationEngine;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* VoicePipelineOrchestrator is the central state machine for the AgentOS
|
|
38
|
+
* streaming voice pipeline. It coordinates audio capture, speech recognition,
|
|
39
|
+
* endpoint detection, agent inference, text-to-speech synthesis, and barge-in
|
|
40
|
+
* handling into a seamless real-time conversation loop.
|
|
41
|
+
*
|
|
42
|
+
* Emits:
|
|
43
|
+
* - `'state_changed'` ({ from: PipelineState, to: PipelineState })
|
|
44
|
+
*/
|
|
45
|
+
export declare class VoicePipelineOrchestrator extends EventEmitter {
|
|
46
|
+
private readonly config;
|
|
47
|
+
/** Current pipeline state. */
|
|
48
|
+
private _state;
|
|
49
|
+
/** Active sub-sessions and components, set during startSession. */
|
|
50
|
+
private _sttSession;
|
|
51
|
+
private _ttsSession;
|
|
52
|
+
private _endpointDetector;
|
|
53
|
+
private _bargeinHandler;
|
|
54
|
+
private _transport;
|
|
55
|
+
private _agentSession;
|
|
56
|
+
/** Watchdog timer ID for max turn duration. */
|
|
57
|
+
private _watchdogTimer;
|
|
58
|
+
/** Tracks cumulative TTS text for barge-in context. */
|
|
59
|
+
private _currentTTSText;
|
|
60
|
+
/** Tracks cumulative played duration for barge-in context. */
|
|
61
|
+
private _currentPlayedMs;
|
|
62
|
+
/** Current pipeline state (read-only). */
|
|
63
|
+
get state(): PipelineState;
|
|
64
|
+
constructor(config: VoicePipelineConfig);
|
|
65
|
+
/**
|
|
66
|
+
* Start a voice session. Accepts pre-built components via overrides for testing.
|
|
67
|
+
* In production, components are resolved from ExtensionManager (future task).
|
|
68
|
+
*
|
|
69
|
+
* @param transport - The bidirectional audio/text stream transport.
|
|
70
|
+
* @param agentSession - The agent session adapter for turn-based conversation.
|
|
71
|
+
* @param overrides - Optional pre-built components (for testing or manual wiring).
|
|
72
|
+
* @returns A live VoicePipelineSession object.
|
|
73
|
+
*/
|
|
74
|
+
startSession(transport: IStreamTransport, agentSession: IVoicePipelineAgentSession, overrides?: VoicePipelineOverrides): Promise<VoicePipelineSession>;
|
|
75
|
+
/**
|
|
76
|
+
* Stop the current session, tearing down all sub-sessions and timers.
|
|
77
|
+
*
|
|
78
|
+
* @param reason - Optional human-readable reason for diagnostics.
|
|
79
|
+
*/
|
|
80
|
+
stopSession(reason?: string): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Forward audio frames from transport to STT session.
|
|
83
|
+
*/
|
|
84
|
+
private _wireTransportToSTT;
|
|
85
|
+
/**
|
|
86
|
+
* Forward STT transcript events to endpoint detector and transport.
|
|
87
|
+
*/
|
|
88
|
+
private _wireSTTToEndpoint;
|
|
89
|
+
/**
|
|
90
|
+
* Handle turn_complete from endpoint detector — transition through
|
|
91
|
+
* PROCESSING → SPEAKING → LISTENING.
|
|
92
|
+
*/
|
|
93
|
+
private _wireTurnComplete;
|
|
94
|
+
/**
|
|
95
|
+
* Forward TTS audio chunks to the transport and handle utterance completion.
|
|
96
|
+
*/
|
|
97
|
+
private _wireTTSToTransport;
|
|
98
|
+
/**
|
|
99
|
+
* Wire barge-in detection: when speech is detected during SPEAKING state,
|
|
100
|
+
* consult the barge-in handler and act accordingly.
|
|
101
|
+
*/
|
|
102
|
+
private _wireBargein;
|
|
103
|
+
/**
|
|
104
|
+
* Handle transport disconnect — close everything.
|
|
105
|
+
*/
|
|
106
|
+
private _wireDisconnect;
|
|
107
|
+
/**
|
|
108
|
+
* Transition to a new pipeline state, emitting a `state_changed` event.
|
|
109
|
+
*/
|
|
110
|
+
private _setState;
|
|
111
|
+
/**
|
|
112
|
+
* Reset the watchdog timer for max turn duration. If the pipeline stays in
|
|
113
|
+
* LISTENING for longer than `maxTurnDurationMs` (default 30s) without a
|
|
114
|
+
* turn_complete, force a timeout.
|
|
115
|
+
*/
|
|
116
|
+
private _resetWatchdog;
|
|
117
|
+
/**
|
|
118
|
+
* Clear the watchdog timer if active.
|
|
119
|
+
*/
|
|
120
|
+
private _clearWatchdog;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=VoicePipelineOrchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoicePipelineOrchestrator.d.ts","sourceRoot":"","sources":["../../src/voice-pipeline/VoicePipelineOrchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAGV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,aAAa,EAKb,mBAAmB,EACnB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,wCAAwC;IACxC,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,kCAAkC;IAClC,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,oCAAoC;IACpC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,qBAAa,yBAA0B,SAAQ,YAAY;IA0B7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAzBnC,8BAA8B;IAC9B,OAAO,CAAC,MAAM,CAAyB;IAEvC,mEAAmE;IACnE,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,aAAa,CAA2C;IAEhE,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAA8C;IAEpE,uDAAuD;IACvD,OAAO,CAAC,eAAe,CAAM;IAE7B,8DAA8D;IAC9D,OAAO,CAAC,gBAAgB,CAAK;IAE7B,0CAA0C;IAC1C,IAAI,KAAK,IAAI,aAAa,CAEzB;gBAE4B,MAAM,EAAE,mBAAmB;IAIxD;;;;;;;;OAQG;IACG,YAAY,CAChB,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EAAE,0BAA0B,EACxC,SAAS,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,oBAAoB,CAAC;IAgEhC;;;;OAIG;IACG,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAuCzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyB3B;;;OAGG;IACH,OAAO,CAAC,YAAY;IA8CpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,cAAc;CAMvB"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module voice-pipeline/VoicePipelineOrchestrator
|
|
3
|
+
*
|
|
4
|
+
* Central state machine that wires together transport, STT, endpoint detection,
|
|
5
|
+
* TTS, barge-in handling, and the agent session into a coordinated real-time
|
|
6
|
+
* voice conversation loop.
|
|
7
|
+
*
|
|
8
|
+
* State transitions:
|
|
9
|
+
* ```
|
|
10
|
+
* IDLE → startSession() → LISTENING
|
|
11
|
+
* LISTENING → turn_complete → PROCESSING
|
|
12
|
+
* PROCESSING → LLM tokens start → SPEAKING
|
|
13
|
+
* SPEAKING → TTS complete → LISTENING
|
|
14
|
+
* SPEAKING → barge-in → INTERRUPTING → LISTENING
|
|
15
|
+
* ANY → transport disconnect → CLOSED
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { EventEmitter } from 'node:events';
|
|
19
|
+
import { randomUUID } from 'node:crypto';
|
|
20
|
+
/**
|
|
21
|
+
* VoicePipelineOrchestrator is the central state machine for the AgentOS
|
|
22
|
+
* streaming voice pipeline. It coordinates audio capture, speech recognition,
|
|
23
|
+
* endpoint detection, agent inference, text-to-speech synthesis, and barge-in
|
|
24
|
+
* handling into a seamless real-time conversation loop.
|
|
25
|
+
*
|
|
26
|
+
* Emits:
|
|
27
|
+
* - `'state_changed'` ({ from: PipelineState, to: PipelineState })
|
|
28
|
+
*/
|
|
29
|
+
export class VoicePipelineOrchestrator extends EventEmitter {
|
|
30
|
+
/** Current pipeline state (read-only). */
|
|
31
|
+
get state() {
|
|
32
|
+
return this._state;
|
|
33
|
+
}
|
|
34
|
+
constructor(config) {
|
|
35
|
+
super();
|
|
36
|
+
this.config = config;
|
|
37
|
+
/** Current pipeline state. */
|
|
38
|
+
this._state = 'idle';
|
|
39
|
+
/** Active sub-sessions and components, set during startSession. */
|
|
40
|
+
this._sttSession = null;
|
|
41
|
+
this._ttsSession = null;
|
|
42
|
+
this._endpointDetector = null;
|
|
43
|
+
this._bargeinHandler = null;
|
|
44
|
+
this._transport = null;
|
|
45
|
+
this._agentSession = null;
|
|
46
|
+
/** Watchdog timer ID for max turn duration. */
|
|
47
|
+
this._watchdogTimer = null;
|
|
48
|
+
/** Tracks cumulative TTS text for barge-in context. */
|
|
49
|
+
this._currentTTSText = '';
|
|
50
|
+
/** Tracks cumulative played duration for barge-in context. */
|
|
51
|
+
this._currentPlayedMs = 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Start a voice session. Accepts pre-built components via overrides for testing.
|
|
55
|
+
* In production, components are resolved from ExtensionManager (future task).
|
|
56
|
+
*
|
|
57
|
+
* @param transport - The bidirectional audio/text stream transport.
|
|
58
|
+
* @param agentSession - The agent session adapter for turn-based conversation.
|
|
59
|
+
* @param overrides - Optional pre-built components (for testing or manual wiring).
|
|
60
|
+
* @returns A live VoicePipelineSession object.
|
|
61
|
+
*/
|
|
62
|
+
async startSession(transport, agentSession, overrides) {
|
|
63
|
+
if (this._state !== 'idle') {
|
|
64
|
+
throw new Error(`Cannot start session in state '${this._state}'; expected 'idle'.`);
|
|
65
|
+
}
|
|
66
|
+
this._transport = transport;
|
|
67
|
+
this._agentSession = agentSession;
|
|
68
|
+
const stt = overrides?.streamingSTT;
|
|
69
|
+
const tts = overrides?.streamingTTS;
|
|
70
|
+
const endpointDetector = overrides?.endpointDetector;
|
|
71
|
+
const bargeinHandler = overrides?.bargeinHandler;
|
|
72
|
+
if (!stt)
|
|
73
|
+
throw new Error('streamingSTT is required (pass via overrides or wait for ExtensionManager support).');
|
|
74
|
+
if (!tts)
|
|
75
|
+
throw new Error('streamingTTS is required (pass via overrides or wait for ExtensionManager support).');
|
|
76
|
+
if (!endpointDetector)
|
|
77
|
+
throw new Error('endpointDetector is required.');
|
|
78
|
+
if (!bargeinHandler)
|
|
79
|
+
throw new Error('bargeinHandler is required.');
|
|
80
|
+
// Create sub-sessions
|
|
81
|
+
const sttSession = await stt.startSession({ language: this.config.language });
|
|
82
|
+
const ttsSession = await tts.startSession({
|
|
83
|
+
voice: this.config.voice,
|
|
84
|
+
format: this.config.format,
|
|
85
|
+
});
|
|
86
|
+
this._sttSession = sttSession;
|
|
87
|
+
this._ttsSession = ttsSession;
|
|
88
|
+
this._endpointDetector = endpointDetector;
|
|
89
|
+
this._bargeinHandler = bargeinHandler;
|
|
90
|
+
// Wire everything up
|
|
91
|
+
this._wireTransportToSTT(transport, sttSession);
|
|
92
|
+
this._wireSTTToEndpoint(sttSession, endpointDetector, transport);
|
|
93
|
+
this._wireTurnComplete(endpointDetector, transport, agentSession, ttsSession);
|
|
94
|
+
this._wireTTSToTransport(ttsSession, transport);
|
|
95
|
+
this._wireBargein(sttSession, ttsSession, bargeinHandler, transport, agentSession);
|
|
96
|
+
this._wireDisconnect(transport, sttSession, ttsSession);
|
|
97
|
+
// Transition to listening
|
|
98
|
+
this._setState('listening');
|
|
99
|
+
// Start watchdog
|
|
100
|
+
this._resetWatchdog();
|
|
101
|
+
// Build and return the VoicePipelineSession object
|
|
102
|
+
const sessionId = randomUUID();
|
|
103
|
+
const orchestrator = this;
|
|
104
|
+
const session = Object.assign(new EventEmitter(), {
|
|
105
|
+
sessionId,
|
|
106
|
+
get state() {
|
|
107
|
+
return orchestrator._state;
|
|
108
|
+
},
|
|
109
|
+
transport,
|
|
110
|
+
async close(reason) {
|
|
111
|
+
await orchestrator.stopSession(reason);
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
// Forward state_changed events to the session
|
|
115
|
+
this.on('state_changed', (evt) => session.emit('state_change', evt.to));
|
|
116
|
+
return session;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Stop the current session, tearing down all sub-sessions and timers.
|
|
120
|
+
*
|
|
121
|
+
* @param reason - Optional human-readable reason for diagnostics.
|
|
122
|
+
*/
|
|
123
|
+
async stopSession(reason) {
|
|
124
|
+
if (this._state === 'closed')
|
|
125
|
+
return;
|
|
126
|
+
this._clearWatchdog();
|
|
127
|
+
this._sttSession?.close();
|
|
128
|
+
this._ttsSession?.close();
|
|
129
|
+
this._transport?.close(1000, reason);
|
|
130
|
+
this._setState('closed');
|
|
131
|
+
// Clean up references
|
|
132
|
+
this._sttSession = null;
|
|
133
|
+
this._ttsSession = null;
|
|
134
|
+
this._endpointDetector = null;
|
|
135
|
+
this._bargeinHandler = null;
|
|
136
|
+
this._transport = null;
|
|
137
|
+
this._agentSession = null;
|
|
138
|
+
}
|
|
139
|
+
// --------------------------------------------------------------------------
|
|
140
|
+
// Wiring helpers
|
|
141
|
+
// --------------------------------------------------------------------------
|
|
142
|
+
/**
|
|
143
|
+
* Forward audio frames from transport to STT session.
|
|
144
|
+
*/
|
|
145
|
+
_wireTransportToSTT(transport, sttSession) {
|
|
146
|
+
transport.on('audio', (frame) => {
|
|
147
|
+
sttSession.pushAudio(frame);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Forward STT transcript events to endpoint detector and transport.
|
|
152
|
+
*/
|
|
153
|
+
_wireSTTToEndpoint(sttSession, endpointDetector, transport) {
|
|
154
|
+
sttSession.on('transcript', (transcript) => {
|
|
155
|
+
endpointDetector.pushTranscript(transcript);
|
|
156
|
+
transport.sendControl({
|
|
157
|
+
type: 'transcript',
|
|
158
|
+
text: transcript.text,
|
|
159
|
+
isFinal: transcript.isFinal,
|
|
160
|
+
confidence: transcript.confidence,
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Handle turn_complete from endpoint detector — transition through
|
|
166
|
+
* PROCESSING → SPEAKING → LISTENING.
|
|
167
|
+
*/
|
|
168
|
+
_wireTurnComplete(endpointDetector, transport, agentSession, ttsSession) {
|
|
169
|
+
endpointDetector.on('turn_complete', async (event) => {
|
|
170
|
+
if (this._state !== 'listening')
|
|
171
|
+
return;
|
|
172
|
+
this._clearWatchdog();
|
|
173
|
+
this._setState('processing');
|
|
174
|
+
transport.sendControl({ type: 'agent_thinking' });
|
|
175
|
+
const metadata = {
|
|
176
|
+
speakers: [],
|
|
177
|
+
endpointReason: event.reason,
|
|
178
|
+
speechDurationMs: event.durationMs,
|
|
179
|
+
wasInterrupted: false,
|
|
180
|
+
transcriptConfidence: event.confidence,
|
|
181
|
+
};
|
|
182
|
+
const tokenStream = agentSession.sendText(event.transcript, metadata);
|
|
183
|
+
this._setState('speaking');
|
|
184
|
+
this._currentTTSText = '';
|
|
185
|
+
this._currentPlayedMs = 0;
|
|
186
|
+
transport.sendControl({ type: 'agent_speaking', text: '' });
|
|
187
|
+
for await (const token of tokenStream) {
|
|
188
|
+
if (this._state !== 'speaking')
|
|
189
|
+
break; // barge-in happened
|
|
190
|
+
this._currentTTSText += token;
|
|
191
|
+
ttsSession.pushTokens(token);
|
|
192
|
+
}
|
|
193
|
+
if (this._state === 'speaking') {
|
|
194
|
+
await ttsSession.flush();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Forward TTS audio chunks to the transport and handle utterance completion.
|
|
200
|
+
*/
|
|
201
|
+
_wireTTSToTransport(ttsSession, transport) {
|
|
202
|
+
ttsSession.on('audio', (chunk) => {
|
|
203
|
+
if (this._state === 'speaking') {
|
|
204
|
+
this._currentPlayedMs += chunk.durationMs;
|
|
205
|
+
transport.sendAudio(chunk);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
ttsSession.on('flush_complete', () => {
|
|
209
|
+
if (this._state === 'speaking') {
|
|
210
|
+
this._setState('listening');
|
|
211
|
+
transport.sendControl({
|
|
212
|
+
type: 'agent_done',
|
|
213
|
+
text: this._currentTTSText,
|
|
214
|
+
durationMs: this._currentPlayedMs,
|
|
215
|
+
});
|
|
216
|
+
this._endpointDetector?.reset();
|
|
217
|
+
this._resetWatchdog();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Wire barge-in detection: when speech is detected during SPEAKING state,
|
|
223
|
+
* consult the barge-in handler and act accordingly.
|
|
224
|
+
*/
|
|
225
|
+
_wireBargein(sttSession, ttsSession, bargeinHandler, transport, agentSession) {
|
|
226
|
+
sttSession.on('speech_start', async () => {
|
|
227
|
+
// Also push VAD event to endpoint detector
|
|
228
|
+
this._endpointDetector?.pushVadEvent({
|
|
229
|
+
type: 'speech_start',
|
|
230
|
+
timestamp: Date.now(),
|
|
231
|
+
source: 'stt',
|
|
232
|
+
});
|
|
233
|
+
if (this._state === 'speaking') {
|
|
234
|
+
const action = await bargeinHandler.handleBargein({
|
|
235
|
+
speechDurationMs: 0,
|
|
236
|
+
interruptedText: this._currentTTSText,
|
|
237
|
+
playedDurationMs: this._currentPlayedMs,
|
|
238
|
+
});
|
|
239
|
+
if (action.type === 'cancel') {
|
|
240
|
+
this._setState('interrupting');
|
|
241
|
+
ttsSession.cancel();
|
|
242
|
+
agentSession.abort?.();
|
|
243
|
+
transport.sendControl({ type: 'barge_in', action });
|
|
244
|
+
this._setState('listening');
|
|
245
|
+
this._endpointDetector?.reset();
|
|
246
|
+
this._resetWatchdog();
|
|
247
|
+
}
|
|
248
|
+
else if (action.type === 'pause') {
|
|
249
|
+
transport.sendControl({ type: 'barge_in', action });
|
|
250
|
+
}
|
|
251
|
+
// 'ignore' and 'resume' — do nothing
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
sttSession.on('speech_end', () => {
|
|
255
|
+
this._endpointDetector?.pushVadEvent({
|
|
256
|
+
type: 'speech_end',
|
|
257
|
+
timestamp: Date.now(),
|
|
258
|
+
source: 'stt',
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Handle transport disconnect — close everything.
|
|
264
|
+
*/
|
|
265
|
+
_wireDisconnect(transport, sttSession, ttsSession) {
|
|
266
|
+
transport.on('close', () => {
|
|
267
|
+
this._clearWatchdog();
|
|
268
|
+
this._setState('closed');
|
|
269
|
+
sttSession.close();
|
|
270
|
+
ttsSession.close();
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
// --------------------------------------------------------------------------
|
|
274
|
+
// State management
|
|
275
|
+
// --------------------------------------------------------------------------
|
|
276
|
+
/**
|
|
277
|
+
* Transition to a new pipeline state, emitting a `state_changed` event.
|
|
278
|
+
*/
|
|
279
|
+
_setState(state) {
|
|
280
|
+
const from = this._state;
|
|
281
|
+
if (from === state)
|
|
282
|
+
return;
|
|
283
|
+
this._state = state;
|
|
284
|
+
this.emit('state_changed', { from, to: state });
|
|
285
|
+
}
|
|
286
|
+
// --------------------------------------------------------------------------
|
|
287
|
+
// Watchdog timer
|
|
288
|
+
// --------------------------------------------------------------------------
|
|
289
|
+
/**
|
|
290
|
+
* Reset the watchdog timer for max turn duration. If the pipeline stays in
|
|
291
|
+
* LISTENING for longer than `maxTurnDurationMs` (default 30s) without a
|
|
292
|
+
* turn_complete, force a timeout.
|
|
293
|
+
*/
|
|
294
|
+
_resetWatchdog() {
|
|
295
|
+
this._clearWatchdog();
|
|
296
|
+
const maxMs = this.config.maxTurnDurationMs ?? 30000;
|
|
297
|
+
this._watchdogTimer = setTimeout(() => {
|
|
298
|
+
if (this._state === 'listening') {
|
|
299
|
+
this._endpointDetector?.pushVadEvent({
|
|
300
|
+
type: 'speech_end',
|
|
301
|
+
timestamp: Date.now(),
|
|
302
|
+
source: 'vad',
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}, maxMs);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Clear the watchdog timer if active.
|
|
309
|
+
*/
|
|
310
|
+
_clearWatchdog() {
|
|
311
|
+
if (this._watchdogTimer !== null) {
|
|
312
|
+
clearTimeout(this._watchdogTimer);
|
|
313
|
+
this._watchdogTimer = null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=VoicePipelineOrchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoicePipelineOrchestrator.js","sourceRoot":"","sources":["../../src/voice-pipeline/VoicePipelineOrchestrator.ts"],"names":[],"mappings":"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"}
|