@voice-ai-labs/web-sdk 0.3.0 → 0.5.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 +184 -40
- package/dist/client/agents.d.ts +4 -5
- package/dist/client/agents.d.ts.map +1 -1
- package/dist/client/agents.js +7 -6
- package/dist/client/agents.js.map +1 -1
- package/dist/client/base.d.ts +1 -1
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +1 -1
- package/dist/client/base.js.map +1 -1
- package/dist/client/index.d.ts +3 -62
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -64
- package/dist/client/index.js.map +1 -1
- package/dist/client/knowledge-base.js +1 -1
- package/dist/client/knowledge-base.js.map +1 -1
- package/dist/client/tts.d.ts +227 -0
- package/dist/client/tts.d.ts.map +1 -0
- package/dist/client/tts.js +259 -0
- package/dist/client/tts.js.map +1 -0
- package/dist/index.d.ts +85 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +754 -49
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +754 -49
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +86 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -4130,6 +4130,12 @@ const ParticipantInfo = /* @__PURE__ */proto3.makeMessageType("livekit.Participa
|
|
|
4130
4130
|
kind: "enum",
|
|
4131
4131
|
T: proto3.getEnumType(ParticipantInfo_KindDetail),
|
|
4132
4132
|
repeated: true
|
|
4133
|
+
}, {
|
|
4134
|
+
no: 19,
|
|
4135
|
+
name: "data_tracks",
|
|
4136
|
+
kind: "message",
|
|
4137
|
+
T: DataTrackInfo,
|
|
4138
|
+
repeated: true
|
|
4133
4139
|
}]);
|
|
4134
4140
|
const ParticipantInfo_State = /* @__PURE__ */proto3.makeEnum("livekit.ParticipantInfo.State", [{
|
|
4135
4141
|
no: 0,
|
|
@@ -4162,6 +4168,9 @@ const ParticipantInfo_Kind = /* @__PURE__ */proto3.makeEnum("livekit.Participant
|
|
|
4162
4168
|
}, {
|
|
4163
4169
|
no: 7,
|
|
4164
4170
|
name: "CONNECTOR"
|
|
4171
|
+
}, {
|
|
4172
|
+
no: 8,
|
|
4173
|
+
name: "BRIDGE"
|
|
4165
4174
|
}]);
|
|
4166
4175
|
const ParticipantInfo_KindDetail = /* @__PURE__ */proto3.makeEnum("livekit.ParticipantInfo.KindDetail", [{
|
|
4167
4176
|
no: 0,
|
|
@@ -4169,6 +4178,15 @@ const ParticipantInfo_KindDetail = /* @__PURE__ */proto3.makeEnum("livekit.Parti
|
|
|
4169
4178
|
}, {
|
|
4170
4179
|
no: 1,
|
|
4171
4180
|
name: "FORWARDED"
|
|
4181
|
+
}, {
|
|
4182
|
+
no: 2,
|
|
4183
|
+
name: "CONNECTOR_WHATSAPP"
|
|
4184
|
+
}, {
|
|
4185
|
+
no: 3,
|
|
4186
|
+
name: "CONNECTOR_TWILIO"
|
|
4187
|
+
}, {
|
|
4188
|
+
no: 4,
|
|
4189
|
+
name: "BRIDGE_RTSP"
|
|
4172
4190
|
}]);
|
|
4173
4191
|
const Encryption_Type = /* @__PURE__ */proto3.makeEnum("livekit.Encryption.Type", [{
|
|
4174
4192
|
no: 0,
|
|
@@ -4332,6 +4350,37 @@ const TrackInfo = /* @__PURE__ */proto3.makeMessageType("livekit.TrackInfo", ()
|
|
|
4332
4350
|
kind: "enum",
|
|
4333
4351
|
T: proto3.getEnumType(BackupCodecPolicy$1)
|
|
4334
4352
|
}]);
|
|
4353
|
+
const DataTrackInfo = /* @__PURE__ */proto3.makeMessageType("livekit.DataTrackInfo", () => [{
|
|
4354
|
+
no: 1,
|
|
4355
|
+
name: "pub_handle",
|
|
4356
|
+
kind: "scalar",
|
|
4357
|
+
T: 13
|
|
4358
|
+
/* ScalarType.UINT32 */
|
|
4359
|
+
}, {
|
|
4360
|
+
no: 2,
|
|
4361
|
+
name: "sid",
|
|
4362
|
+
kind: "scalar",
|
|
4363
|
+
T: 9
|
|
4364
|
+
/* ScalarType.STRING */
|
|
4365
|
+
}, {
|
|
4366
|
+
no: 3,
|
|
4367
|
+
name: "name",
|
|
4368
|
+
kind: "scalar",
|
|
4369
|
+
T: 9
|
|
4370
|
+
/* ScalarType.STRING */
|
|
4371
|
+
}, {
|
|
4372
|
+
no: 4,
|
|
4373
|
+
name: "encryption",
|
|
4374
|
+
kind: "enum",
|
|
4375
|
+
T: proto3.getEnumType(Encryption_Type)
|
|
4376
|
+
}]);
|
|
4377
|
+
const DataTrackSubscriptionOptions = /* @__PURE__ */proto3.makeMessageType("livekit.DataTrackSubscriptionOptions", () => [{
|
|
4378
|
+
no: 1,
|
|
4379
|
+
name: "target_fps",
|
|
4380
|
+
kind: "scalar",
|
|
4381
|
+
T: 13,
|
|
4382
|
+
opt: true
|
|
4383
|
+
}]);
|
|
4335
4384
|
const VideoLayer = /* @__PURE__ */proto3.makeMessageType("livekit.VideoLayer", () => [{
|
|
4336
4385
|
no: 1,
|
|
4337
4386
|
name: "quality",
|
|
@@ -4373,6 +4422,12 @@ const VideoLayer = /* @__PURE__ */proto3.makeMessageType("livekit.VideoLayer", (
|
|
|
4373
4422
|
kind: "scalar",
|
|
4374
4423
|
T: 9
|
|
4375
4424
|
/* ScalarType.STRING */
|
|
4425
|
+
}, {
|
|
4426
|
+
no: 8,
|
|
4427
|
+
name: "repair_ssrc",
|
|
4428
|
+
kind: "scalar",
|
|
4429
|
+
T: 13
|
|
4430
|
+
/* ScalarType.UINT32 */
|
|
4376
4431
|
}]);
|
|
4377
4432
|
const VideoLayer_Mode = /* @__PURE__ */proto3.makeEnum("livekit.VideoLayer.Mode", [{
|
|
4378
4433
|
no: 0,
|
|
@@ -5387,6 +5442,24 @@ const SignalRequest = /* @__PURE__ */proto3.makeMessageType("livekit.SignalReque
|
|
|
5387
5442
|
kind: "message",
|
|
5388
5443
|
T: UpdateLocalVideoTrack,
|
|
5389
5444
|
oneof: "message"
|
|
5445
|
+
}, {
|
|
5446
|
+
no: 19,
|
|
5447
|
+
name: "publish_data_track_request",
|
|
5448
|
+
kind: "message",
|
|
5449
|
+
T: PublishDataTrackRequest,
|
|
5450
|
+
oneof: "message"
|
|
5451
|
+
}, {
|
|
5452
|
+
no: 20,
|
|
5453
|
+
name: "unpublish_data_track_request",
|
|
5454
|
+
kind: "message",
|
|
5455
|
+
T: UnpublishDataTrackRequest,
|
|
5456
|
+
oneof: "message"
|
|
5457
|
+
}, {
|
|
5458
|
+
no: 21,
|
|
5459
|
+
name: "update_data_subscription",
|
|
5460
|
+
kind: "message",
|
|
5461
|
+
T: UpdateDataSubscription,
|
|
5462
|
+
oneof: "message"
|
|
5390
5463
|
}]);
|
|
5391
5464
|
const SignalResponse = /* @__PURE__ */proto3.makeMessageType("livekit.SignalResponse", () => [{
|
|
5392
5465
|
no: 1,
|
|
@@ -5538,6 +5611,24 @@ const SignalResponse = /* @__PURE__ */proto3.makeMessageType("livekit.SignalResp
|
|
|
5538
5611
|
kind: "message",
|
|
5539
5612
|
T: SubscribedAudioCodecUpdate,
|
|
5540
5613
|
oneof: "message"
|
|
5614
|
+
}, {
|
|
5615
|
+
no: 27,
|
|
5616
|
+
name: "publish_data_track_response",
|
|
5617
|
+
kind: "message",
|
|
5618
|
+
T: PublishDataTrackResponse,
|
|
5619
|
+
oneof: "message"
|
|
5620
|
+
}, {
|
|
5621
|
+
no: 28,
|
|
5622
|
+
name: "unpublish_data_track_response",
|
|
5623
|
+
kind: "message",
|
|
5624
|
+
T: UnpublishDataTrackResponse,
|
|
5625
|
+
oneof: "message"
|
|
5626
|
+
}, {
|
|
5627
|
+
no: 29,
|
|
5628
|
+
name: "data_track_subscriber_handles",
|
|
5629
|
+
kind: "message",
|
|
5630
|
+
T: DataTrackSubscriberHandles,
|
|
5631
|
+
oneof: "message"
|
|
5541
5632
|
}]);
|
|
5542
5633
|
const SimulcastCodec = /* @__PURE__ */proto3.makeMessageType("livekit.SimulcastCodec", () => [{
|
|
5543
5634
|
no: 1,
|
|
@@ -5662,6 +5753,74 @@ const AddTrackRequest = /* @__PURE__ */proto3.makeMessageType("livekit.AddTrackR
|
|
|
5662
5753
|
T: proto3.getEnumType(AudioTrackFeature),
|
|
5663
5754
|
repeated: true
|
|
5664
5755
|
}]);
|
|
5756
|
+
const PublishDataTrackRequest = /* @__PURE__ */proto3.makeMessageType("livekit.PublishDataTrackRequest", () => [{
|
|
5757
|
+
no: 1,
|
|
5758
|
+
name: "pub_handle",
|
|
5759
|
+
kind: "scalar",
|
|
5760
|
+
T: 13
|
|
5761
|
+
/* ScalarType.UINT32 */
|
|
5762
|
+
}, {
|
|
5763
|
+
no: 2,
|
|
5764
|
+
name: "name",
|
|
5765
|
+
kind: "scalar",
|
|
5766
|
+
T: 9
|
|
5767
|
+
/* ScalarType.STRING */
|
|
5768
|
+
}, {
|
|
5769
|
+
no: 3,
|
|
5770
|
+
name: "encryption",
|
|
5771
|
+
kind: "enum",
|
|
5772
|
+
T: proto3.getEnumType(Encryption_Type)
|
|
5773
|
+
}]);
|
|
5774
|
+
const PublishDataTrackResponse = /* @__PURE__ */proto3.makeMessageType("livekit.PublishDataTrackResponse", () => [{
|
|
5775
|
+
no: 1,
|
|
5776
|
+
name: "info",
|
|
5777
|
+
kind: "message",
|
|
5778
|
+
T: DataTrackInfo
|
|
5779
|
+
}]);
|
|
5780
|
+
const UnpublishDataTrackRequest = /* @__PURE__ */proto3.makeMessageType("livekit.UnpublishDataTrackRequest", () => [{
|
|
5781
|
+
no: 1,
|
|
5782
|
+
name: "pub_handle",
|
|
5783
|
+
kind: "scalar",
|
|
5784
|
+
T: 13
|
|
5785
|
+
/* ScalarType.UINT32 */
|
|
5786
|
+
}]);
|
|
5787
|
+
const UnpublishDataTrackResponse = /* @__PURE__ */proto3.makeMessageType("livekit.UnpublishDataTrackResponse", () => [{
|
|
5788
|
+
no: 1,
|
|
5789
|
+
name: "info",
|
|
5790
|
+
kind: "message",
|
|
5791
|
+
T: DataTrackInfo
|
|
5792
|
+
}]);
|
|
5793
|
+
const DataTrackSubscriberHandles = /* @__PURE__ */proto3.makeMessageType("livekit.DataTrackSubscriberHandles", () => [{
|
|
5794
|
+
no: 1,
|
|
5795
|
+
name: "sub_handles",
|
|
5796
|
+
kind: "map",
|
|
5797
|
+
K: 13,
|
|
5798
|
+
V: {
|
|
5799
|
+
kind: "message",
|
|
5800
|
+
T: DataTrackSubscriberHandles_PublishedDataTrack
|
|
5801
|
+
}
|
|
5802
|
+
}]);
|
|
5803
|
+
const DataTrackSubscriberHandles_PublishedDataTrack = /* @__PURE__ */proto3.makeMessageType("livekit.DataTrackSubscriberHandles.PublishedDataTrack", () => [{
|
|
5804
|
+
no: 1,
|
|
5805
|
+
name: "publisher_identity",
|
|
5806
|
+
kind: "scalar",
|
|
5807
|
+
T: 9
|
|
5808
|
+
/* ScalarType.STRING */
|
|
5809
|
+
}, {
|
|
5810
|
+
no: 2,
|
|
5811
|
+
name: "publisher_sid",
|
|
5812
|
+
kind: "scalar",
|
|
5813
|
+
T: 9
|
|
5814
|
+
/* ScalarType.STRING */
|
|
5815
|
+
}, {
|
|
5816
|
+
no: 3,
|
|
5817
|
+
name: "track_sid",
|
|
5818
|
+
kind: "scalar",
|
|
5819
|
+
T: 9
|
|
5820
|
+
/* ScalarType.STRING */
|
|
5821
|
+
}], {
|
|
5822
|
+
localName: "DataTrackSubscriberHandles_PublishedDataTrack"
|
|
5823
|
+
});
|
|
5665
5824
|
const TrickleRequest = /* @__PURE__ */proto3.makeMessageType("livekit.TrickleRequest", () => [{
|
|
5666
5825
|
no: 1,
|
|
5667
5826
|
name: "candidateInit",
|
|
@@ -5877,6 +6036,33 @@ const UpdateSubscription = /* @__PURE__ */proto3.makeMessageType("livekit.Update
|
|
|
5877
6036
|
T: ParticipantTracks,
|
|
5878
6037
|
repeated: true
|
|
5879
6038
|
}]);
|
|
6039
|
+
const UpdateDataSubscription = /* @__PURE__ */proto3.makeMessageType("livekit.UpdateDataSubscription", () => [{
|
|
6040
|
+
no: 1,
|
|
6041
|
+
name: "updates",
|
|
6042
|
+
kind: "message",
|
|
6043
|
+
T: UpdateDataSubscription_Update,
|
|
6044
|
+
repeated: true
|
|
6045
|
+
}]);
|
|
6046
|
+
const UpdateDataSubscription_Update = /* @__PURE__ */proto3.makeMessageType("livekit.UpdateDataSubscription.Update", () => [{
|
|
6047
|
+
no: 1,
|
|
6048
|
+
name: "track_sid",
|
|
6049
|
+
kind: "scalar",
|
|
6050
|
+
T: 9
|
|
6051
|
+
/* ScalarType.STRING */
|
|
6052
|
+
}, {
|
|
6053
|
+
no: 2,
|
|
6054
|
+
name: "subscribe",
|
|
6055
|
+
kind: "scalar",
|
|
6056
|
+
T: 8
|
|
6057
|
+
/* ScalarType.BOOL */
|
|
6058
|
+
}, {
|
|
6059
|
+
no: 3,
|
|
6060
|
+
name: "options",
|
|
6061
|
+
kind: "message",
|
|
6062
|
+
T: DataTrackSubscriptionOptions
|
|
6063
|
+
}], {
|
|
6064
|
+
localName: "UpdateDataSubscription_Update"
|
|
6065
|
+
});
|
|
5880
6066
|
const UpdateTrackSettings = /* @__PURE__ */proto3.makeMessageType("livekit.UpdateTrackSettings", () => [{
|
|
5881
6067
|
no: 1,
|
|
5882
6068
|
name: "track_sids",
|
|
@@ -6283,6 +6469,12 @@ const SyncState = /* @__PURE__ */proto3.makeMessageType("livekit.SyncState", ()
|
|
|
6283
6469
|
kind: "message",
|
|
6284
6470
|
T: DataChannelReceiveState,
|
|
6285
6471
|
repeated: true
|
|
6472
|
+
}, {
|
|
6473
|
+
no: 8,
|
|
6474
|
+
name: "publish_data_tracks",
|
|
6475
|
+
kind: "message",
|
|
6476
|
+
T: PublishDataTrackResponse,
|
|
6477
|
+
repeated: true
|
|
6286
6478
|
}]);
|
|
6287
6479
|
const DataChannelReceiveState = /* @__PURE__ */proto3.makeMessageType("livekit.DataChannelReceiveState", () => [{
|
|
6288
6480
|
no: 1,
|
|
@@ -6487,6 +6679,18 @@ const RequestResponse = /* @__PURE__ */proto3.makeMessageType("livekit.RequestRe
|
|
|
6487
6679
|
kind: "message",
|
|
6488
6680
|
T: UpdateLocalVideoTrack,
|
|
6489
6681
|
oneof: "request"
|
|
6682
|
+
}, {
|
|
6683
|
+
no: 10,
|
|
6684
|
+
name: "publish_data_track",
|
|
6685
|
+
kind: "message",
|
|
6686
|
+
T: PublishDataTrackRequest,
|
|
6687
|
+
oneof: "request"
|
|
6688
|
+
}, {
|
|
6689
|
+
no: 11,
|
|
6690
|
+
name: "unpublish_data_track",
|
|
6691
|
+
kind: "message",
|
|
6692
|
+
T: UnpublishDataTrackRequest,
|
|
6693
|
+
oneof: "request"
|
|
6490
6694
|
}]);
|
|
6491
6695
|
const RequestResponse_Reason = /* @__PURE__ */proto3.makeEnum("livekit.RequestResponse.Reason", [{
|
|
6492
6696
|
no: 0,
|
|
@@ -6509,6 +6713,18 @@ const RequestResponse_Reason = /* @__PURE__ */proto3.makeEnum("livekit.RequestRe
|
|
|
6509
6713
|
}, {
|
|
6510
6714
|
no: 6,
|
|
6511
6715
|
name: "UNCLASSIFIED_ERROR"
|
|
6716
|
+
}, {
|
|
6717
|
+
no: 7,
|
|
6718
|
+
name: "INVALID_HANDLE"
|
|
6719
|
+
}, {
|
|
6720
|
+
no: 8,
|
|
6721
|
+
name: "INVALID_NAME"
|
|
6722
|
+
}, {
|
|
6723
|
+
no: 9,
|
|
6724
|
+
name: "DUPLICATE_HANDLE"
|
|
6725
|
+
}, {
|
|
6726
|
+
no: 10,
|
|
6727
|
+
name: "DUPLICATE_NAME"
|
|
6512
6728
|
}]);
|
|
6513
6729
|
const TrackSubscribed = /* @__PURE__ */proto3.makeMessageType("livekit.TrackSubscribed", () => [{
|
|
6514
6730
|
no: 1,
|
|
@@ -6541,6 +6757,12 @@ const ConnectionSettings = /* @__PURE__ */proto3.makeMessageType("livekit.Connec
|
|
|
6541
6757
|
kind: "scalar",
|
|
6542
6758
|
T: 8
|
|
6543
6759
|
/* ScalarType.BOOL */
|
|
6760
|
+
}, {
|
|
6761
|
+
no: 5,
|
|
6762
|
+
name: "auto_subscribe_data_track",
|
|
6763
|
+
kind: "scalar",
|
|
6764
|
+
T: 8,
|
|
6765
|
+
opt: true
|
|
6544
6766
|
}]);
|
|
6545
6767
|
const JoinRequest = /* @__PURE__ */proto3.makeMessageType("livekit.JoinRequest", () => [{
|
|
6546
6768
|
no: 1,
|
|
@@ -10391,7 +10613,8 @@ function adapterFactory() {
|
|
|
10391
10613
|
|
|
10392
10614
|
adapterFactory({
|
|
10393
10615
|
window: typeof window === 'undefined' ? undefined : window
|
|
10394
|
-
});
|
|
10616
|
+
});var _a, _b;
|
|
10617
|
+
class TypedPromise extends (_b = Promise) {
|
|
10395
10618
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
10396
10619
|
constructor(executor) {
|
|
10397
10620
|
super(executor);
|
|
@@ -10408,7 +10631,11 @@ adapterFactory({
|
|
|
10408
10631
|
static race(values) {
|
|
10409
10632
|
return super.race(values);
|
|
10410
10633
|
}
|
|
10411
|
-
}
|
|
10634
|
+
}
|
|
10635
|
+
_a = TypedPromise;
|
|
10636
|
+
TypedPromise.resolve = value => {
|
|
10637
|
+
return Reflect.get(_b, "resolve", _a).call(_a, value);
|
|
10638
|
+
};// tiny, simplified version of https://github.com/lancedikson/bowser/blob/master/src/parser-browsers.js
|
|
10412
10639
|
// reduced to only differentiate Chrome(ium) based browsers / Firefox / Safari
|
|
10413
10640
|
const commonVersionIdentifier = /version\/(\d+(\.?_?\d+)+)/i;
|
|
10414
10641
|
let browserDetails;
|
|
@@ -10474,14 +10701,23 @@ function getMatch(exp, ua) {
|
|
|
10474
10701
|
}
|
|
10475
10702
|
function getOSVersion(ua) {
|
|
10476
10703
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
|
10477
|
-
}var version$1 = "2.17.
|
|
10478
|
-
const protocolVersion = 16
|
|
10479
|
-
|
|
10480
|
-
|
|
10704
|
+
}var version$1 = "2.17.1";const version = version$1;
|
|
10705
|
+
const protocolVersion = 16;/** Base error that all LiveKit specific custom errors inherit from. */
|
|
10706
|
+
class LivekitError extends Error {
|
|
10707
|
+
constructor(code, message, options) {
|
|
10708
|
+
super(message || 'an error has occurred');
|
|
10481
10709
|
this.name = 'LiveKitError';
|
|
10482
10710
|
this.code = code;
|
|
10711
|
+
if (typeof (options === null || options === void 0 ? void 0 : options.cause) !== 'undefined') {
|
|
10712
|
+
this.cause = options === null || options === void 0 ? void 0 : options.cause;
|
|
10713
|
+
}
|
|
10483
10714
|
}
|
|
10484
10715
|
}
|
|
10716
|
+
/**
|
|
10717
|
+
* LiveKit specific error type representing an error with an associated set of reasons.
|
|
10718
|
+
* Use this to represent an error with multiple different but contextually related variants.
|
|
10719
|
+
* */
|
|
10720
|
+
class LivekitReasonedError extends LivekitError {}
|
|
10485
10721
|
var ConnectionErrorReason;
|
|
10486
10722
|
(function (ConnectionErrorReason) {
|
|
10487
10723
|
ConnectionErrorReason[ConnectionErrorReason["NotAllowed"] = 0] = "NotAllowed";
|
|
@@ -10493,7 +10729,7 @@ var ConnectionErrorReason;
|
|
|
10493
10729
|
ConnectionErrorReason[ConnectionErrorReason["WebSocket"] = 6] = "WebSocket";
|
|
10494
10730
|
ConnectionErrorReason[ConnectionErrorReason["ServiceNotFound"] = 7] = "ServiceNotFound";
|
|
10495
10731
|
})(ConnectionErrorReason || (ConnectionErrorReason = {}));
|
|
10496
|
-
class ConnectionError extends
|
|
10732
|
+
class ConnectionError extends LivekitReasonedError {
|
|
10497
10733
|
constructor(message, reason, status, context) {
|
|
10498
10734
|
super(1, message);
|
|
10499
10735
|
this.name = 'ConnectionError';
|
|
@@ -10564,7 +10800,7 @@ class PublishTrackError extends LivekitError {
|
|
|
10564
10800
|
this.status = status;
|
|
10565
10801
|
}
|
|
10566
10802
|
}
|
|
10567
|
-
class SignalRequestError extends
|
|
10803
|
+
class SignalRequestError extends LivekitReasonedError {
|
|
10568
10804
|
constructor(message, reason) {
|
|
10569
10805
|
super(15, message);
|
|
10570
10806
|
this.name = 'SignalRequestError';
|
|
@@ -10590,7 +10826,7 @@ var DataStreamErrorReason;
|
|
|
10590
10826
|
// Encryption type mismatch.
|
|
10591
10827
|
DataStreamErrorReason[DataStreamErrorReason["EncryptionTypeMismatch"] = 8] = "EncryptionTypeMismatch";
|
|
10592
10828
|
})(DataStreamErrorReason || (DataStreamErrorReason = {}));
|
|
10593
|
-
class DataStreamError extends
|
|
10829
|
+
class DataStreamError extends LivekitReasonedError {
|
|
10594
10830
|
constructor(message, reason) {
|
|
10595
10831
|
super(16, message);
|
|
10596
10832
|
this.name = 'DataStreamError';
|
|
@@ -20117,7 +20353,8 @@ class TextStreamReader extends BaseStreamReader {
|
|
|
20117
20353
|
topic: streamHeader.topic,
|
|
20118
20354
|
timestamp: Number(streamHeader.timestamp),
|
|
20119
20355
|
attributes: streamHeader.attributes,
|
|
20120
|
-
encryptionType
|
|
20356
|
+
encryptionType,
|
|
20357
|
+
attachedStreamIds: streamHeader.contentHeader.value.attachedStreamIds
|
|
20121
20358
|
};
|
|
20122
20359
|
const stream = new ReadableStream({
|
|
20123
20360
|
start: controller => {
|
|
@@ -20270,7 +20507,8 @@ class OutgoingDataStreamManager {
|
|
|
20270
20507
|
topic: (_b = options === null || options === void 0 ? void 0 : options.topic) !== null && _b !== void 0 ? _b : '',
|
|
20271
20508
|
size: options === null || options === void 0 ? void 0 : options.totalSize,
|
|
20272
20509
|
attributes: options === null || options === void 0 ? void 0 : options.attributes,
|
|
20273
|
-
encryptionType: ((_c = this.engine.e2eeManager) === null || _c === void 0 ? void 0 : _c.isDataChannelEncryptionEnabled) ? Encryption_Type.GCM : Encryption_Type.NONE
|
|
20510
|
+
encryptionType: ((_c = this.engine.e2eeManager) === null || _c === void 0 ? void 0 : _c.isDataChannelEncryptionEnabled) ? Encryption_Type.GCM : Encryption_Type.NONE,
|
|
20511
|
+
attachedStreamIds: options === null || options === void 0 ? void 0 : options.attachedStreamIds
|
|
20274
20512
|
};
|
|
20275
20513
|
const header = new DataStream_Header({
|
|
20276
20514
|
streamId,
|
|
@@ -20283,7 +20521,7 @@ class OutgoingDataStreamManager {
|
|
|
20283
20521
|
case: 'textHeader',
|
|
20284
20522
|
value: new DataStream_TextHeader({
|
|
20285
20523
|
version: options === null || options === void 0 ? void 0 : options.version,
|
|
20286
|
-
attachedStreamIds:
|
|
20524
|
+
attachedStreamIds: info.attachedStreamIds,
|
|
20287
20525
|
replyToStreamId: options === null || options === void 0 ? void 0 : options.replyToStreamId,
|
|
20288
20526
|
operationType: (options === null || options === void 0 ? void 0 : options.type) === 'update' ? DataStream_OperationType.UPDATE : DataStream_OperationType.CREATE
|
|
20289
20527
|
})
|
|
@@ -26893,7 +27131,44 @@ class JWSSignatureVerificationFailed extends JOSEError {
|
|
|
26893
27131
|
_defineProperty(this, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
|
|
26894
27132
|
}
|
|
26895
27133
|
}
|
|
26896
|
-
_defineProperty(JWSSignatureVerificationFailed, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
|
|
27134
|
+
_defineProperty(JWSSignatureVerificationFailed, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');var DataTrackHandleErrorReason;
|
|
27135
|
+
(function (DataTrackHandleErrorReason) {
|
|
27136
|
+
DataTrackHandleErrorReason[DataTrackHandleErrorReason["Reserved"] = 0] = "Reserved";
|
|
27137
|
+
DataTrackHandleErrorReason[DataTrackHandleErrorReason["TooLarge"] = 1] = "TooLarge";
|
|
27138
|
+
})(DataTrackHandleErrorReason || (DataTrackHandleErrorReason = {}));
|
|
27139
|
+
var DataTrackDeserializeErrorReason;
|
|
27140
|
+
(function (DataTrackDeserializeErrorReason) {
|
|
27141
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["TooShort"] = 0] = "TooShort";
|
|
27142
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["HeaderOverrun"] = 1] = "HeaderOverrun";
|
|
27143
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["MissingExtWords"] = 2] = "MissingExtWords";
|
|
27144
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["UnsupportedVersion"] = 3] = "UnsupportedVersion";
|
|
27145
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["InvalidHandle"] = 4] = "InvalidHandle";
|
|
27146
|
+
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["MalformedExt"] = 5] = "MalformedExt";
|
|
27147
|
+
})(DataTrackDeserializeErrorReason || (DataTrackDeserializeErrorReason = {}));
|
|
27148
|
+
var DataTrackSerializeErrorReason;
|
|
27149
|
+
(function (DataTrackSerializeErrorReason) {
|
|
27150
|
+
DataTrackSerializeErrorReason[DataTrackSerializeErrorReason["TooSmallForHeader"] = 0] = "TooSmallForHeader";
|
|
27151
|
+
DataTrackSerializeErrorReason[DataTrackSerializeErrorReason["TooSmallForPayload"] = 1] = "TooSmallForPayload";
|
|
27152
|
+
})(DataTrackSerializeErrorReason || (DataTrackSerializeErrorReason = {}));
|
|
27153
|
+
var DataTrackExtensionTag;
|
|
27154
|
+
(function (DataTrackExtensionTag) {
|
|
27155
|
+
DataTrackExtensionTag[DataTrackExtensionTag["UserTimestamp"] = 2] = "UserTimestamp";
|
|
27156
|
+
DataTrackExtensionTag[DataTrackExtensionTag["E2ee"] = 1] = "E2ee";
|
|
27157
|
+
})(DataTrackExtensionTag || (DataTrackExtensionTag = {}));
|
|
27158
|
+
DataTrackExtensionTag.UserTimestamp;
|
|
27159
|
+
DataTrackExtensionTag.E2ee;
|
|
27160
|
+
/** Marker indicating a packet's position in relation to a frame. */
|
|
27161
|
+
var FrameMarker;
|
|
27162
|
+
(function (FrameMarker) {
|
|
27163
|
+
/** Packet is the first in a frame. */
|
|
27164
|
+
FrameMarker[FrameMarker["Start"] = 0] = "Start";
|
|
27165
|
+
/** Packet is within a frame. */
|
|
27166
|
+
FrameMarker[FrameMarker["Inter"] = 1] = "Inter";
|
|
27167
|
+
/** Packet is the last in a frame. */
|
|
27168
|
+
FrameMarker[FrameMarker["Final"] = 2] = "Final";
|
|
27169
|
+
/** Packet is the only one in a frame. */
|
|
27170
|
+
FrameMarker[FrameMarker["Single"] = 3] = "Single";
|
|
27171
|
+
})(FrameMarker || (FrameMarker = {}));
|
|
26897
27172
|
|
|
26898
27173
|
/**
|
|
26899
27174
|
* Base HTTP Client for Voice.ai API
|
|
@@ -27052,7 +27327,7 @@ class BaseClient {
|
|
|
27052
27327
|
/**
|
|
27053
27328
|
* Perform DELETE request
|
|
27054
27329
|
*/
|
|
27055
|
-
async
|
|
27330
|
+
async httpDelete(path) {
|
|
27056
27331
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27057
27332
|
method: 'DELETE',
|
|
27058
27333
|
headers: this.getHeaders(),
|
|
@@ -27245,25 +27520,26 @@ class AgentClient extends BaseClient {
|
|
|
27245
27520
|
return this.post(`/agent/${encodeURIComponent(agentId)}/pause`);
|
|
27246
27521
|
}
|
|
27247
27522
|
/**
|
|
27248
|
-
* Delete
|
|
27523
|
+
* Delete an agent
|
|
27249
27524
|
*
|
|
27250
27525
|
* An agent must be paused before being deleted.
|
|
27251
|
-
* Disabled agents will be automatically deleted after a grace period.
|
|
27252
27526
|
*
|
|
27253
27527
|
* @param agentId - The agent ID to delete
|
|
27254
27528
|
* @returns Delete response
|
|
27255
27529
|
*
|
|
27256
27530
|
* @example
|
|
27257
27531
|
* ```typescript
|
|
27258
|
-
* // First pause, then delete
|
|
27259
27532
|
* await client.agents.pause('agent-123');
|
|
27260
|
-
*
|
|
27261
|
-
* console.log('Deleted:', result.message);
|
|
27533
|
+
* await client.agents.disable('agent-123');
|
|
27262
27534
|
* ```
|
|
27263
27535
|
*/
|
|
27264
27536
|
async disable(agentId) {
|
|
27265
27537
|
return this.post(`/agent/${encodeURIComponent(agentId)}/disable`);
|
|
27266
27538
|
}
|
|
27539
|
+
/** Alias for {@link disable} */
|
|
27540
|
+
async delete(agentId) {
|
|
27541
|
+
return this.disable(agentId);
|
|
27542
|
+
}
|
|
27267
27543
|
/**
|
|
27268
27544
|
* Initialize agent from template
|
|
27269
27545
|
*
|
|
@@ -27333,7 +27609,7 @@ class AgentClient extends BaseClient {
|
|
|
27333
27609
|
* ```
|
|
27334
27610
|
*/
|
|
27335
27611
|
async unassignKnowledgeBase(agentId) {
|
|
27336
|
-
await this.
|
|
27612
|
+
await this.httpDelete(`/agent/${encodeURIComponent(agentId)}/knowledge-base`);
|
|
27337
27613
|
}
|
|
27338
27614
|
}
|
|
27339
27615
|
|
|
@@ -27552,7 +27828,7 @@ class KnowledgeBaseClient extends BaseClient {
|
|
|
27552
27828
|
* ```
|
|
27553
27829
|
*/
|
|
27554
27830
|
async remove(kbId) {
|
|
27555
|
-
await
|
|
27831
|
+
await this.httpDelete(`/knowledge-base/${kbId}`);
|
|
27556
27832
|
}
|
|
27557
27833
|
}
|
|
27558
27834
|
|
|
@@ -27698,6 +27974,264 @@ class PhoneNumberClient extends BaseClient {
|
|
|
27698
27974
|
}
|
|
27699
27975
|
}
|
|
27700
27976
|
|
|
27977
|
+
/**
|
|
27978
|
+
* Text-to-Speech (TTS) Client
|
|
27979
|
+
*
|
|
27980
|
+
* Provides methods for:
|
|
27981
|
+
* - Generating speech from text (synchronous and streaming)
|
|
27982
|
+
* - Listing available voices
|
|
27983
|
+
* - Getting voice details
|
|
27984
|
+
* - Cloning voices from audio samples
|
|
27985
|
+
* - Updating and deleting voices
|
|
27986
|
+
*/
|
|
27987
|
+
/**
|
|
27988
|
+
* Client for Text-to-Speech operations
|
|
27989
|
+
*
|
|
27990
|
+
* @example
|
|
27991
|
+
* ```typescript
|
|
27992
|
+
* // List available voices
|
|
27993
|
+
* const voices = await client.tts.listVoices();
|
|
27994
|
+
*
|
|
27995
|
+
* // Generate speech
|
|
27996
|
+
* const audio = await client.tts.synthesize({
|
|
27997
|
+
* text: 'Hello world!',
|
|
27998
|
+
* voice_id: 'voice-123',
|
|
27999
|
+
* language: 'en',
|
|
28000
|
+
* });
|
|
28001
|
+
*
|
|
28002
|
+
* // Clone a voice
|
|
28003
|
+
* const cloned = await client.tts.cloneVoice({
|
|
28004
|
+
* file: audioFile,
|
|
28005
|
+
* name: 'My Voice',
|
|
28006
|
+
* language: 'en',
|
|
28007
|
+
* });
|
|
28008
|
+
* ```
|
|
28009
|
+
*/
|
|
28010
|
+
class TTSClient extends BaseClient {
|
|
28011
|
+
constructor(config) {
|
|
28012
|
+
super(config);
|
|
28013
|
+
}
|
|
28014
|
+
// ==========================================================================
|
|
28015
|
+
// SPEECH GENERATION
|
|
28016
|
+
// ==========================================================================
|
|
28017
|
+
/**
|
|
28018
|
+
* Generate speech from text (returns complete audio file)
|
|
28019
|
+
*
|
|
28020
|
+
* This is the synchronous endpoint - it blocks until generation completes
|
|
28021
|
+
* and returns the entire audio file as a Blob. For lower latency with
|
|
28022
|
+
* chunked streaming, use {@link synthesizeStream}.
|
|
28023
|
+
*
|
|
28024
|
+
* @param options - Speech generation options
|
|
28025
|
+
* @returns Audio blob in the requested format
|
|
28026
|
+
*
|
|
28027
|
+
* @example
|
|
28028
|
+
* ```typescript
|
|
28029
|
+
* const audio = await client.tts.synthesize({
|
|
28030
|
+
* text: 'Hello, welcome to Voice AI!',
|
|
28031
|
+
* voice_id: 'voice-123',
|
|
28032
|
+
* language: 'en',
|
|
28033
|
+
* audio_format: 'mp3',
|
|
28034
|
+
* });
|
|
28035
|
+
*
|
|
28036
|
+
* // Play in browser
|
|
28037
|
+
* const url = URL.createObjectURL(audio);
|
|
28038
|
+
* new Audio(url).play();
|
|
28039
|
+
*
|
|
28040
|
+
* // Or download
|
|
28041
|
+
* const a = document.createElement('a');
|
|
28042
|
+
* a.href = url;
|
|
28043
|
+
* a.download = 'speech.mp3';
|
|
28044
|
+
* a.click();
|
|
28045
|
+
* ```
|
|
28046
|
+
*/
|
|
28047
|
+
async synthesize(options) {
|
|
28048
|
+
return this.postForBlob('/tts/speech', options);
|
|
28049
|
+
}
|
|
28050
|
+
/**
|
|
28051
|
+
* Generate speech from text with HTTP chunked streaming
|
|
28052
|
+
*
|
|
28053
|
+
* Returns a Response object with a readable body stream. Audio chunks
|
|
28054
|
+
* are sent to the client as they are generated, providing lower perceived
|
|
28055
|
+
* latency than {@link synthesize}.
|
|
28056
|
+
*
|
|
28057
|
+
* @param options - Speech generation options
|
|
28058
|
+
* @returns Fetch Response with streaming body
|
|
28059
|
+
*
|
|
28060
|
+
* @example
|
|
28061
|
+
* ```typescript
|
|
28062
|
+
* const response = await client.tts.synthesizeStream({
|
|
28063
|
+
* text: 'Hello, welcome to Voice AI!',
|
|
28064
|
+
* voice_id: 'voice-123',
|
|
28065
|
+
* language: 'en',
|
|
28066
|
+
* });
|
|
28067
|
+
*
|
|
28068
|
+
* // Read chunks as they arrive
|
|
28069
|
+
* const reader = response.body!.getReader();
|
|
28070
|
+
* while (true) {
|
|
28071
|
+
* const { done, value } = await reader.read();
|
|
28072
|
+
* if (done) break;
|
|
28073
|
+
* // Process audio chunk (Uint8Array)
|
|
28074
|
+
* console.log('Received chunk:', value.length, 'bytes');
|
|
28075
|
+
* }
|
|
28076
|
+
*
|
|
28077
|
+
* // Or collect all chunks and create a blob
|
|
28078
|
+
* const response = await client.tts.synthesizeStream({ text: '...', voice_id: '...' });
|
|
28079
|
+
* const blob = await response.blob();
|
|
28080
|
+
* ```
|
|
28081
|
+
*/
|
|
28082
|
+
async synthesizeStream(options) {
|
|
28083
|
+
return this.postForStream('/tts/speech/stream', options);
|
|
28084
|
+
}
|
|
28085
|
+
// ==========================================================================
|
|
28086
|
+
// VOICE MANAGEMENT
|
|
28087
|
+
// ==========================================================================
|
|
28088
|
+
/**
|
|
28089
|
+
* List voices available to the current user
|
|
28090
|
+
*
|
|
28091
|
+
* Returns voices owned by the authenticated user plus default/public voices.
|
|
28092
|
+
* Deleted voices are excluded.
|
|
28093
|
+
*
|
|
28094
|
+
* @returns Array of voice objects
|
|
28095
|
+
*
|
|
28096
|
+
* @example
|
|
28097
|
+
* ```typescript
|
|
28098
|
+
* const voices = await client.tts.listVoices();
|
|
28099
|
+
*
|
|
28100
|
+
* for (const voice of voices) {
|
|
28101
|
+
* console.log(`${voice.name} (${voice.voice_id}): ${voice.status}`);
|
|
28102
|
+
* }
|
|
28103
|
+
*
|
|
28104
|
+
* // Filter to only available voices
|
|
28105
|
+
* const available = voices.filter(v => v.status === 'AVAILABLE');
|
|
28106
|
+
* ```
|
|
28107
|
+
*/
|
|
28108
|
+
async listVoices() {
|
|
28109
|
+
return this.get('/tts/voices');
|
|
28110
|
+
}
|
|
28111
|
+
/**
|
|
28112
|
+
* Get voice details and status
|
|
28113
|
+
*
|
|
28114
|
+
* Useful for polling the status of a voice clone operation
|
|
28115
|
+
* (PENDING -> PROCESSING -> AVAILABLE).
|
|
28116
|
+
*
|
|
28117
|
+
* Access control:
|
|
28118
|
+
* - PUBLIC voices: readable by any authenticated user
|
|
28119
|
+
* - PRIVATE voices: readable only by owner (returns 404 otherwise)
|
|
28120
|
+
*
|
|
28121
|
+
* @param voiceId - The voice ID
|
|
28122
|
+
* @returns Voice details and status
|
|
28123
|
+
*
|
|
28124
|
+
* @example
|
|
28125
|
+
* ```typescript
|
|
28126
|
+
* const voice = await client.tts.getVoice('voice-123');
|
|
28127
|
+
*
|
|
28128
|
+
* if (voice.status === 'AVAILABLE') {
|
|
28129
|
+
* console.log('Voice is ready to use!');
|
|
28130
|
+
* } else if (voice.status === 'PROCESSING') {
|
|
28131
|
+
* console.log('Voice is still being processed...');
|
|
28132
|
+
* }
|
|
28133
|
+
* ```
|
|
28134
|
+
*/
|
|
28135
|
+
async getVoice(voiceId) {
|
|
28136
|
+
return this.get(`/tts/voice/${encodeURIComponent(voiceId)}`);
|
|
28137
|
+
}
|
|
28138
|
+
/**
|
|
28139
|
+
* Clone a voice from a reference audio file
|
|
28140
|
+
*
|
|
28141
|
+
* Accepts an audio file (MP3, WAV, or OGG, max 7.5MB) and creates
|
|
28142
|
+
* a cloned voice. The voice starts in PENDING status and moves to
|
|
28143
|
+
* PROCESSING, then AVAILABLE once ready.
|
|
28144
|
+
*
|
|
28145
|
+
* Use {@link getVoice} to poll the voice status.
|
|
28146
|
+
*
|
|
28147
|
+
* @param options - Clone voice options including audio file
|
|
28148
|
+
* @returns Created voice with ID and initial status (PENDING)
|
|
28149
|
+
*
|
|
28150
|
+
* @example
|
|
28151
|
+
* ```typescript
|
|
28152
|
+
* // From a file input
|
|
28153
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
28154
|
+
* const file = fileInput.files[0];
|
|
28155
|
+
*
|
|
28156
|
+
* const voice = await client.tts.cloneVoice({
|
|
28157
|
+
* file: file,
|
|
28158
|
+
* name: 'My Custom Voice',
|
|
28159
|
+
* language: 'en',
|
|
28160
|
+
* voice_visibility: 'PRIVATE',
|
|
28161
|
+
* });
|
|
28162
|
+
*
|
|
28163
|
+
* console.log('Voice ID:', voice.voice_id);
|
|
28164
|
+
* console.log('Status:', voice.status); // 'PENDING'
|
|
28165
|
+
*
|
|
28166
|
+
* // Poll until ready
|
|
28167
|
+
* let status = voice.status;
|
|
28168
|
+
* while (status !== 'AVAILABLE' && status !== 'FAILED') {
|
|
28169
|
+
* await new Promise(r => setTimeout(r, 2000));
|
|
28170
|
+
* const updated = await client.tts.getVoice(voice.voice_id);
|
|
28171
|
+
* status = updated.status;
|
|
28172
|
+
* console.log('Status:', status);
|
|
28173
|
+
* }
|
|
28174
|
+
* ```
|
|
28175
|
+
*/
|
|
28176
|
+
async cloneVoice(options) {
|
|
28177
|
+
const formData = new FormData();
|
|
28178
|
+
formData.append('file', options.file);
|
|
28179
|
+
if (options.name !== undefined) {
|
|
28180
|
+
formData.append('name', options.name);
|
|
28181
|
+
}
|
|
28182
|
+
if (options.voice_visibility !== undefined) {
|
|
28183
|
+
formData.append('voice_visibility', options.voice_visibility);
|
|
28184
|
+
}
|
|
28185
|
+
if (options.language !== undefined) {
|
|
28186
|
+
formData.append('language', options.language);
|
|
28187
|
+
}
|
|
28188
|
+
return this.postFormData('/tts/clone-voice', formData);
|
|
28189
|
+
}
|
|
28190
|
+
/**
|
|
28191
|
+
* Update voice metadata (name and/or visibility)
|
|
28192
|
+
*
|
|
28193
|
+
* Only the voice owner can update a voice.
|
|
28194
|
+
*
|
|
28195
|
+
* @param voiceId - The voice ID to update
|
|
28196
|
+
* @param options - Fields to update
|
|
28197
|
+
* @returns Updated voice details
|
|
28198
|
+
*
|
|
28199
|
+
* @example
|
|
28200
|
+
* ```typescript
|
|
28201
|
+
* // Rename a voice
|
|
28202
|
+
* const updated = await client.tts.updateVoice('voice-123', {
|
|
28203
|
+
* name: 'New Voice Name',
|
|
28204
|
+
* });
|
|
28205
|
+
*
|
|
28206
|
+
* // Make a voice private
|
|
28207
|
+
* const updated = await client.tts.updateVoice('voice-123', {
|
|
28208
|
+
* voice_visibility: 'PRIVATE',
|
|
28209
|
+
* });
|
|
28210
|
+
* ```
|
|
28211
|
+
*/
|
|
28212
|
+
async updateVoice(voiceId, options) {
|
|
28213
|
+
return this.patch(`/tts/voice/${encodeURIComponent(voiceId)}`, options);
|
|
28214
|
+
}
|
|
28215
|
+
/**
|
|
28216
|
+
* Delete a voice
|
|
28217
|
+
*
|
|
28218
|
+
* Only the voice owner can delete a voice. The voice will no longer
|
|
28219
|
+
* appear in voice listings.
|
|
28220
|
+
*
|
|
28221
|
+
* @param voiceId - The voice ID to delete
|
|
28222
|
+
* @returns Deletion confirmation
|
|
28223
|
+
*
|
|
28224
|
+
* @example
|
|
28225
|
+
* ```typescript
|
|
28226
|
+
* await client.tts.deleteVoice('voice-123');
|
|
28227
|
+
* console.log('Voice deleted');
|
|
28228
|
+
* ```
|
|
28229
|
+
*/
|
|
28230
|
+
async deleteVoice(voiceId) {
|
|
28231
|
+
return this.httpDelete(`/tts/voice/${encodeURIComponent(voiceId)}`);
|
|
28232
|
+
}
|
|
28233
|
+
}
|
|
28234
|
+
|
|
27701
28235
|
/**
|
|
27702
28236
|
* VoiceAgentWidget - UI widget for Voice.ai
|
|
27703
28237
|
*
|
|
@@ -28154,14 +28688,47 @@ const DEFAULT_API_URL = 'https://dev.voice.ai/api/v1';
|
|
|
28154
28688
|
* ```
|
|
28155
28689
|
*/
|
|
28156
28690
|
class VoiceAI {
|
|
28691
|
+
// ==========================================================================
|
|
28692
|
+
// API CLIENTS (REST API)
|
|
28693
|
+
// ==========================================================================
|
|
28694
|
+
/** Agent management - create, update, deploy, pause, delete agents. */
|
|
28695
|
+
get agents() {
|
|
28696
|
+
if (!this._agents)
|
|
28697
|
+
throw new VoiceAIError('API key required for agents API. Pass apiKey in the constructor.');
|
|
28698
|
+
return this._agents;
|
|
28699
|
+
}
|
|
28700
|
+
/** Analytics - call history, transcripts, stats. */
|
|
28701
|
+
get analytics() {
|
|
28702
|
+
if (!this._analytics)
|
|
28703
|
+
throw new VoiceAIError('API key required for analytics API. Pass apiKey in the constructor.');
|
|
28704
|
+
return this._analytics;
|
|
28705
|
+
}
|
|
28706
|
+
/** Knowledge Base - manage RAG documents. */
|
|
28707
|
+
get knowledgeBase() {
|
|
28708
|
+
if (!this._knowledgeBase)
|
|
28709
|
+
throw new VoiceAIError('API key required for knowledgeBase API. Pass apiKey in the constructor.');
|
|
28710
|
+
return this._knowledgeBase;
|
|
28711
|
+
}
|
|
28712
|
+
/** Phone Numbers - search, select, release phone numbers. */
|
|
28713
|
+
get phoneNumbers() {
|
|
28714
|
+
if (!this._phoneNumbers)
|
|
28715
|
+
throw new VoiceAIError('API key required for phoneNumbers API. Pass apiKey in the constructor.');
|
|
28716
|
+
return this._phoneNumbers;
|
|
28717
|
+
}
|
|
28718
|
+
/** Text-to-Speech - generate speech, manage voices, clone voices. */
|
|
28719
|
+
get tts() {
|
|
28720
|
+
if (!this._tts)
|
|
28721
|
+
throw new VoiceAIError('API key required for tts API. Pass apiKey in the constructor.');
|
|
28722
|
+
return this._tts;
|
|
28723
|
+
}
|
|
28157
28724
|
/**
|
|
28158
28725
|
* Create a new VoiceAI client
|
|
28159
28726
|
*
|
|
28160
|
-
* @param config - Configuration options
|
|
28161
|
-
* @param config.apiKey - Your Voice.ai API key (required)
|
|
28727
|
+
* @param config - Configuration options (optional for frontend-only usage)
|
|
28728
|
+
* @param config.apiKey - Your Voice.ai API key (required for API operations and `getConnectionDetails`)
|
|
28162
28729
|
* @param config.apiUrl - Custom API URL (optional, defaults to production)
|
|
28163
28730
|
*/
|
|
28164
|
-
constructor(config) {
|
|
28731
|
+
constructor(config = {}) {
|
|
28165
28732
|
// ==========================================================================
|
|
28166
28733
|
// PRIVATE STATE (Real-time voice)
|
|
28167
28734
|
// ==========================================================================
|
|
@@ -28173,31 +28740,118 @@ class VoiceAI {
|
|
|
28173
28740
|
this.agentStateHandlers = new Set();
|
|
28174
28741
|
this.audioLevelHandlers = new Set();
|
|
28175
28742
|
this.microphoneStateHandlers = new Set();
|
|
28743
|
+
this.effectiveApiKey = '';
|
|
28176
28744
|
this.cachedConnectionDetails = null;
|
|
28177
28745
|
this.currentAgentState = 'disconnected';
|
|
28178
28746
|
this.agentParticipantId = null;
|
|
28179
28747
|
this.audioLevelInterval = null;
|
|
28180
|
-
|
|
28181
|
-
throw new Error('API key is required. Get one at https://voice.ai');
|
|
28182
|
-
}
|
|
28183
|
-
this.apiKey = config.apiKey;
|
|
28748
|
+
this.apiKey = config.apiKey || '';
|
|
28184
28749
|
this.apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
28185
|
-
// Initialize API clients
|
|
28186
|
-
|
|
28187
|
-
|
|
28188
|
-
|
|
28189
|
-
|
|
28190
|
-
|
|
28750
|
+
// Initialize API clients when apiKey is provided
|
|
28751
|
+
if (this.apiKey) {
|
|
28752
|
+
const clientConfig = { apiKey: this.apiKey, apiUrl: this.apiUrl };
|
|
28753
|
+
this._agents = new AgentClient(clientConfig);
|
|
28754
|
+
this._analytics = new AnalyticsClient(clientConfig);
|
|
28755
|
+
this._knowledgeBase = new KnowledgeBaseClient(clientConfig);
|
|
28756
|
+
this._phoneNumbers = new PhoneNumberClient(clientConfig);
|
|
28757
|
+
this._tts = new TTSClient(clientConfig);
|
|
28758
|
+
}
|
|
28191
28759
|
}
|
|
28192
28760
|
// ==========================================================================
|
|
28193
28761
|
// REAL-TIME VOICE CONNECTION
|
|
28194
28762
|
// ==========================================================================
|
|
28195
28763
|
/**
|
|
28196
|
-
*
|
|
28764
|
+
* Get connection details for a voice agent.
|
|
28765
|
+
*
|
|
28766
|
+
* Requires an API key. Call this from your backend, then pass the result
|
|
28767
|
+
* to `connectRoom()` on the frontend.
|
|
28768
|
+
*
|
|
28769
|
+
* @param options - Connection options (agentId, testMode, etc.)
|
|
28770
|
+
* @returns Connection details (serverUrl, participantToken, callId)
|
|
28771
|
+
*
|
|
28772
|
+
* @example
|
|
28773
|
+
* ```typescript
|
|
28774
|
+
* // Server-side: get connection details
|
|
28775
|
+
* const details = await voiceai.getConnectionDetails({ agentId: 'agent-123' });
|
|
28776
|
+
* // Return details to frontend...
|
|
28777
|
+
*
|
|
28778
|
+
* // With test mode
|
|
28779
|
+
* const details = await voiceai.getConnectionDetails({
|
|
28780
|
+
* agentId: 'agent-123',
|
|
28781
|
+
* testMode: true
|
|
28782
|
+
* });
|
|
28783
|
+
* ```
|
|
28784
|
+
*/
|
|
28785
|
+
async getConnectionDetails(options) {
|
|
28786
|
+
return this.fetchConnectionDetails(options);
|
|
28787
|
+
}
|
|
28788
|
+
/**
|
|
28789
|
+
* Connect to a LiveKit room using pre-fetched connection details.
|
|
28790
|
+
*
|
|
28791
|
+
* This is the browser-safe method -- it only needs a room token,
|
|
28792
|
+
* no API key required. Get the connection details from your backend
|
|
28793
|
+
* using `getConnectionDetails()`.
|
|
28794
|
+
*
|
|
28795
|
+
* @param connectionDetails - Server URL, participant token, and call ID from your backend
|
|
28796
|
+
* @param options - Audio/microphone options
|
|
28797
|
+
*
|
|
28798
|
+
* @example
|
|
28799
|
+
* ```typescript
|
|
28800
|
+
* // Frontend: connect using token from your backend
|
|
28801
|
+
* const voiceai = new VoiceAI();
|
|
28802
|
+
* await voiceai.connectRoom(
|
|
28803
|
+
* { serverUrl, participantToken, callId },
|
|
28804
|
+
* { autoPublishMic: true }
|
|
28805
|
+
* );
|
|
28806
|
+
* ```
|
|
28807
|
+
*/
|
|
28808
|
+
async connectRoom(connectionDetails, options = {}) {
|
|
28809
|
+
if (this.connectionStatus.connecting || this.connectionStatus.connected) {
|
|
28810
|
+
throw new Error('Already connected or connecting');
|
|
28811
|
+
}
|
|
28812
|
+
this.updateStatus({ connecting: true, connected: false });
|
|
28813
|
+
this.cachedConnectionDetails = connectionDetails;
|
|
28814
|
+
try {
|
|
28815
|
+
this.room = new Room();
|
|
28816
|
+
this.setupRoomListeners();
|
|
28817
|
+
this.room.prepareConnection(connectionDetails.serverUrl, connectionDetails.participantToken);
|
|
28818
|
+
const preConnectBuffer = options.preConnectBuffer !== false;
|
|
28819
|
+
let connected = false;
|
|
28820
|
+
let lastError;
|
|
28821
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
28822
|
+
try {
|
|
28823
|
+
await Promise.all([
|
|
28824
|
+
this.setupAudio(options, preConnectBuffer),
|
|
28825
|
+
this.room.connect(connectionDetails.serverUrl, connectionDetails.participantToken)
|
|
28826
|
+
]);
|
|
28827
|
+
connected = true;
|
|
28828
|
+
break;
|
|
28829
|
+
}
|
|
28830
|
+
catch (error) {
|
|
28831
|
+
lastError = error;
|
|
28832
|
+
if (attempt < 3) {
|
|
28833
|
+
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
|
28834
|
+
}
|
|
28835
|
+
}
|
|
28836
|
+
}
|
|
28837
|
+
if (!connected) {
|
|
28838
|
+
throw lastError || new Error('Failed to connect after 3 attempts');
|
|
28839
|
+
}
|
|
28840
|
+
this.updateStatus({ connected: true, connecting: false, callId: connectionDetails.callId });
|
|
28841
|
+
}
|
|
28842
|
+
catch (error) {
|
|
28843
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
28844
|
+
this.updateStatus({ connected: false, connecting: false, error: err.message });
|
|
28845
|
+
this.emitError(err);
|
|
28846
|
+
throw err;
|
|
28847
|
+
}
|
|
28848
|
+
}
|
|
28849
|
+
/**
|
|
28850
|
+
* Connect to a voice agent for real-time conversation.
|
|
28851
|
+
*
|
|
28852
|
+
* Convenience method that combines `getConnectionDetails()` + `connectRoom()`.
|
|
28197
28853
|
*
|
|
28198
28854
|
* @param options - Connection options
|
|
28199
|
-
* @param options.agentId - ID of the agent to connect to
|
|
28200
|
-
* @param options.autoPublishMic - Auto-enable microphone (default: true)
|
|
28201
28855
|
*
|
|
28202
28856
|
* @example
|
|
28203
28857
|
* ```typescript
|
|
@@ -28210,7 +28864,7 @@ class VoiceAI {
|
|
|
28210
28864
|
}
|
|
28211
28865
|
this.updateStatus({ connecting: true, connected: false });
|
|
28212
28866
|
try {
|
|
28213
|
-
// Get connection details
|
|
28867
|
+
// Get connection details via the appropriate method
|
|
28214
28868
|
const connectionDetails = await this.getOrRefreshConnectionDetails(options);
|
|
28215
28869
|
// Create room instance
|
|
28216
28870
|
this.room = new Room();
|
|
@@ -28250,11 +28904,17 @@ class VoiceAI {
|
|
|
28250
28904
|
}
|
|
28251
28905
|
}
|
|
28252
28906
|
/**
|
|
28253
|
-
* Disconnect from the
|
|
28907
|
+
* Disconnect from the room and end the call.
|
|
28908
|
+
*
|
|
28909
|
+
* Signals the server to free the concurrency slot using endToken from
|
|
28910
|
+
* connection details. Connection details always include end_token when
|
|
28911
|
+
* fetched from the API; backends must pass it when using pre-fetched details.
|
|
28912
|
+
* If no endToken, the server detects room disconnect as fallback.
|
|
28254
28913
|
*/
|
|
28255
28914
|
async disconnect() {
|
|
28256
28915
|
this.stopAudioLevelMonitoring();
|
|
28257
28916
|
const callId = this.cachedConnectionDetails?.callId;
|
|
28917
|
+
const endToken = this.cachedConnectionDetails?.endToken;
|
|
28258
28918
|
if (this.room) {
|
|
28259
28919
|
try {
|
|
28260
28920
|
await this.room.disconnect();
|
|
@@ -28264,22 +28924,29 @@ class VoiceAI {
|
|
|
28264
28924
|
}
|
|
28265
28925
|
this.room = null;
|
|
28266
28926
|
}
|
|
28267
|
-
//
|
|
28268
|
-
if (callId) {
|
|
28927
|
+
// Signal server to free concurrency slot (endToken only - API always returns it)
|
|
28928
|
+
if (callId && endToken) {
|
|
28269
28929
|
try {
|
|
28270
|
-
await fetch(`${this.apiUrl}/calls/${encodeURIComponent(callId)}/end`, {
|
|
28930
|
+
const response = await fetch(`${this.apiUrl}/calls/${encodeURIComponent(callId)}/end`, {
|
|
28271
28931
|
method: 'POST',
|
|
28272
28932
|
headers: {
|
|
28273
28933
|
'Content-Type': 'application/json',
|
|
28274
|
-
'Authorization': `Bearer ${
|
|
28934
|
+
'Authorization': `Bearer ${endToken}`
|
|
28275
28935
|
}
|
|
28276
28936
|
});
|
|
28937
|
+
if (!response.ok) {
|
|
28938
|
+
console.warn(`[VoiceAI] Failed to end call ${callId}: ${response.status} ${response.statusText}`);
|
|
28939
|
+
}
|
|
28277
28940
|
}
|
|
28278
|
-
catch {
|
|
28279
|
-
|
|
28941
|
+
catch (err) {
|
|
28942
|
+
console.warn(`[VoiceAI] Failed to end call ${callId}:`, err);
|
|
28280
28943
|
}
|
|
28281
28944
|
}
|
|
28945
|
+
else if (callId && !endToken) {
|
|
28946
|
+
console.warn(`[VoiceAI] No endToken in connection details - pass end_token from your backend to enable immediate teardown`);
|
|
28947
|
+
}
|
|
28282
28948
|
this.cachedConnectionDetails = null;
|
|
28949
|
+
this.effectiveApiKey = '';
|
|
28283
28950
|
this.agentParticipantId = null;
|
|
28284
28951
|
this.updateAgentState('disconnected');
|
|
28285
28952
|
this.updateStatus({ connected: false, connecting: false });
|
|
@@ -28418,16 +29085,52 @@ class VoiceAI {
|
|
|
28418
29085
|
}
|
|
28419
29086
|
}
|
|
28420
29087
|
async getOrRefreshConnectionDetails(options) {
|
|
29088
|
+
// Mode 1: Pre-fetched connection details provided directly
|
|
29089
|
+
if (options.serverUrl && options.participantToken) {
|
|
29090
|
+
const details = {
|
|
29091
|
+
serverUrl: options.serverUrl,
|
|
29092
|
+
participantToken: options.participantToken,
|
|
29093
|
+
callId: options.callId || '',
|
|
29094
|
+
endToken: options.endToken,
|
|
29095
|
+
};
|
|
29096
|
+
this.cachedConnectionDetails = details;
|
|
29097
|
+
return details;
|
|
29098
|
+
}
|
|
29099
|
+
// Use cached details if still valid
|
|
28421
29100
|
if (this.cachedConnectionDetails && !this.isTokenExpired(this.cachedConnectionDetails.participantToken)) {
|
|
28422
29101
|
return this.cachedConnectionDetails;
|
|
28423
29102
|
}
|
|
28424
|
-
|
|
29103
|
+
// Mode 2: Direct API call with API key (constructor or per-call)
|
|
29104
|
+
if (!this.apiKey && !options.apiKey) {
|
|
29105
|
+
throw new Error('No authentication method configured. Use one of:\n' +
|
|
29106
|
+
'1. connectRoom() with pre-fetched details from your backend\n' +
|
|
29107
|
+
'2. API key: new VoiceAI({ apiKey: "vk_..." }) or connect({ apiKey: "vk_..." })');
|
|
29108
|
+
}
|
|
29109
|
+
const connectionDetails = await this.fetchConnectionDetails(options);
|
|
28425
29110
|
this.cachedConnectionDetails = connectionDetails;
|
|
28426
29111
|
return connectionDetails;
|
|
28427
29112
|
}
|
|
28428
|
-
|
|
29113
|
+
/**
|
|
29114
|
+
* Fetch connection details from the developer's backend endpoint.
|
|
29115
|
+
* The backend holds the API key and calls the Voice.AI API server-side.
|
|
29116
|
+
*/
|
|
29117
|
+
/**
|
|
29118
|
+
* Fetch connection details using the API key directly.
|
|
29119
|
+
* Used by the public getConnectionDetails() method.
|
|
29120
|
+
*/
|
|
29121
|
+
async fetchConnectionDetails(options) {
|
|
29122
|
+
if (!this.apiKey && !options.apiKey) {
|
|
29123
|
+
throw new Error('API key is required for getConnectionDetails(). Pass { apiKey: "vk_..." } to the constructor or options.');
|
|
29124
|
+
}
|
|
29125
|
+
return this.fetchConnectionDetailsFromApi(options);
|
|
29126
|
+
}
|
|
29127
|
+
async fetchConnectionDetailsFromApi(options) {
|
|
28429
29128
|
const url = options.apiUrl || this.apiUrl;
|
|
28430
|
-
|
|
29129
|
+
// Use test-connection-details for testMode (allows testing paused/undeployed agents)
|
|
29130
|
+
const endpointPath = options.testMode
|
|
29131
|
+
? '/connection/test-connection-details'
|
|
29132
|
+
: '/connection/connection-details';
|
|
29133
|
+
const endpoint = `${url}${endpointPath}`;
|
|
28431
29134
|
const requestData = {};
|
|
28432
29135
|
if (options.agentId)
|
|
28433
29136
|
requestData.agent_id = options.agentId;
|
|
@@ -28443,6 +29146,7 @@ class VoiceAI {
|
|
|
28443
29146
|
: JSON.stringify(options.environment);
|
|
28444
29147
|
}
|
|
28445
29148
|
const apiKey = options.apiKey || this.apiKey;
|
|
29149
|
+
this.effectiveApiKey = apiKey;
|
|
28446
29150
|
const response = await fetch(endpoint, {
|
|
28447
29151
|
method: 'POST',
|
|
28448
29152
|
headers: {
|
|
@@ -28468,7 +29172,8 @@ class VoiceAI {
|
|
|
28468
29172
|
return {
|
|
28469
29173
|
serverUrl: data.server_url,
|
|
28470
29174
|
participantToken: data.participant_token,
|
|
28471
|
-
callId: data.call_id
|
|
29175
|
+
callId: data.call_id,
|
|
29176
|
+
endToken: data.end_token,
|
|
28472
29177
|
};
|
|
28473
29178
|
}
|
|
28474
29179
|
async setupAudio(options, preConnectBuffer) {
|