@hivegpt/hiveai-angular 0.0.583 → 0.0.585
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/bundles/hivegpt-hiveai-angular.umd.js +239 -547
- package/bundles/hivegpt-hiveai-angular.umd.js.map +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js.map +1 -1
- package/esm2015/hivegpt-hiveai-angular.js +4 -5
- package/esm2015/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.js +17 -24
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +174 -236
- package/esm2015/lib/components/voice-agent/voice-agent.module.js +3 -5
- package/fesm2015/hivegpt-hiveai-angular.js +190 -460
- package/fesm2015/hivegpt-hiveai-angular.js.map +1 -1
- package/hivegpt-hiveai-angular.d.ts +3 -4
- package/hivegpt-hiveai-angular.d.ts.map +1 -1
- package/hivegpt-hiveai-angular.metadata.json +1 -1
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts +7 -4
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts.map +1 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +24 -26
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/lib/components/voice-agent/voice-agent.module.d.ts +2 -2
- package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
- package/package.json +1 -1
- package/esm2015/lib/components/voice-agent/services/websocket-voice-client.service.js +0 -206
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts +0 -59
- package/lib/components/voice-agent/services/websocket-voice-client.service.d.ts.map +0 -1
package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts
CHANGED
|
@@ -30,9 +30,12 @@ export declare class VoiceAgentModalComponent implements OnInit, OnDestroy {
|
|
|
30
30
|
isMicMuted: boolean;
|
|
31
31
|
isUserSpeaking: boolean;
|
|
32
32
|
audioLevels: number[];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
/** True while the bot is speaking — drives avatar pulse animation and voice visualizer. */
|
|
34
|
+
get isBotTalking(): boolean;
|
|
35
|
+
/** True while the user is actively speaking — drives waveform active color. */
|
|
36
|
+
get isUserActive(): boolean;
|
|
37
|
+
/** True during the brief processing pause between user speech and bot response. */
|
|
38
|
+
get isProcessing(): boolean;
|
|
36
39
|
private subscriptions;
|
|
37
40
|
ngOnInit(): void;
|
|
38
41
|
ngOnDestroy(): void;
|
|
@@ -46,7 +49,7 @@ export declare class VoiceAgentModalComponent implements OnInit, OnDestroy {
|
|
|
46
49
|
* as tiny dots — matching the audio-waveform reference design.
|
|
47
50
|
*/
|
|
48
51
|
getWaveformHeight(level: number, index: number): number;
|
|
49
|
-
/** Status label for active call. */
|
|
52
|
+
/** Status label for active call — driven by callState + service statusText. */
|
|
50
53
|
get statusLabel(): string;
|
|
51
54
|
/** Call Again: reset to idle then start a new call. */
|
|
52
55
|
callAgain(): void;
|
package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-agent-modal.component.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,SAAS,EAAU,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEpG,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAG7E,qBAKa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IAoBvD,iBAAiB,EAAE,iBAAiB;IACpC,aAAa,EAAE,oBAAoB;IAC1C,OAAO,CAAC,QAAQ;IArBR,KAAK,qBAA4B;IAClC,MAAM,EAAG,MAAM,CAAC;IAChB,KAAK,EAAG,MAAM,CAAC;IACf,KAAK,EAAG,MAAM,CAAC;IACf,cAAc,EAAG,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAM;IACpB,UAAU,EAAE,MAAM,CAAM;IACxB,OAAO,EAAE,MAAM,CAAM;IACrB,QAAQ,EAAE,MAAM,CAAM;IACtB,eAAe,EAAE,MAAM,CAAe;IACtC,SAAS,EAAE,MAAM,CAAkB;IACnC,SAAS,EAAE,MAAM,CAAyB;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAM;IAElC,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,eAAe,CAA6B;gBAG3C,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,oBAAoB,EAClC,QAAQ,EAAE,QAAQ;IAG5B,0CAA0C;IAC1C,QAAQ,CAAC,gBAAgB,2GAA2G;IAEpI,SAAS,EAAE,SAAS,CAAU;IAC9B,UAAU,EAAE,MAAM,CAAM;IACxB,QAAQ,EAAE,MAAM,CAAW;IAC3B,UAAU,EAAE,OAAO,CAAS;IAC5B,cAAc,EAAE,OAAO,CAAS;IAChC,WAAW,EAAE,MAAM,EAAE,CAAM;
|
|
1
|
+
{"version":3,"file":"voice-agent-modal.component.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,SAAS,EAAU,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEpG,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAG7E,qBAKa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IAoBvD,iBAAiB,EAAE,iBAAiB;IACpC,aAAa,EAAE,oBAAoB;IAC1C,OAAO,CAAC,QAAQ;IArBR,KAAK,qBAA4B;IAClC,MAAM,EAAG,MAAM,CAAC;IAChB,KAAK,EAAG,MAAM,CAAC;IACf,KAAK,EAAG,MAAM,CAAC;IACf,cAAc,EAAG,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAM;IACpB,UAAU,EAAE,MAAM,CAAM;IACxB,OAAO,EAAE,MAAM,CAAM;IACrB,QAAQ,EAAE,MAAM,CAAM;IACtB,eAAe,EAAE,MAAM,CAAe;IACtC,SAAS,EAAE,MAAM,CAAkB;IACnC,SAAS,EAAE,MAAM,CAAyB;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAM;IAElC,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,eAAe,CAA6B;gBAG3C,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,oBAAoB,EAClC,QAAQ,EAAE,QAAQ;IAG5B,0CAA0C;IAC1C,QAAQ,CAAC,gBAAgB,2GAA2G;IAEpI,SAAS,EAAE,SAAS,CAAU;IAC9B,UAAU,EAAE,MAAM,CAAM;IACxB,QAAQ,EAAE,MAAM,CAAW;IAC3B,UAAU,EAAE,OAAO,CAAS;IAC5B,cAAc,EAAE,OAAO,CAAS;IAChC,WAAW,EAAE,MAAM,EAAE,CAAM;IAE3B,2FAA2F;IAC3F,IAAI,YAAY,IAAI,OAAO,CAAyC;IAEpE,+EAA+E;IAC/E,IAAI,YAAY,IAAI,OAAO,CAAsF;IAEjH,mFAAmF;IACnF,IAAI,YAAY,IAAI,OAAO,CAAkF;IAE7G,OAAO,CAAC,aAAa,CAAsB;IAE3C,QAAQ,IAAI,IAAI;IA6DhB,WAAW,IAAI,IAAI;IAKnB,YAAY,EAAE,OAAO,CAAS;IAExB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,SAAS,IAAI,IAAI;IAIjB;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAYvD,+EAA+E;IAC/E,IAAI,WAAW,IAAI,MAAM,CASxB;IAED,uDAAuD;IACvD,SAAS,IAAI,IAAI;IAKjB,gDAAgD;IAChD,UAAU,IAAI,IAAI;IAIlB,mFAAmF;IACnF,MAAM,IAAI,IAAI;IAId,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
import { OnDestroy } from '@angular/core';
|
|
1
|
+
import { NgZone, OnDestroy } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { PlatformTokenRefreshService } from '../../../services/platform-token-refresh.service';
|
|
4
4
|
import { AudioAnalyzerService } from './audio-analyzer.service';
|
|
5
|
-
import { WebSocketVoiceClientService } from './websocket-voice-client.service';
|
|
6
5
|
export declare type CallState = 'idle' | 'connecting' | 'connected' | 'listening' | 'talking' | 'ended';
|
|
7
6
|
export interface TranscriptData {
|
|
8
7
|
text: string;
|
|
9
8
|
final: boolean;
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
|
-
* Voice agent orchestrator
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Voice agent orchestrator using the official PipecatClient SDK.
|
|
12
|
+
*
|
|
13
|
+
* Audio flow (mirrors the React reference implementation):
|
|
14
|
+
* - Local mic: acquired by PipecatClient.initDevices(); local track fed to
|
|
15
|
+
* AudioAnalyzerService for waveform visualisation.
|
|
16
|
+
* - Bot audio: received as a MediaStreamTrack via RTVIEvent.TrackStarted,
|
|
17
|
+
* played through a hidden <audio> element.
|
|
18
|
+
* - All binary protobuf framing / RTVI protocol handled by
|
|
19
|
+
* @pipecat-ai/client-js + @pipecat-ai/websocket-transport.
|
|
15
20
|
*/
|
|
16
21
|
export declare class VoiceAgentService implements OnDestroy {
|
|
17
22
|
private audioAnalyzer;
|
|
18
|
-
private wsClient;
|
|
19
23
|
private platformTokenRefresh;
|
|
24
|
+
private ngZone;
|
|
20
25
|
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
21
26
|
private platformId;
|
|
22
27
|
private callStateSubject;
|
|
@@ -29,11 +34,8 @@ export declare class VoiceAgentService implements OnDestroy {
|
|
|
29
34
|
private botTranscriptSubject;
|
|
30
35
|
private callStartTime;
|
|
31
36
|
private durationInterval;
|
|
32
|
-
private
|
|
33
|
-
private
|
|
34
|
-
private pendingRemoteAudio;
|
|
35
|
-
private remoteAudioPlaying;
|
|
36
|
-
private readonly endCall$;
|
|
37
|
+
private pcClient;
|
|
38
|
+
private botAudioElement;
|
|
37
39
|
private subscriptions;
|
|
38
40
|
private destroy$;
|
|
39
41
|
callState$: Observable<CallState>;
|
|
@@ -44,27 +46,23 @@ export declare class VoiceAgentService implements OnDestroy {
|
|
|
44
46
|
audioLevels$: Observable<number[]>;
|
|
45
47
|
userTranscript$: Observable<TranscriptData>;
|
|
46
48
|
botTranscript$: Observable<string>;
|
|
47
|
-
constructor(audioAnalyzer: AudioAnalyzerService,
|
|
49
|
+
constructor(audioAnalyzer: AudioAnalyzerService, platformTokenRefresh: PlatformTokenRefreshService, ngZone: NgZone,
|
|
48
50
|
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
49
51
|
platformId: Object);
|
|
50
52
|
ngOnDestroy(): void;
|
|
51
|
-
/** Reset to idle
|
|
53
|
+
/** Reset to idle (e.g. when modal re-opens so user can click Start Call). */
|
|
52
54
|
resetToIdle(): void;
|
|
53
55
|
connect(apiUrl: string, token: string, botId: string, conversationId: string, apiKey: string, eventToken: string, eventId: string, eventUrl: string, domainAuthority: string, usersApiUrl?: string): Promise<void>;
|
|
54
|
-
private
|
|
55
|
-
private
|
|
56
|
-
private
|
|
57
|
-
private
|
|
58
|
-
private
|
|
59
|
-
private
|
|
60
|
-
private
|
|
61
|
-
private
|
|
62
|
-
private playDecodedBuffer;
|
|
63
|
-
private assistantAudioStarted;
|
|
64
|
-
private assistantAudioStopped;
|
|
65
|
-
private resetRemoteAudioPlayback;
|
|
66
|
-
private handleRemoteClose;
|
|
56
|
+
private onPipecatConnected;
|
|
57
|
+
private onPipecatDisconnected;
|
|
58
|
+
private onBotReady;
|
|
59
|
+
private startLocalMicAnalyzer;
|
|
60
|
+
private onBotStartedSpeaking;
|
|
61
|
+
private onBotStoppedSpeaking;
|
|
62
|
+
private setupBotAudioTrack;
|
|
63
|
+
private stopBotAudio;
|
|
67
64
|
disconnect(): Promise<void>;
|
|
65
|
+
private cleanupPipecatClient;
|
|
68
66
|
toggleMic(): void;
|
|
69
67
|
private startDurationTimer;
|
|
70
68
|
private stopDurationTimer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-agent.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/voice-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,SAAS,EAAe,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"voice-agent.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/voice-agent.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,MAAM,EAAE,SAAS,EAAe,MAAM,eAAe,CAAC;AACnF,OAAO,EAAmB,UAAU,EAAyB,MAAM,MAAM,CAAC;AAI1E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kDAAkD,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,oBAAY,SAAS,GACjB,MAAM,GACN,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,qBAGa,iBAAkB,YAAW,SAAS;IA6B/C,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IACd,8FAA8F;IACzE,OAAO,CAAC,UAAU;IAhCzC,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,iBAAiB,CAAmC;IAC5D,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,qBAAqB,CAAuC;IACpE,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,qBAAqB,CAAiC;IAC9D,OAAO,CAAC,oBAAoB,CAAyB;IAErD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,gBAAgB,CAA+C;IAEvE,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,eAAe,CAAiC;IAExD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAuB;IAEvC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,CAAwC;IACzE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,CAAyC;IACxE,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAuC;IACpE,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAyC;IACzE,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,CAA6C;IACjF,YAAY,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAA0C;IAC5E,eAAe,EAAE,UAAU,CAAC,cAAc,CAAC,CAA6C;IACxF,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CAA4C;gBAGpE,aAAa,EAAE,oBAAoB,EACnC,oBAAoB,EAAE,2BAA2B,EACjD,MAAM,EAAE,MAAM;IACtB,8FAA8F;IACjE,UAAU,EAAE,MAAM;IASjD,WAAW,IAAI,IAAI;IAMnB,6EAA6E;IAC7E,WAAW,IAAI,IAAI;IAQb,OAAO,CACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAuHhB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;IAed,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAUnB,oBAAoB;IAWlC,SAAS,IAAI,IAAI;IAQjB,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,iBAAiB;CAM1B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Voice agent module. Uses
|
|
3
|
-
*
|
|
2
|
+
* Voice agent module. Uses @pipecat-ai/client-js + @pipecat-ai/websocket-transport
|
|
3
|
+
* (peer dependencies) for WebSocket transport, RTVI protocol, and audio.
|
|
4
4
|
*/
|
|
5
5
|
export declare class VoiceAgentModule {
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-agent.module.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/voice-agent.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"voice-agent.module.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/voice-agent.module.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qBAea,gBAAgB;CAAI"}
|
package/package.json
CHANGED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { Injectable, NgZone } from '@angular/core';
|
|
3
|
-
import { Subject } from 'rxjs';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
/**
|
|
6
|
-
* Native WebSocket client for voice session (signaling, transcripts, speaking hints).
|
|
7
|
-
* CRITICAL: Uses native WebSocket only. NO Socket.IO, NO ngx-socket-io.
|
|
8
|
-
*
|
|
9
|
-
* Connects to `ws_url` from `POST {baseUrl}/ai/ask-voice-socket`.
|
|
10
|
-
* Parses JSON messages for transcripts and optional assistant/user speaking flags.
|
|
11
|
-
*/
|
|
12
|
-
export class WebSocketVoiceClientService {
|
|
13
|
-
constructor(ngZone) {
|
|
14
|
-
this.ngZone = ngZone;
|
|
15
|
-
this.ws = null;
|
|
16
|
-
/** True when {@link disconnect} initiated the close (not counted as remote close). */
|
|
17
|
-
this.closeInitiatedByClient = false;
|
|
18
|
-
this.openedSubject = new Subject();
|
|
19
|
-
this.remoteCloseSubject = new Subject();
|
|
20
|
-
this.userTranscriptSubject = new Subject();
|
|
21
|
-
this.botTranscriptSubject = new Subject();
|
|
22
|
-
this.assistantSpeakingSubject = new Subject();
|
|
23
|
-
this.serverUserSpeakingSubject = new Subject();
|
|
24
|
-
this.audioChunkSubject = new Subject();
|
|
25
|
-
/** Fires once each time the WebSocket reaches OPEN. */
|
|
26
|
-
this.opened$ = this.openedSubject.asObservable();
|
|
27
|
-
/** Fires when the socket closes without a client-initiated {@link disconnect}. */
|
|
28
|
-
this.remoteClose$ = this.remoteCloseSubject.asObservable();
|
|
29
|
-
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
30
|
-
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
31
|
-
/** Assistant/bot speaking, when the server sends explicit events (see {@link handleJsonMessage}). */
|
|
32
|
-
this.assistantSpeaking$ = this.assistantSpeakingSubject.asObservable();
|
|
33
|
-
/** User speaking from server-side VAD, if provided. */
|
|
34
|
-
this.serverUserSpeaking$ = this.serverUserSpeakingSubject.asObservable();
|
|
35
|
-
/** Binary audio frames from server (when backend streams bot audio over WS). */
|
|
36
|
-
this.audioChunk$ = this.audioChunkSubject.asObservable();
|
|
37
|
-
}
|
|
38
|
-
connect(wsUrl) {
|
|
39
|
-
var _a;
|
|
40
|
-
if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (this.ws) {
|
|
44
|
-
this.closeInitiatedByClient = true;
|
|
45
|
-
this.ws.close();
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const socket = new WebSocket(wsUrl);
|
|
49
|
-
this.ws = socket;
|
|
50
|
-
socket.onopen = () => {
|
|
51
|
-
if (this.ws !== socket)
|
|
52
|
-
return;
|
|
53
|
-
this.ngZone.run(() => this.openedSubject.next());
|
|
54
|
-
};
|
|
55
|
-
socket.onmessage = (event) => {
|
|
56
|
-
if (this.ws !== socket)
|
|
57
|
-
return;
|
|
58
|
-
void this.handleIncomingMessage(event.data);
|
|
59
|
-
};
|
|
60
|
-
socket.onerror = () => {
|
|
61
|
-
this.ngZone.run(() => {
|
|
62
|
-
if (this.ws === socket && socket.readyState !== WebSocket.CLOSED) {
|
|
63
|
-
socket.close();
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
|
-
socket.onclose = () => {
|
|
68
|
-
if (this.ws === socket) {
|
|
69
|
-
this.ws = null;
|
|
70
|
-
}
|
|
71
|
-
const client = this.closeInitiatedByClient;
|
|
72
|
-
this.closeInitiatedByClient = false;
|
|
73
|
-
if (!client) {
|
|
74
|
-
this.ngZone.run(() => this.remoteCloseSubject.next());
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
console.error('WebSocketVoiceClient: connect failed', err);
|
|
80
|
-
this.ws = null;
|
|
81
|
-
throw err;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
handleIncomingMessage(payload) {
|
|
85
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
if (typeof payload === 'string') {
|
|
87
|
-
this.handleJsonString(payload);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
if (payload instanceof ArrayBuffer) {
|
|
91
|
-
this.handleBinaryMessage(payload);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (payload instanceof Blob) {
|
|
95
|
-
const ab = yield payload.arrayBuffer();
|
|
96
|
-
this.handleBinaryMessage(ab);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
handleJsonString(jsonText) {
|
|
101
|
-
try {
|
|
102
|
-
const msg = JSON.parse(jsonText);
|
|
103
|
-
this.ngZone.run(() => this.handleJsonMessage(msg));
|
|
104
|
-
}
|
|
105
|
-
catch (_a) {
|
|
106
|
-
// Ignore non-JSON
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
handleBinaryMessage(buffer) {
|
|
110
|
-
// Some backends wrap JSON events inside binary WS frames.
|
|
111
|
-
const maybeText = this.tryDecodeUtf8(buffer);
|
|
112
|
-
if (maybeText !== null) {
|
|
113
|
-
this.handleJsonString(maybeText);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
// Otherwise treat binary as streamed assistant audio.
|
|
117
|
-
this.ngZone.run(() => this.audioChunkSubject.next(buffer));
|
|
118
|
-
}
|
|
119
|
-
tryDecodeUtf8(buffer) {
|
|
120
|
-
try {
|
|
121
|
-
const text = new TextDecoder('utf-8', { fatal: true }).decode(buffer);
|
|
122
|
-
const trimmed = text.trim();
|
|
123
|
-
if (!trimmed || (trimmed[0] !== '{' && trimmed[0] !== '[')) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return trimmed;
|
|
127
|
-
}
|
|
128
|
-
catch (_a) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
handleJsonMessage(msg) {
|
|
133
|
-
const type = msg.type;
|
|
134
|
-
const typeStr = typeof type === 'string' ? type : '';
|
|
135
|
-
if (typeStr === 'session_ready' || typeStr === 'connected' || typeStr === 'voice_session_started') {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (typeStr === 'assistant_speaking' ||
|
|
139
|
-
typeStr === 'bot_speaking') {
|
|
140
|
-
if (msg.active === true || msg.speaking === true) {
|
|
141
|
-
this.assistantSpeakingSubject.next(true);
|
|
142
|
-
}
|
|
143
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
144
|
-
this.assistantSpeakingSubject.next(false);
|
|
145
|
-
}
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (typeStr === 'user_speaking') {
|
|
149
|
-
if (msg.active === true || msg.speaking === true) {
|
|
150
|
-
this.serverUserSpeakingSubject.next(true);
|
|
151
|
-
}
|
|
152
|
-
else if (msg.active === false || msg.speaking === false) {
|
|
153
|
-
this.serverUserSpeakingSubject.next(false);
|
|
154
|
-
}
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (typeStr === 'input_audio_buffer.speech_started') {
|
|
158
|
-
this.serverUserSpeakingSubject.next(true);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
if (typeStr === 'input_audio_buffer.speech_stopped') {
|
|
162
|
-
this.serverUserSpeakingSubject.next(false);
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (typeStr === 'response.audio.delta') {
|
|
166
|
-
this.assistantSpeakingSubject.next(true);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (typeStr === 'response.audio.done' ||
|
|
170
|
-
typeStr === 'response.output_audio.done') {
|
|
171
|
-
this.assistantSpeakingSubject.next(false);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
if (typeStr === 'user_transcript' && typeof msg.text === 'string') {
|
|
175
|
-
this.userTranscriptSubject.next({
|
|
176
|
-
text: msg.text,
|
|
177
|
-
final: msg.final === true,
|
|
178
|
-
});
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
if (typeStr === 'bot_transcript' && typeof msg.text === 'string') {
|
|
182
|
-
this.botTranscriptSubject.next(msg.text);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
disconnect() {
|
|
186
|
-
if (!this.ws) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
this.closeInitiatedByClient = true;
|
|
190
|
-
this.ws.close();
|
|
191
|
-
}
|
|
192
|
-
get isConnected() {
|
|
193
|
-
var _a;
|
|
194
|
-
return ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
WebSocketVoiceClientService.ɵprov = i0.ɵɵdefineInjectable({ factory: function WebSocketVoiceClientService_Factory() { return new WebSocketVoiceClientService(i0.ɵɵinject(i0.NgZone)); }, token: WebSocketVoiceClientService, providedIn: "root" });
|
|
198
|
-
WebSocketVoiceClientService.decorators = [
|
|
199
|
-
{ type: Injectable, args: [{
|
|
200
|
-
providedIn: 'root',
|
|
201
|
-
},] }
|
|
202
|
-
];
|
|
203
|
-
WebSocketVoiceClientService.ctorParameters = () => [
|
|
204
|
-
{ type: NgZone }
|
|
205
|
-
];
|
|
206
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LXZvaWNlLWNsaWVudC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL3dlYnNvY2tldC12b2ljZS1jbGllbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUF1QjNDOzs7Ozs7R0FNRztBQUlILE1BQU0sT0FBTywyQkFBMkI7SUFvQ3RDLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBbkMxQixPQUFFLEdBQXFCLElBQUksQ0FBQztRQUNwQyxzRkFBc0Y7UUFDOUUsMkJBQXNCLEdBQUcsS0FBSyxDQUFDO1FBRS9CLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUNwQyx1QkFBa0IsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3pDLDBCQUFxQixHQUFHLElBQUksT0FBTyxFQUFrQixDQUFDO1FBQ3RELHlCQUFvQixHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFDN0MsNkJBQXdCLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNsRCw4QkFBeUIsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBQ25ELHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFFdkQsdURBQXVEO1FBQ3ZELFlBQU8sR0FBcUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5RCxrRkFBa0Y7UUFDbEYsaUJBQVksR0FBcUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlB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QUssS0FBSyxJQUFJO2FBQzFCLENBQUMsQ0FBQztZQUNILE9BQU87U0FDUjtRQUNELElBQUksT0FBTyxLQUFLLGdCQUFnQixJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7WUFDaEUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDMUM7SUFDSCxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ1osT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxJQUFJLFdBQVc7O1FBQ2IsT0FBTyxDQUFBLE1BQUEsSUFBSSxDQUFDLEVBQUUsMENBQUUsVUFBVSxNQUFLLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDaEQsQ0FBQzs7OztZQTdNRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7OztZQWpDb0IsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG4vKiogV2ViU29ja2V0IG1lc3NhZ2UgdHlwZXMgZnJvbSBiYWNrZW5kICh2b2ljZSBzZXNzaW9uIG92ZXIgYSBzaW5nbGUgV1MpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBXc01lc3NhZ2VVc2VyVHJhbnNjcmlwdCB7XG4gIHR5cGU6ICd1c2VyX3RyYW5zY3JpcHQnO1xuICB0ZXh0OiBzdHJpbmc7XG4gIGZpbmFsPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXc01lc3NhZ2VCb3RUcmFuc2NyaXB0IHtcbiAgdHlwZTogJ2JvdF90cmFuc2NyaXB0JztcbiAgdGV4dDogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBXc01lc3NhZ2UgPVxuICB8IFdzTWVzc2FnZVVzZXJUcmFuc2NyaXB0XG4gIHwgV3NNZXNzYWdlQm90VHJhbnNjcmlwdDtcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2NyaXB0RGF0YSB7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw6IGJvb2xlYW47XG59XG5cbi8qKlxuICogTmF0aXZlIFdlYlNvY2tldCBjbGllbnQgZm9yIHZvaWNlIHNlc3Npb24gKHNpZ25hbGluZywgdHJhbnNjcmlwdHMsIHNwZWFraW5nIGhpbnRzKS5cbiAqIENSSVRJQ0FMOiBVc2VzIG5hdGl2ZSBXZWJTb2NrZXQgb25seS4gTk8gU29ja2V0LklPLCBOTyBuZ3gtc29ja2V0LWlvLlxuICpcbiAqIENvbm5lY3RzIHRvIGB3c191cmxgIGZyb20gYFBPU1Qge2Jhc2VVcmx9L2FpL2Fzay12b2ljZS1zb2NrZXRgLlxuICogUGFyc2VzIEpTT04gbWVzc2FnZXMgZm9yIHRyYW5zY3JpcHRzIGFuZCBvcHRpb25hbCBhc3Npc3RhbnQvdXNlciBzcGVha2luZyBmbGFncy5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFdlYlNvY2tldFZvaWNlQ2xpZW50U2VydmljZSB7XG4gIHByaXZhdGUgd3M6IFdlYlNvY2tldCB8IG51bGwgPSBudWxsO1xuICAvKiogVHJ1ZSB3aGVuIHtAbGluayBkaXNjb25uZWN0fSBpbml0aWF0ZWQgdGhlIGNsb3NlIChub3QgY291bnRlZCBhcyByZW1vdGUgY2xvc2UpLiAqL1xuICBwcml2YXRlIGNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSBmYWxzZTtcblxuICBwcml2YXRlIG9wZW5lZFN1YmplY3QgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlbW90ZUNsb3NlU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgdXNlclRyYW5zY3JpcHRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8VHJhbnNjcmlwdERhdGE+KCk7XG4gIHByaXZhdGUgYm90VHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG4gIHByaXZhdGUgYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSBzZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSBhdWRpb0NodW5rU3ViamVjdCA9IG5ldyBTdWJqZWN0PEFycmF5QnVmZmVyPigpO1xuXG4gIC8qKiBGaXJlcyBvbmNlIGVhY2ggdGltZSB0aGUgV2ViU29ja2V0IHJlYWNoZXMgT1BFTi4gKi9cbiAgb3BlbmVkJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMub3BlbmVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogRmlyZXMgd2hlbiB0aGUgc29ja2V0IGNsb3NlcyB3aXRob3V0IGEgY2xpZW50LWluaXRpYXRlZCB7QGxpbmsgZGlzY29ubmVjdH0uICovXG4gIHJlbW90ZUNsb3NlJDogT2JzZXJ2YWJsZTx2b2lkPiA9IHRoaXMucmVtb3RlQ2xvc2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPVxuICAgIHRoaXMudXNlclRyYW5zY3JpcHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGJvdFRyYW5zY3JpcHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPVxuICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgLyoqIEFzc2lzdGFudC9ib3Qgc3BlYWtpbmcsIHdoZW4gdGhlIHNlcnZlciBzZW5kcyBleHBsaWNpdCBldmVudHMgKHNlZSB7QGxpbmsgaGFuZGxlSnNvbk1lc3NhZ2V9KS4gKi9cbiAgYXNzaXN0YW50U3BlYWtpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID1cbiAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogVXNlciBzcGVha2luZyBmcm9tIHNlcnZlci1zaWRlIFZBRCwgaWYgcHJvdmlkZWQuICovXG4gIHNlcnZlclVzZXJTcGVha2luZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPVxuICAgIHRoaXMuc2VydmVyVXNlclNwZWFraW5nU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICAvKiogQmluYXJ5IGF1ZGlvIGZyYW1lcyBmcm9tIHNlcnZlciAod2hlbiBiYWNrZW5kIHN0cmVhbXMgYm90IGF1ZGlvIG92ZXIgV1MpLiAqL1xuICBhdWRpb0NodW5rJDogT2JzZXJ2YWJsZTxBcnJheUJ1ZmZlcj4gPSB0aGlzLmF1ZGlvQ2h1bmtTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgY29ubmVjdCh3c1VybDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLndzKSB7XG4gICAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgICAgdGhpcy53cy5jbG9zZSgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzb2NrZXQgPSBuZXcgV2ViU29ja2V0KHdzVXJsKTtcbiAgICAgIHRoaXMud3MgPSBzb2NrZXQ7XG4gICAgICBzb2NrZXQub25vcGVuID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy53cyAhPT0gc29ja2V0KSByZXR1cm47XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm9wZW5lZFN1YmplY3QubmV4dCgpKTtcbiAgICAgIH07XG4gICAgICBzb2NrZXQub25tZXNzYWdlID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMud3MgIT09IHNvY2tldCkgcmV0dXJuO1xuICAgICAgICB2b2lkIHRoaXMuaGFuZGxlSW5jb21pbmdNZXNzYWdlKGV2ZW50LmRhdGEpO1xuICAgICAgfTtcbiAgICAgIHNvY2tldC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLndzID09PSBzb2NrZXQgJiYgc29ja2V0LnJlYWR5U3RhdGUgIT09IFdlYlNvY2tldC5DTE9TRUQpIHtcbiAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLndzID09PSBzb2NrZXQpIHtcbiAgICAgICAgICB0aGlzLndzID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQ7XG4gICAgICAgIHRoaXMuY2xvc2VJbml0aWF0ZWRCeUNsaWVudCA9IGZhbHNlO1xuICAgICAgICBpZiAoIWNsaWVudCkge1xuICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLnJlbW90ZUNsb3NlU3ViamVjdC5uZXh0KCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcignV2ViU29ja2V0Vm9pY2VDbGllbnQ6IGNvbm5lY3QgZmFpbGVkJywgZXJyKTtcbiAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlSW5jb21pbmdNZXNzYWdlKHBheWxvYWQ6IHVua25vd24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLmhhbmRsZUpzb25TdHJpbmcocGF5bG9hZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwYXlsb2FkIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHRoaXMuaGFuZGxlQmluYXJ5TWVzc2FnZShwYXlsb2FkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHBheWxvYWQgaW5zdGFuY2VvZiBCbG9iKSB7XG4gICAgICBjb25zdCBhYiA9IGF3YWl0IHBheWxvYWQuYXJyYXlCdWZmZXIoKTtcbiAgICAgIHRoaXMuaGFuZGxlQmluYXJ5TWVzc2FnZShhYik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uU3RyaW5nKGpzb25UZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbXNnID0gSlNPTi5wYXJzZShqc29uVGV4dCkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5oYW5kbGVKc29uTWVzc2FnZShtc2cpKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIElnbm9yZSBub24tSlNPTlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQmluYXJ5TWVzc2FnZShidWZmZXI6IEFycmF5QnVmZmVyKTogdm9pZCB7XG4gICAgLy8gU29tZSBiYWNrZW5kcyB3cmFwIEpTT04gZXZlbnRzIGluc2lkZSBiaW5hcnkgV1MgZnJhbWVzLlxuICAgIGNvbnN0IG1heWJlVGV4dCA9IHRoaXMudHJ5RGVjb2RlVXRmOChidWZmZXIpO1xuICAgIGlmIChtYXliZVRleHQgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuaGFuZGxlSnNvblN0cmluZyhtYXliZVRleHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBPdGhlcndpc2UgdHJlYXQgYmluYXJ5IGFzIHN0cmVhbWVkIGFzc2lzdGFudCBhdWRpby5cbiAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5hdWRpb0NodW5rU3ViamVjdC5uZXh0KGJ1ZmZlcikpO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnlEZWNvZGVVdGY4KGJ1ZmZlcjogQXJyYXlCdWZmZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdGV4dCA9IG5ldyBUZXh0RGVjb2RlcigndXRmLTgnLCB7IGZhdGFsOiB0cnVlIH0pLmRlY29kZShidWZmZXIpO1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHRleHQudHJpbSgpO1xuICAgICAgaWYgKCF0cmltbWVkIHx8ICh0cmltbWVkWzBdICE9PSAneycgJiYgdHJpbW1lZFswXSAhPT0gJ1snKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmltbWVkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVKc29uTWVzc2FnZShtc2c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gICAgY29uc3QgdHlwZSA9IG1zZy50eXBlO1xuICAgIGNvbnN0IHR5cGVTdHIgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlIDogJyc7XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3Nlc3Npb25fcmVhZHknIHx8IHR5cGVTdHIgPT09ICdjb25uZWN0ZWQnIHx8IHR5cGVTdHIgPT09ICd2b2ljZV9zZXNzaW9uX3N0YXJ0ZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZVN0ciA9PT0gJ2Fzc2lzdGFudF9zcGVha2luZycgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdib3Rfc3BlYWtpbmcnXG4gICAgKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5hc3Npc3RhbnRTcGVha2luZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAobXNnLmFjdGl2ZSA9PT0gZmFsc2UgfHwgbXNnLnNwZWFraW5nID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZVN0ciA9PT0gJ3VzZXJfc3BlYWtpbmcnKSB7XG4gICAgICBpZiAobXNnLmFjdGl2ZSA9PT0gdHJ1ZSB8fCBtc2cuc3BlYWtpbmcgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG1zZy5hY3RpdmUgPT09IGZhbHNlIHx8IG1zZy5zcGVha2luZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdGFydGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlU3RyID09PSAnaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkJykge1xuICAgICAgdGhpcy5zZXJ2ZXJVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZGVsdGEnKSB7XG4gICAgICB0aGlzLmFzc2lzdGFudFNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0eXBlU3RyID09PSAncmVzcG9uc2UuYXVkaW8uZG9uZScgfHxcbiAgICAgIHR5cGVTdHIgPT09ICdyZXNwb25zZS5vdXRwdXRfYXVkaW8uZG9uZSdcbiAgICApIHtcbiAgICAgIHRoaXMuYXNzaXN0YW50U3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlU3RyID09PSAndXNlcl90cmFuc2NyaXB0JyAmJiB0eXBlb2YgbXNnLnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5uZXh0KHtcbiAgICAgICAgdGV4dDogbXNnLnRleHQsXG4gICAgICAgIGZpbmFsOiBtc2cuZmluYWwgPT09IHRydWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVTdHIgPT09ICdib3RfdHJhbnNjcmlwdCcgJiYgdHlwZW9mIG1zZy50ZXh0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5ib3RUcmFuc2NyaXB0U3ViamVjdC5uZXh0KG1zZy50ZXh0KTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy53cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlSW5pdGlhdGVkQnlDbGllbnQgPSB0cnVlO1xuICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgfVxuXG4gIGdldCBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy53cz8ucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0Lk9QRU47XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { NgZone } from '@angular/core';
|
|
2
|
-
import { Observable } from 'rxjs';
|
|
3
|
-
/** WebSocket message types from backend (voice session over a single WS). */
|
|
4
|
-
export interface WsMessageUserTranscript {
|
|
5
|
-
type: 'user_transcript';
|
|
6
|
-
text: string;
|
|
7
|
-
final?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface WsMessageBotTranscript {
|
|
10
|
-
type: 'bot_transcript';
|
|
11
|
-
text: string;
|
|
12
|
-
}
|
|
13
|
-
export declare type WsMessage = WsMessageUserTranscript | WsMessageBotTranscript;
|
|
14
|
-
export interface TranscriptData {
|
|
15
|
-
text: string;
|
|
16
|
-
final: boolean;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Native WebSocket client for voice session (signaling, transcripts, speaking hints).
|
|
20
|
-
* CRITICAL: Uses native WebSocket only. NO Socket.IO, NO ngx-socket-io.
|
|
21
|
-
*
|
|
22
|
-
* Connects to `ws_url` from `POST {baseUrl}/ai/ask-voice-socket`.
|
|
23
|
-
* Parses JSON messages for transcripts and optional assistant/user speaking flags.
|
|
24
|
-
*/
|
|
25
|
-
export declare class WebSocketVoiceClientService {
|
|
26
|
-
private ngZone;
|
|
27
|
-
private ws;
|
|
28
|
-
/** True when {@link disconnect} initiated the close (not counted as remote close). */
|
|
29
|
-
private closeInitiatedByClient;
|
|
30
|
-
private openedSubject;
|
|
31
|
-
private remoteCloseSubject;
|
|
32
|
-
private userTranscriptSubject;
|
|
33
|
-
private botTranscriptSubject;
|
|
34
|
-
private assistantSpeakingSubject;
|
|
35
|
-
private serverUserSpeakingSubject;
|
|
36
|
-
private audioChunkSubject;
|
|
37
|
-
/** Fires once each time the WebSocket reaches OPEN. */
|
|
38
|
-
opened$: Observable<void>;
|
|
39
|
-
/** Fires when the socket closes without a client-initiated {@link disconnect}. */
|
|
40
|
-
remoteClose$: Observable<void>;
|
|
41
|
-
userTranscript$: Observable<TranscriptData>;
|
|
42
|
-
botTranscript$: Observable<string>;
|
|
43
|
-
/** Assistant/bot speaking, when the server sends explicit events (see {@link handleJsonMessage}). */
|
|
44
|
-
assistantSpeaking$: Observable<boolean>;
|
|
45
|
-
/** User speaking from server-side VAD, if provided. */
|
|
46
|
-
serverUserSpeaking$: Observable<boolean>;
|
|
47
|
-
/** Binary audio frames from server (when backend streams bot audio over WS). */
|
|
48
|
-
audioChunk$: Observable<ArrayBuffer>;
|
|
49
|
-
constructor(ngZone: NgZone);
|
|
50
|
-
connect(wsUrl: string): void;
|
|
51
|
-
private handleIncomingMessage;
|
|
52
|
-
private handleJsonString;
|
|
53
|
-
private handleBinaryMessage;
|
|
54
|
-
private tryDecodeUtf8;
|
|
55
|
-
private handleJsonMessage;
|
|
56
|
-
disconnect(): void;
|
|
57
|
-
get isConnected(): boolean;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=websocket-voice-client.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-voice-client.service.d.ts","sourceRoot":"/Users/rohitthakur/hive-gpt/HiveAI-Packages/Angular/projects/hivegpt/eventsgpt-angular/src/","sources":["lib/components/voice-agent/services/websocket-voice-client.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAE3C,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oBAAY,SAAS,GACjB,uBAAuB,GACvB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAGa,2BAA2B;IAoC1B,OAAO,CAAC,MAAM;IAnC1B,OAAO,CAAC,EAAE,CAA0B;IACpC,sFAAsF;IACtF,OAAO,CAAC,sBAAsB,CAAS;IAEvC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,qBAAqB,CAAiC;IAC9D,OAAO,CAAC,oBAAoB,CAAyB;IACrD,OAAO,CAAC,wBAAwB,CAA0B;IAC1D,OAAO,CAAC,yBAAyB,CAA0B;IAC3D,OAAO,CAAC,iBAAiB,CAA8B;IAEvD,uDAAuD;IACvD,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAqC;IAE9D,kFAAkF;IAClF,YAAY,EAAE,UAAU,CAAC,IAAI,CAAC,CAA0C;IAExE,eAAe,EAAE,UAAU,CAAC,cAAc,CAAC,CACC;IAE5C,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,CACS;IAE3C,qGAAqG;IACrG,kBAAkB,EAAE,UAAU,CAAC,OAAO,CAAC,CACQ;IAE/C,uDAAuD;IACvD,mBAAmB,EAAE,UAAU,CAAC,OAAO,CAAC,CACQ;IAEhD,gFAAgF;IAChF,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,CAAyC;gBAEzD,MAAM,EAAE,MAAM;IAElC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;YA4Cd,qBAAqB;IAenC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,iBAAiB;IA8DzB,UAAU,IAAI,IAAI;IAQlB,IAAI,WAAW,IAAI,OAAO,CAEzB;CACF"}
|