@craftedxp/voice-js 0.9.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -20
- package/dist/assistant.d.mts +3 -3
- package/dist/assistant.d.ts +3 -3
- package/dist/assistant.js +210 -22
- package/dist/assistant.js.map +1 -1
- package/dist/assistant.mjs +2 -1
- package/dist/browser.d.mts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +201 -34
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +3 -2
- package/dist/browser.mjs.map +1 -1
- package/dist/{chunk-ZW22Y67M.mjs → chunk-C2U6V5NI.mjs} +191 -23
- package/dist/chunk-C2U6V5NI.mjs.map +1 -0
- package/dist/chunk-OS2GZAR7.mjs +18 -0
- package/dist/chunk-OS2GZAR7.mjs.map +1 -0
- package/dist/{chunk-LV7JGPYW.mjs → chunk-VSY43NGD.mjs} +6 -13
- package/dist/chunk-VSY43NGD.mjs.map +1 -0
- package/dist/{config-D2TbvIqT.d.mts → config-DfbPB1Tq.d.mts} +22 -3
- package/dist/{config-D2TbvIqT.d.ts → config-DfbPB1Tq.d.ts} +22 -3
- package/dist/embed.iife.js +42 -5
- package/dist/{incomingCall-CfRRzj2P.d.ts → incomingCall-2B3XB8pM.d.mts} +3 -1
- package/dist/{incomingCall-CfRRzj2P.d.mts → incomingCall-CYmeQkIw.d.ts} +3 -1
- package/dist/node.d.mts +37 -4
- package/dist/node.d.ts +37 -4
- package/dist/node.js +31 -2
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +31 -2
- package/dist/node.mjs.map +1 -1
- package/dist/room.js +15 -12
- package/dist/room.js.map +1 -1
- package/dist/room.mjs +2 -1
- package/dist/transcribe.d.mts +2 -2
- package/dist/transcribe.d.ts +2 -2
- package/dist/transcribe.js +209 -21
- package/dist/transcribe.js.map +1 -1
- package/dist/transcribe.mjs +2 -1
- package/dist/transcribe.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-LV7JGPYW.mjs.map +0 -1
- package/dist/chunk-ZW22Y67M.mjs.map +0 -1
package/dist/assistant.mjs
CHANGED
package/dist/browser.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { V as VoiceClientConfig, a as VoiceClientFactory } from './config-
|
|
2
|
-
export { C as Call, b as CallEndEvent, c as CallEndReason, d as CallError, e as CallErrorCode, f as CallState, g as
|
|
1
|
+
import { V as VoiceClientConfig, a as VoiceClientFactory } from './config-DfbPB1Tq.mjs';
|
|
2
|
+
export { C as Call, b as CallEndEvent, c as CallEndReason, d as CallError, e as CallErrorCode, f as CallState, g as CallTransport, h as ChatEvent, i as ClientTool, j as ClientToolMap, F as FetchToken, k as FetchTokenArgs, l as FetchTokenResult, P as ProtocolCallbacks, m as ProtocolState, S as ServerMessage, n as StartCallOptions, o as StartTextSessionOpts, T as TextSession, p as TranscriptEntry, q as TransportChangeEvent, r as VolumeEvent, s as buildWsUrl, t as createProtocolState, u as handleServerMessage, v as startTextSession } from './config-DfbPB1Tq.mjs';
|
|
3
3
|
import { JoinRoomOptions, RoomSession } from './room.mjs';
|
|
4
4
|
export { AnalysisMessage, RoomEventName, RoomEventPayloads, RoomParticipantInfo, SystemMessage, TranscriptMessage, joinRoom } from './room.mjs';
|
|
5
|
-
export { C as CaptureController, a as CaptureOptions, I as IncomingCallPayload, O as OnAgentSpeakingChange, b as OnChunk, c as OnError, d as OnVolume, P as PlaybackController, e as PlaybackOptions, R as RWSEvent, f as RWSOptions, g as ReconnectingWebSocket, W as WebSocketFactory, h as WebSocketLike, i as createAudioCapture, j as createAudioPlayback, k as createReconnectingWebSocket, p as parseIncomingCall } from './incomingCall-
|
|
5
|
+
export { C as CaptureController, a as CaptureOptions, I as IncomingCallPayload, O as OnAgentSpeakingChange, b as OnChunk, c as OnError, d as OnVolume, P as PlaybackController, e as PlaybackOptions, R as RWSEvent, f as RWSOptions, g as ReconnectingWebSocket, W as WebSocketFactory, h as WebSocketLike, i as createAudioCapture, j as createAudioPlayback, k as createReconnectingWebSocket, p as parseIncomingCall } from './incomingCall-2B3XB8pM.mjs';
|
|
6
6
|
import 'livekit-client';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { V as VoiceClientConfig, a as VoiceClientFactory } from './config-
|
|
2
|
-
export { C as Call, b as CallEndEvent, c as CallEndReason, d as CallError, e as CallErrorCode, f as CallState, g as
|
|
1
|
+
import { V as VoiceClientConfig, a as VoiceClientFactory } from './config-DfbPB1Tq.js';
|
|
2
|
+
export { C as Call, b as CallEndEvent, c as CallEndReason, d as CallError, e as CallErrorCode, f as CallState, g as CallTransport, h as ChatEvent, i as ClientTool, j as ClientToolMap, F as FetchToken, k as FetchTokenArgs, l as FetchTokenResult, P as ProtocolCallbacks, m as ProtocolState, S as ServerMessage, n as StartCallOptions, o as StartTextSessionOpts, T as TextSession, p as TranscriptEntry, q as TransportChangeEvent, r as VolumeEvent, s as buildWsUrl, t as createProtocolState, u as handleServerMessage, v as startTextSession } from './config-DfbPB1Tq.js';
|
|
3
3
|
import { JoinRoomOptions, RoomSession } from './room.js';
|
|
4
4
|
export { AnalysisMessage, RoomEventName, RoomEventPayloads, RoomParticipantInfo, SystemMessage, TranscriptMessage, joinRoom } from './room.js';
|
|
5
|
-
export { C as CaptureController, a as CaptureOptions, I as IncomingCallPayload, O as OnAgentSpeakingChange, b as OnChunk, c as OnError, d as OnVolume, P as PlaybackController, e as PlaybackOptions, R as RWSEvent, f as RWSOptions, g as ReconnectingWebSocket, W as WebSocketFactory, h as WebSocketLike, i as createAudioCapture, j as createAudioPlayback, k as createReconnectingWebSocket, p as parseIncomingCall } from './incomingCall-
|
|
5
|
+
export { C as CaptureController, a as CaptureOptions, I as IncomingCallPayload, O as OnAgentSpeakingChange, b as OnChunk, c as OnError, d as OnVolume, P as PlaybackController, e as PlaybackOptions, R as RWSEvent, f as RWSOptions, g as ReconnectingWebSocket, W as WebSocketFactory, h as WebSocketLike, i as createAudioCapture, j as createAudioPlayback, k as createReconnectingWebSocket, p as parseIncomingCall } from './incomingCall-CYmeQkIw.js';
|
|
6
6
|
import 'livekit-client';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/browser.js
CHANGED
|
@@ -523,7 +523,8 @@ function buildWsUrl(args) {
|
|
|
523
523
|
const base = new URL(args.apiBase);
|
|
524
524
|
const proto = base.protocol === "https:" ? "wss:" : "ws:";
|
|
525
525
|
const bargeQS = args.bargeIn === false ? "&barge=off" : "";
|
|
526
|
-
|
|
526
|
+
const mediaQS = args.media === "livekit" ? "&media=livekit" : "";
|
|
527
|
+
return `${proto}//${base.host}/v1/agents/${encodeURIComponent(args.agentId)}/call?token=${encodeURIComponent(args.token)}${bargeQS}${mediaQS}`;
|
|
527
528
|
}
|
|
528
529
|
|
|
529
530
|
// src/clientTools.ts
|
|
@@ -677,7 +678,75 @@ var createClientMarksBuffer = (args) => {
|
|
|
677
678
|
};
|
|
678
679
|
};
|
|
679
680
|
|
|
681
|
+
// src/livekit/createLiveKitMedia.ts
|
|
682
|
+
var toError = (e) => e instanceof Error ? e : new Error(String(e));
|
|
683
|
+
function createLiveKitMedia(lk, opts = {}) {
|
|
684
|
+
let room = null;
|
|
685
|
+
let audioEl = null;
|
|
686
|
+
let muted = false;
|
|
687
|
+
const attach = (track) => {
|
|
688
|
+
if (track.kind !== lk.Track.Kind.Audio) return;
|
|
689
|
+
if (typeof document === "undefined") return;
|
|
690
|
+
if (!audioEl) {
|
|
691
|
+
audioEl = document.createElement("audio");
|
|
692
|
+
audioEl.autoplay = true;
|
|
693
|
+
audioEl.style.display = "none";
|
|
694
|
+
document.body.appendChild(audioEl);
|
|
695
|
+
}
|
|
696
|
+
track.attach(audioEl);
|
|
697
|
+
};
|
|
698
|
+
return {
|
|
699
|
+
connect: async (url, token) => {
|
|
700
|
+
const r = new lk.Room({ adaptiveStream: false, dynacast: false });
|
|
701
|
+
room = r;
|
|
702
|
+
r.on(lk.RoomEvent.TrackSubscribed, (track) => attach(track));
|
|
703
|
+
await r.connect(url, token);
|
|
704
|
+
if (room !== r) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
await r.localParticipant.setMicrophoneEnabled(!muted);
|
|
708
|
+
if (room !== r) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
try {
|
|
712
|
+
await r.startAudio();
|
|
713
|
+
} catch {
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
disconnect: () => {
|
|
717
|
+
const r = room;
|
|
718
|
+
room = null;
|
|
719
|
+
if (r) void r.disconnect().catch(() => void 0);
|
|
720
|
+
audioEl?.remove();
|
|
721
|
+
audioEl = null;
|
|
722
|
+
},
|
|
723
|
+
setMuted: (m) => {
|
|
724
|
+
muted = m;
|
|
725
|
+
const r = room;
|
|
726
|
+
if (!r) return;
|
|
727
|
+
void r.localParticipant.setMicrophoneEnabled(!m).catch((e) => opts.onError?.(toError(e)));
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
|
|
680
732
|
// src/VoiceClient.ts
|
|
733
|
+
var parseMediaFrame = (raw) => {
|
|
734
|
+
if (!raw.includes('"livekit_')) return null;
|
|
735
|
+
try {
|
|
736
|
+
const m = JSON.parse(raw);
|
|
737
|
+
if (m.type === "livekit_join" && typeof m.url === "string" && typeof m.token === "string") {
|
|
738
|
+
return { type: "livekit_join", url: m.url, token: m.token };
|
|
739
|
+
}
|
|
740
|
+
if (m.type === "livekit_fallback") {
|
|
741
|
+
return {
|
|
742
|
+
type: "livekit_fallback",
|
|
743
|
+
reason: typeof m.reason === "string" ? m.reason : void 0
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
return null;
|
|
749
|
+
};
|
|
681
750
|
var BrowserVoiceClient = class {
|
|
682
751
|
constructor(args) {
|
|
683
752
|
this.rws = null;
|
|
@@ -689,6 +758,9 @@ var BrowserVoiceClient = class {
|
|
|
689
758
|
this.startedAt = null;
|
|
690
759
|
this.endedFired = false;
|
|
691
760
|
this.lastError = null;
|
|
761
|
+
this.mediaMode = "ws";
|
|
762
|
+
this.lkMedia = null;
|
|
763
|
+
this.lkJoinSeen = false;
|
|
692
764
|
this.end = () => {
|
|
693
765
|
this.teardown("user_hangup");
|
|
694
766
|
};
|
|
@@ -696,11 +768,73 @@ var BrowserVoiceClient = class {
|
|
|
696
768
|
if (this.muted) return;
|
|
697
769
|
this.muted = true;
|
|
698
770
|
this.capture?.mute(true);
|
|
771
|
+
this.lkMedia?.setMuted(true);
|
|
699
772
|
};
|
|
700
773
|
this.unmute = () => {
|
|
701
774
|
if (!this.muted) return;
|
|
702
775
|
this.muted = false;
|
|
703
776
|
this.capture?.mute(false);
|
|
777
|
+
this.lkMedia?.setMuted(false);
|
|
778
|
+
};
|
|
779
|
+
this.ensureWsPlayback = async () => {
|
|
780
|
+
if (this.playback) return;
|
|
781
|
+
const createPlayback = this.args.audio?.createPlayback ?? createAudioPlayback;
|
|
782
|
+
this.playback = createPlayback({
|
|
783
|
+
onVolume: (v) => {
|
|
784
|
+
this.outputVolume = v;
|
|
785
|
+
this.args.options.onVolume?.({ input: this.inputVolume, output: v });
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
try {
|
|
789
|
+
await this.playback.resume();
|
|
790
|
+
} catch {
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
// ---------------------------------------------------------------
|
|
794
|
+
// LiveKit media lifecycle (phase 35)
|
|
795
|
+
// ---------------------------------------------------------------
|
|
796
|
+
this.joinLiveKit = async (url, token) => {
|
|
797
|
+
this.lkJoinSeen = true;
|
|
798
|
+
const lk = this.args.media?.lk;
|
|
799
|
+
if (!lk) {
|
|
800
|
+
this.fallbackToWs("livekit-client unavailable");
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
const media = createLiveKitMedia(lk, {
|
|
804
|
+
onError: (e) => this.emitError({ code: "mic_start_failed", message: e.message })
|
|
805
|
+
});
|
|
806
|
+
this.lkMedia = media;
|
|
807
|
+
if (this.muted) media.setMuted(true);
|
|
808
|
+
try {
|
|
809
|
+
await media.connect(url, token);
|
|
810
|
+
if (this.lkMedia !== media) return;
|
|
811
|
+
this.mediaMode = "livekit";
|
|
812
|
+
this.rws?.send(JSON.stringify({ type: "livekit_ready" }));
|
|
813
|
+
} catch (err) {
|
|
814
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
815
|
+
media.disconnect();
|
|
816
|
+
if (this.lkMedia === media) this.lkMedia = null;
|
|
817
|
+
this.rws?.send(JSON.stringify({ type: "livekit_failed", reason }));
|
|
818
|
+
this.fallbackToWs(reason);
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
// Idempotent: whichever side gives up first (client join error, server
|
|
822
|
+
// livekit_fallback, `connected` without a join) lands here once.
|
|
823
|
+
this.fallbackToWs = (reason) => {
|
|
824
|
+
if (this.mediaMode === "ws") return;
|
|
825
|
+
this.mediaMode = "ws";
|
|
826
|
+
this.lkMedia?.disconnect();
|
|
827
|
+
this.lkMedia = null;
|
|
828
|
+
void this.ensureWsPlayback();
|
|
829
|
+
void this.startCapture();
|
|
830
|
+
this.args.options.onTransportChange?.({ requested: "livekit", actual: "ws", reason });
|
|
831
|
+
};
|
|
832
|
+
this.resetLiveKitForReconnect = () => {
|
|
833
|
+
if (this.args.media?.kind !== "livekit") return;
|
|
834
|
+
this.lkMedia?.disconnect();
|
|
835
|
+
this.lkMedia = null;
|
|
836
|
+
this.lkJoinSeen = false;
|
|
837
|
+
this.mediaMode = "livekit-pending";
|
|
704
838
|
};
|
|
705
839
|
// ---------------------------------------------------------------
|
|
706
840
|
// Internal
|
|
@@ -721,17 +855,27 @@ var BrowserVoiceClient = class {
|
|
|
721
855
|
this.handleSocketEvent = (ev) => {
|
|
722
856
|
switch (ev.type) {
|
|
723
857
|
case "open":
|
|
724
|
-
void this.startCapture();
|
|
858
|
+
if (this.mediaMode === "ws") void this.startCapture();
|
|
725
859
|
break;
|
|
726
860
|
case "reconnected":
|
|
727
861
|
this.proto.transcript = [];
|
|
728
862
|
this.proto.agentBubbleId = null;
|
|
729
863
|
this.args.options.onTranscript?.(this.proto.transcript);
|
|
730
|
-
|
|
864
|
+
this.resetLiveKitForReconnect();
|
|
865
|
+
if (this.mediaMode === "ws") void this.startCapture();
|
|
731
866
|
this.setState("listening");
|
|
732
867
|
break;
|
|
733
868
|
case "message":
|
|
734
869
|
if (typeof ev.data === "string") {
|
|
870
|
+
const media = parseMediaFrame(ev.data);
|
|
871
|
+
if (media?.type === "livekit_join") {
|
|
872
|
+
if (this.mediaMode === "livekit-pending") void this.joinLiveKit(media.url, media.token);
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
if (media?.type === "livekit_fallback") {
|
|
876
|
+
this.fallbackToWs(media.reason ?? "server_fallback");
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
735
879
|
handleServerMessage(ev.data, this.proto, {
|
|
736
880
|
onState: this.setState,
|
|
737
881
|
onTranscript: (entries) => this.args.options.onTranscript?.(entries),
|
|
@@ -748,7 +892,12 @@ var BrowserVoiceClient = class {
|
|
|
748
892
|
if (typeof seq === "number") this.marks.onAgentTurnEnd(seq);
|
|
749
893
|
},
|
|
750
894
|
onCallEnd: (reason) => this.teardown(reason),
|
|
751
|
-
onConnected: () =>
|
|
895
|
+
onConnected: () => {
|
|
896
|
+
if (this.mediaMode === "livekit-pending" && !this.lkJoinSeen) {
|
|
897
|
+
this.fallbackToWs("server_declined");
|
|
898
|
+
}
|
|
899
|
+
this.sendClientToolsRegister();
|
|
900
|
+
},
|
|
752
901
|
onClientToolCall: (frame) => dispatchClientToolCall(
|
|
753
902
|
(f) => this.rws?.send(JSON.stringify(f)),
|
|
754
903
|
this.args.options.clientTools ?? {},
|
|
@@ -756,6 +905,8 @@ var BrowserVoiceClient = class {
|
|
|
756
905
|
)
|
|
757
906
|
});
|
|
758
907
|
} else {
|
|
908
|
+
if (this.mediaMode === "livekit") break;
|
|
909
|
+
if (!this.playback) void this.ensureWsPlayback();
|
|
759
910
|
this.marks.markFirstAudibleOutput();
|
|
760
911
|
this.playback?.enqueue(ev.data);
|
|
761
912
|
}
|
|
@@ -773,7 +924,8 @@ var BrowserVoiceClient = class {
|
|
|
773
924
|
};
|
|
774
925
|
this.startCapture = async () => {
|
|
775
926
|
if (this.capture?.isCapturing()) return;
|
|
776
|
-
this.
|
|
927
|
+
const createCapture = this.args.audio?.createCapture ?? createAudioCapture;
|
|
928
|
+
this.capture = createCapture({
|
|
777
929
|
onChunk: (pcm) => {
|
|
778
930
|
this.marks.markFirstOutboundAudio();
|
|
779
931
|
this.rws?.send(pcm);
|
|
@@ -802,6 +954,8 @@ var BrowserVoiceClient = class {
|
|
|
802
954
|
}
|
|
803
955
|
this.capture?.stop();
|
|
804
956
|
this.capture = null;
|
|
957
|
+
this.lkMedia?.disconnect();
|
|
958
|
+
this.lkMedia = null;
|
|
805
959
|
this.playback?.close();
|
|
806
960
|
this.playback = null;
|
|
807
961
|
try {
|
|
@@ -854,28 +1008,17 @@ var BrowserVoiceClient = class {
|
|
|
854
1008
|
async start() {
|
|
855
1009
|
this.setState("connecting");
|
|
856
1010
|
this.startedAt = Date.now();
|
|
1011
|
+
this.mediaMode = this.args.media?.kind === "livekit" ? "livekit-pending" : "ws";
|
|
857
1012
|
const url = buildWsUrl({
|
|
858
1013
|
apiBase: this.args.config.apiBase,
|
|
859
1014
|
agentId: this.args.options.agentId,
|
|
860
1015
|
token: this.args.token,
|
|
861
|
-
bargeIn: this.args.options.bargeIn
|
|
862
|
-
|
|
863
|
-
this.playback = createAudioPlayback({
|
|
864
|
-
onVolume: (v) => {
|
|
865
|
-
this.outputVolume = v;
|
|
866
|
-
this.args.options.onVolume?.({ input: this.inputVolume, output: v });
|
|
867
|
-
}
|
|
1016
|
+
bargeIn: this.args.options.bargeIn,
|
|
1017
|
+
media: this.mediaMode === "ws" ? void 0 : "livekit"
|
|
868
1018
|
});
|
|
869
|
-
|
|
870
|
-
await this.playback.resume();
|
|
871
|
-
} catch {
|
|
872
|
-
}
|
|
1019
|
+
if (this.mediaMode === "ws") await this.ensureWsPlayback();
|
|
873
1020
|
this.rws = createReconnectingWebSocket(
|
|
874
|
-
{
|
|
875
|
-
url,
|
|
876
|
-
wsFactory: this.args.wsFactory,
|
|
877
|
-
maxRetries: 3
|
|
878
|
-
},
|
|
1021
|
+
{ url, wsFactory: this.args.wsFactory, maxRetries: 3 },
|
|
879
1022
|
(ev) => this.handleSocketEvent(ev)
|
|
880
1023
|
);
|
|
881
1024
|
}
|
|
@@ -1060,6 +1203,20 @@ async function createWebRtcCall(opts) {
|
|
|
1060
1203
|
};
|
|
1061
1204
|
}
|
|
1062
1205
|
|
|
1206
|
+
// src/livekit/loadLiveKit.ts
|
|
1207
|
+
var lkPromise;
|
|
1208
|
+
var loadLiveKit = (requiredBy = "this feature") => {
|
|
1209
|
+
lkPromise ?? (lkPromise = import("livekit-client").catch((e) => {
|
|
1210
|
+
lkPromise = void 0;
|
|
1211
|
+
const wrapped = new Error(
|
|
1212
|
+
`${requiredBy} requires the optional peer dependency 'livekit-client' \u2014 npm install livekit-client`
|
|
1213
|
+
);
|
|
1214
|
+
wrapped.cause = e;
|
|
1215
|
+
throw wrapped;
|
|
1216
|
+
}));
|
|
1217
|
+
return lkPromise;
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1063
1220
|
// src/textSession.ts
|
|
1064
1221
|
async function startTextSession(opts) {
|
|
1065
1222
|
const f = opts.fetch ?? fetch;
|
|
@@ -1156,7 +1313,7 @@ var parseIncomingCall = (raw) => {
|
|
|
1156
1313
|
if (typeof p.agentId !== "string" || p.agentId.length === 0) {
|
|
1157
1314
|
throw new Error("parseIncomingCall: missing `agentId`");
|
|
1158
1315
|
}
|
|
1159
|
-
const transport = p.transport === "webrtc" ? "webrtc" : "ws";
|
|
1316
|
+
const transport = p.transport === "webrtc" ? "webrtc" : p.transport === "livekit" ? "livekit" : "ws";
|
|
1160
1317
|
const out = { token: p.token, agentId: p.agentId, transport };
|
|
1161
1318
|
if (transport === "webrtc" && typeof p.webrtcGatewayBase === "string") {
|
|
1162
1319
|
out.webrtcGatewayBase = p.webrtcGatewayBase;
|
|
@@ -1213,6 +1370,27 @@ var AssistantVoiceFactory = class {
|
|
|
1213
1370
|
clientTools: options.clientTools
|
|
1214
1371
|
});
|
|
1215
1372
|
}
|
|
1373
|
+
if (resolved.transport === "livekit") {
|
|
1374
|
+
let lk = null;
|
|
1375
|
+
let loadError = "";
|
|
1376
|
+
try {
|
|
1377
|
+
lk = await loadLiveKit("transport 'livekit'");
|
|
1378
|
+
} catch (e) {
|
|
1379
|
+
loadError = e instanceof Error ? e.message : String(e);
|
|
1380
|
+
}
|
|
1381
|
+
if (!lk) {
|
|
1382
|
+
options.onTransportChange?.({ requested: "livekit", actual: "ws", reason: loadError });
|
|
1383
|
+
}
|
|
1384
|
+
const client2 = new BrowserVoiceClient({
|
|
1385
|
+
config: this.config,
|
|
1386
|
+
options: { ...options, context, metadata },
|
|
1387
|
+
token: resolved.token,
|
|
1388
|
+
wsFactory: browserWsFactory,
|
|
1389
|
+
media: lk ? { kind: "livekit", lk } : void 0
|
|
1390
|
+
});
|
|
1391
|
+
await client2.start();
|
|
1392
|
+
return client2;
|
|
1393
|
+
}
|
|
1216
1394
|
const client = new BrowserVoiceClient({
|
|
1217
1395
|
config: this.config,
|
|
1218
1396
|
// Carry merged context/metadata through to startCall so server can
|
|
@@ -1273,17 +1451,6 @@ var decodeAnalysis = (bytes) => {
|
|
|
1273
1451
|
};
|
|
1274
1452
|
|
|
1275
1453
|
// src/room.ts
|
|
1276
|
-
var lkPromise;
|
|
1277
|
-
var loadLiveKit = () => {
|
|
1278
|
-
lkPromise ?? (lkPromise = import("livekit-client").catch((e) => {
|
|
1279
|
-
lkPromise = void 0;
|
|
1280
|
-
const msg = "joinRoom requires the optional peer dependency 'livekit-client' \u2014 npm install livekit-client";
|
|
1281
|
-
const wrapped = new Error(msg);
|
|
1282
|
-
wrapped.cause = e;
|
|
1283
|
-
throw wrapped;
|
|
1284
|
-
}));
|
|
1285
|
-
return lkPromise;
|
|
1286
|
-
};
|
|
1287
1454
|
var identityToPid = (identity) => identity.startsWith("guest:") ? identity.slice("guest:".length) : identity;
|
|
1288
1455
|
var joinRoom = async (opts) => {
|
|
1289
1456
|
const exchangeUrl = `${opts.apiBase.replace(/\/+$/, "")}/v1/rooms/${encodeURIComponent(
|
|
@@ -1308,7 +1475,7 @@ var joinRoom = async (opts) => {
|
|
|
1308
1475
|
}
|
|
1309
1476
|
});
|
|
1310
1477
|
};
|
|
1311
|
-
const lk = await loadLiveKit();
|
|
1478
|
+
const lk = await loadLiveKit("joinRoom");
|
|
1312
1479
|
const trackKind = (t) => t.kind === lk.Track.Kind.Video ? "video" : "audio";
|
|
1313
1480
|
const trackSource = (s) => {
|
|
1314
1481
|
switch (s) {
|