@burki.dev/sdk 0.1.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/dist/index.mjs ADDED
@@ -0,0 +1,1507 @@
1
+ // src/auth.ts
2
+ var BurkiAuth = class {
3
+ apiKey;
4
+ constructor(apiKey) {
5
+ if (!apiKey) {
6
+ throw new Error("API key is required");
7
+ }
8
+ this.apiKey = apiKey;
9
+ }
10
+ /**
11
+ * Get authentication headers for API requests.
12
+ */
13
+ get headers() {
14
+ return {
15
+ "Authorization": `Bearer ${this.apiKey}`,
16
+ "Content-Type": "application/json"
17
+ };
18
+ }
19
+ /**
20
+ * Get the token for WebSocket authentication.
21
+ */
22
+ getWebSocketToken() {
23
+ return this.apiKey;
24
+ }
25
+ };
26
+
27
+ // src/errors.ts
28
+ var BurkiError = class extends Error {
29
+ statusCode;
30
+ responseBody;
31
+ constructor(message, statusCode, responseBody) {
32
+ super(message);
33
+ this.name = "BurkiError";
34
+ this.statusCode = statusCode;
35
+ this.responseBody = responseBody;
36
+ }
37
+ };
38
+ var AuthenticationError = class extends BurkiError {
39
+ constructor(message = "Authentication failed. Check your API key.", responseBody) {
40
+ super(message, 401, responseBody);
41
+ this.name = "AuthenticationError";
42
+ }
43
+ };
44
+ var NotFoundError = class extends BurkiError {
45
+ constructor(message = "Resource not found.", responseBody) {
46
+ super(message, 404, responseBody);
47
+ this.name = "NotFoundError";
48
+ }
49
+ };
50
+ var ValidationError = class extends BurkiError {
51
+ constructor(message = "Request validation failed.", statusCode = 400, responseBody) {
52
+ super(message, statusCode, responseBody);
53
+ this.name = "ValidationError";
54
+ }
55
+ };
56
+ var RateLimitError = class extends BurkiError {
57
+ retryAfter;
58
+ constructor(message = "Rate limit exceeded.", responseBody, retryAfter) {
59
+ super(message, 429, responseBody);
60
+ this.name = "RateLimitError";
61
+ this.retryAfter = retryAfter;
62
+ }
63
+ };
64
+ var ServerError = class extends BurkiError {
65
+ constructor(message = "Server error occurred.", statusCode = 500, responseBody) {
66
+ super(message, statusCode, responseBody);
67
+ this.name = "ServerError";
68
+ }
69
+ };
70
+ var WebSocketError = class extends BurkiError {
71
+ constructor(message = "WebSocket error occurred.", responseBody) {
72
+ super(message, void 0, responseBody);
73
+ this.name = "WebSocketError";
74
+ }
75
+ };
76
+
77
+ // src/http-client.ts
78
+ var DEFAULT_BASE_URL = "https://api.burki.dev";
79
+ var DEFAULT_TIMEOUT = 3e4;
80
+ var HTTPClient = class {
81
+ auth;
82
+ baseUrl;
83
+ timeout;
84
+ constructor(options) {
85
+ this.auth = options.auth;
86
+ this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
87
+ this.timeout = options.timeout || DEFAULT_TIMEOUT;
88
+ }
89
+ async handleResponse(response) {
90
+ let data;
91
+ try {
92
+ const text = await response.text();
93
+ data = text ? JSON.parse(text) : null;
94
+ } catch {
95
+ data = null;
96
+ }
97
+ if (response.status === 401) {
98
+ const message = data?.detail || "Authentication failed";
99
+ throw new AuthenticationError(message, data);
100
+ }
101
+ if (response.status === 404) {
102
+ const message = data?.detail || "Resource not found";
103
+ throw new NotFoundError(message, data);
104
+ }
105
+ if (response.status === 400 || response.status === 422) {
106
+ const message = data?.detail || "Validation error";
107
+ throw new ValidationError(message, response.status, data);
108
+ }
109
+ if (response.status === 429) {
110
+ const message = data?.detail || "Rate limit exceeded";
111
+ const retryAfter = response.headers.get("Retry-After");
112
+ throw new RateLimitError(message, data, retryAfter ? parseInt(retryAfter) : void 0);
113
+ }
114
+ if (response.status >= 500) {
115
+ const message = data?.detail || "Server error";
116
+ throw new ServerError(message, response.status, data);
117
+ }
118
+ if (!response.ok) {
119
+ const message = data?.detail || `Request failed with status ${response.status}`;
120
+ throw new BurkiError(message, response.status, data);
121
+ }
122
+ return data;
123
+ }
124
+ buildUrl(path, params) {
125
+ let url = `${this.baseUrl}${path}`;
126
+ if (params) {
127
+ const searchParams = new URLSearchParams();
128
+ for (const [key, value] of Object.entries(params)) {
129
+ if (value !== void 0 && value !== null) {
130
+ searchParams.append(key, String(value));
131
+ }
132
+ }
133
+ const queryString = searchParams.toString();
134
+ if (queryString) {
135
+ url += `?${queryString}`;
136
+ }
137
+ }
138
+ return url;
139
+ }
140
+ async request(method, path, options = {}) {
141
+ const url = this.buildUrl(path, options.params);
142
+ const headers = {
143
+ ...this.auth.headers,
144
+ ...options.headers
145
+ };
146
+ const fetchOptions = {
147
+ method,
148
+ headers,
149
+ signal: AbortSignal.timeout(this.timeout)
150
+ };
151
+ if (options.body) {
152
+ fetchOptions.body = JSON.stringify(options.body);
153
+ }
154
+ const response = await fetch(url, fetchOptions);
155
+ return this.handleResponse(response);
156
+ }
157
+ async get(path, params) {
158
+ return this.request("GET", path, { params });
159
+ }
160
+ async post(path, body, params) {
161
+ return this.request("POST", path, { body, params });
162
+ }
163
+ async put(path, body, params) {
164
+ return this.request("PUT", path, { body, params });
165
+ }
166
+ async patch(path, body, params) {
167
+ return this.request("PATCH", path, { body, params });
168
+ }
169
+ async delete(path, params) {
170
+ return this.request("DELETE", path, { params });
171
+ }
172
+ async uploadFile(path, file, filename, additionalData) {
173
+ const formData = new FormData();
174
+ formData.append("file", file, filename);
175
+ if (additionalData) {
176
+ for (const [key, value] of Object.entries(additionalData)) {
177
+ formData.append(key, value);
178
+ }
179
+ }
180
+ const url = `${this.baseUrl}${path}`;
181
+ const response = await fetch(url, {
182
+ method: "POST",
183
+ headers: {
184
+ "Authorization": this.auth.headers["Authorization"]
185
+ // Don't set Content-Type - let browser set it with boundary
186
+ },
187
+ body: formData,
188
+ signal: AbortSignal.timeout(this.timeout)
189
+ });
190
+ return this.handleResponse(response);
191
+ }
192
+ /**
193
+ * Get the base URL for constructing external URLs.
194
+ */
195
+ get baseUrlValue() {
196
+ return this.baseUrl;
197
+ }
198
+ };
199
+
200
+ // src/resources/base.ts
201
+ var BaseResource = class {
202
+ http;
203
+ constructor(httpClient) {
204
+ this.http = httpClient;
205
+ }
206
+ };
207
+
208
+ // src/resources/assistants.ts
209
+ var AssistantsResource = class extends BaseResource {
210
+ /**
211
+ * List all assistants in your organization.
212
+ */
213
+ async list(params = {}) {
214
+ const queryParams = {
215
+ skip: params.skip ?? 0,
216
+ limit: params.limit ?? 100
217
+ };
218
+ if (params.activeOnly !== void 0) {
219
+ queryParams.active_only = params.activeOnly;
220
+ }
221
+ if (params.myAssistantsOnly) {
222
+ queryParams.my_assistants_only = params.myAssistantsOnly;
223
+ }
224
+ if (params.includeStats) {
225
+ queryParams.include_stats = params.includeStats;
226
+ }
227
+ const response = await this.http.get(
228
+ "/api/v1/assistants",
229
+ queryParams
230
+ );
231
+ if (Array.isArray(response)) {
232
+ return response;
233
+ }
234
+ return response.items || [];
235
+ }
236
+ /**
237
+ * Get a specific assistant by ID.
238
+ */
239
+ async get(assistantId) {
240
+ return this.http.get(`/api/v1/assistants/${assistantId}`);
241
+ }
242
+ /**
243
+ * Get an assistant by its assigned phone number.
244
+ */
245
+ async getByPhone(phoneNumber) {
246
+ return this.http.get(`/api/v1/assistants/by-phone/${encodeURIComponent(phoneNumber)}`);
247
+ }
248
+ /**
249
+ * Create a new assistant.
250
+ */
251
+ async create(params) {
252
+ const data = {
253
+ name: params.name,
254
+ llm_provider: params.llmProvider ?? "openai"
255
+ };
256
+ if (params.description) data.description = params.description;
257
+ if (params.llmProviderConfig) data.llm_provider_config = params.llmProviderConfig;
258
+ if (params.llmSettings) data.llm_settings = params.llmSettings;
259
+ if (params.ttsSettings) data.tts_settings = params.ttsSettings;
260
+ if (params.sttSettings) data.stt_settings = params.sttSettings;
261
+ if (params.ragSettings) data.rag_settings = params.ragSettings;
262
+ if (params.toolsSettings) data.tools_settings = params.toolsSettings;
263
+ if (params.interruptionSettings) data.interruption_settings = params.interruptionSettings;
264
+ if (params.recordingSettings) data.recording_settings = params.recordingSettings;
265
+ if (params.webhookUrl) data.webhook_url = params.webhookUrl;
266
+ if (params.webhookHeaders) data.webhook_headers = params.webhookHeaders;
267
+ if (params.smsWebhookUrl) data.sms_webhook_url = params.smsWebhookUrl;
268
+ if (params.messagingServiceSid) data.messaging_service_sid = params.messagingServiceSid;
269
+ if (params.endCallMessage) data.end_call_message = params.endCallMessage;
270
+ if (params.transferCallMessage) data.transfer_call_message = params.transferCallMessage;
271
+ if (params.idleMessage) data.idle_message = params.idleMessage;
272
+ if (params.maxIdleMessages !== void 0) data.max_idle_messages = params.maxIdleMessages;
273
+ if (params.idleTimeout !== void 0) data.idle_timeout = params.idleTimeout;
274
+ if (params.maxCallLength !== void 0) data.max_call_length = params.maxCallLength;
275
+ if (params.conversationContinuityEnabled !== void 0) {
276
+ data.conversation_continuity_enabled = params.conversationContinuityEnabled;
277
+ }
278
+ if (params.llmFallbackProviders) data.llm_fallback_providers = params.llmFallbackProviders;
279
+ if (params.customSettings) data.custom_settings = params.customSettings;
280
+ if (params.isActive !== void 0) data.is_active = params.isActive;
281
+ return this.http.post("/api/v1/assistants", data);
282
+ }
283
+ /**
284
+ * Update an existing assistant (PATCH - partial update with merge).
285
+ */
286
+ async update(assistantId, params) {
287
+ const data = {};
288
+ if (params.name !== void 0) data.name = params.name;
289
+ if (params.description !== void 0) data.description = params.description;
290
+ if (params.isActive !== void 0) data.is_active = params.isActive;
291
+ if (params.llmProvider !== void 0) data.llm_provider = params.llmProvider;
292
+ if (params.llmProviderConfig !== void 0) data.llm_provider_config = params.llmProviderConfig;
293
+ if (params.llmSettings !== void 0) data.llm_settings = params.llmSettings;
294
+ if (params.ttsSettings !== void 0) data.tts_settings = params.ttsSettings;
295
+ if (params.sttSettings !== void 0) data.stt_settings = params.sttSettings;
296
+ if (params.ragSettings !== void 0) data.rag_settings = params.ragSettings;
297
+ if (params.toolsSettings !== void 0) data.tools_settings = params.toolsSettings;
298
+ if (params.interruptionSettings !== void 0) data.interruption_settings = params.interruptionSettings;
299
+ if (params.recordingSettings !== void 0) data.recording_settings = params.recordingSettings;
300
+ if (params.webhookUrl !== void 0) data.webhook_url = params.webhookUrl;
301
+ if (params.webhookHeaders !== void 0) data.webhook_headers = params.webhookHeaders;
302
+ if (params.smsWebhookUrl !== void 0) data.sms_webhook_url = params.smsWebhookUrl;
303
+ if (params.messagingServiceSid !== void 0) data.messaging_service_sid = params.messagingServiceSid;
304
+ if (params.endCallMessage !== void 0) data.end_call_message = params.endCallMessage;
305
+ if (params.transferCallMessage !== void 0) data.transfer_call_message = params.transferCallMessage;
306
+ if (params.idleMessage !== void 0) data.idle_message = params.idleMessage;
307
+ if (params.maxIdleMessages !== void 0) data.max_idle_messages = params.maxIdleMessages;
308
+ if (params.idleTimeout !== void 0) data.idle_timeout = params.idleTimeout;
309
+ if (params.maxCallLength !== void 0) data.max_call_length = params.maxCallLength;
310
+ if (params.conversationContinuityEnabled !== void 0) {
311
+ data.conversation_continuity_enabled = params.conversationContinuityEnabled;
312
+ }
313
+ if (params.llmFallbackProviders !== void 0) data.llm_fallback_providers = params.llmFallbackProviders;
314
+ if (params.customSettings !== void 0) data.custom_settings = params.customSettings;
315
+ return this.http.patch(`/api/v1/assistants/${assistantId}`, data);
316
+ }
317
+ /**
318
+ * Quick method to update just the active status of an assistant.
319
+ */
320
+ async updateStatus(assistantId, isActive) {
321
+ return this.http.patch(
322
+ `/api/v1/assistants/${assistantId}/status`,
323
+ void 0,
324
+ { is_active: isActive }
325
+ );
326
+ }
327
+ /**
328
+ * Delete an assistant.
329
+ */
330
+ async delete(assistantId) {
331
+ await this.http.delete(`/api/v1/assistants/${assistantId}`);
332
+ }
333
+ /**
334
+ * Get the total count of assistants.
335
+ */
336
+ async getCount(activeOnly = false) {
337
+ const params = {};
338
+ if (activeOnly) {
339
+ params.active_only = activeOnly;
340
+ }
341
+ const response = await this.http.get("/api/v1/assistants/count", params);
342
+ return response?.count || 0;
343
+ }
344
+ /**
345
+ * Export assistants data in CSV or JSON format.
346
+ */
347
+ async export(params = {}) {
348
+ const queryParams = {
349
+ format: params.format ?? "csv"
350
+ };
351
+ if (params.assistantIds && params.assistantIds.length > 0) {
352
+ queryParams.assistant_ids = params.assistantIds.join(",");
353
+ }
354
+ if (params.search) {
355
+ queryParams.search = params.search;
356
+ }
357
+ if (params.status) {
358
+ queryParams.status = params.status;
359
+ }
360
+ const response = await this.http.get("/api/v1/assistants/export", queryParams);
361
+ return response;
362
+ }
363
+ /**
364
+ * List cloned voices for your organization.
365
+ */
366
+ async getClonedVoices(params = {}) {
367
+ const queryParams = {};
368
+ if (params.status) {
369
+ queryParams.status = params.status;
370
+ }
371
+ if (params.provider) {
372
+ queryParams.provider = params.provider;
373
+ }
374
+ const response = await this.http.get(
375
+ "/api/v1/assistants/cloned-voices",
376
+ queryParams
377
+ );
378
+ if (Array.isArray(response)) {
379
+ return response;
380
+ }
381
+ return response.cloned_voices || [];
382
+ }
383
+ /**
384
+ * Get list of supported LLM providers.
385
+ */
386
+ async getProviders() {
387
+ const response = await this.http.get(
388
+ "/api/v1/assistants/providers"
389
+ );
390
+ return response?.providers || {};
391
+ }
392
+ /**
393
+ * Get information about your organization.
394
+ */
395
+ async getOrganizationInfo() {
396
+ return this.http.get("/api/v1/assistants/me/organization");
397
+ }
398
+ };
399
+
400
+ // src/resources/calls.ts
401
+ var CallsResource = class extends BaseResource {
402
+ /**
403
+ * Initiate an outbound call from an assistant.
404
+ */
405
+ async initiate(params) {
406
+ const data = {
407
+ from_phone_number: params.fromPhoneNumber,
408
+ to_phone_number: params.toPhoneNumber
409
+ };
410
+ if (params.welcomeMessage) data.welcome_message = params.welcomeMessage;
411
+ if (params.agenda) data.agenda = params.agenda;
412
+ if (params.assistantId) data.assistant_id = params.assistantId;
413
+ if (params.variables) data.variables = params.variables;
414
+ return this.http.post("/calls/initiate", data);
415
+ }
416
+ /**
417
+ * List calls with filtering options.
418
+ */
419
+ async list(params = {}) {
420
+ const queryParams = {
421
+ skip: params.skip ?? 0,
422
+ limit: params.limit ?? 100
423
+ };
424
+ if (params.status) queryParams.status = params.status;
425
+ if (params.assistantId) queryParams.assistant_id = params.assistantId;
426
+ if (params.customerPhone) queryParams.customer_phone = params.customerPhone;
427
+ if (params.dateFrom) queryParams.date_from = params.dateFrom;
428
+ if (params.dateTo) queryParams.date_to = params.dateTo;
429
+ if (params.minDuration !== void 0) queryParams.min_duration = params.minDuration;
430
+ if (params.maxDuration !== void 0) queryParams.max_duration = params.maxDuration;
431
+ const response = await this.http.get(
432
+ "/api/v1/calls",
433
+ queryParams
434
+ );
435
+ if (Array.isArray(response)) {
436
+ return response;
437
+ }
438
+ return response.items || [];
439
+ }
440
+ /**
441
+ * Get a specific call by ID.
442
+ */
443
+ async get(callId) {
444
+ return this.http.get(`/api/v1/calls/${callId}`);
445
+ }
446
+ /**
447
+ * Get a specific call by SID.
448
+ */
449
+ async getBySid(callSid) {
450
+ return this.http.get(`/api/v1/calls/sid/${callSid}`);
451
+ }
452
+ /**
453
+ * Update the metadata for a specific call.
454
+ */
455
+ async updateMetadata(callId, metadata) {
456
+ return this.http.patch(`/api/v1/calls/${callId}/metadata`, { metadata });
457
+ }
458
+ /**
459
+ * Get transcripts for a call.
460
+ */
461
+ async getTranscripts(callId, params = {}) {
462
+ const queryParams = {
463
+ include_interim: params.includeInterim ?? false
464
+ };
465
+ if (params.speaker) queryParams.speaker = params.speaker;
466
+ return this.http.get(
467
+ `/api/v1/calls/${callId}/transcripts`,
468
+ queryParams
469
+ );
470
+ }
471
+ /**
472
+ * Get transcripts for a call by SID.
473
+ */
474
+ async getTranscriptsBySid(callSid, params = {}) {
475
+ const queryParams = {
476
+ include_interim: params.includeInterim ?? false
477
+ };
478
+ if (params.speaker) queryParams.speaker = params.speaker;
479
+ return this.http.get(
480
+ `/api/v1/calls/sid/${callSid}/transcripts`,
481
+ queryParams
482
+ );
483
+ }
484
+ /**
485
+ * Export call transcripts in various formats.
486
+ */
487
+ async exportTranscripts(callId, params = {}) {
488
+ const queryParams = {
489
+ format: params.format ?? "txt"
490
+ };
491
+ if (params.speaker) queryParams.speaker = params.speaker;
492
+ return this.http.get(
493
+ `/api/v1/calls/${callId}/transcripts/export`,
494
+ queryParams
495
+ );
496
+ }
497
+ /**
498
+ * Get recordings for a call.
499
+ */
500
+ async getRecordings(callId, params = {}) {
501
+ const queryParams = {};
502
+ if (params.recordingType) queryParams.recording_type = params.recordingType;
503
+ return this.http.get(
504
+ `/api/v1/calls/${callId}/recordings`,
505
+ queryParams
506
+ );
507
+ }
508
+ /**
509
+ * Get recordings for a call by SID.
510
+ */
511
+ async getRecordingsBySid(callSid, params = {}) {
512
+ const queryParams = {};
513
+ if (params.recordingType) queryParams.recording_type = params.recordingType;
514
+ return this.http.get(
515
+ `/api/v1/calls/sid/${callSid}/recordings`,
516
+ queryParams
517
+ );
518
+ }
519
+ /**
520
+ * Get the streaming URL for a recording.
521
+ */
522
+ getRecordingUrl(callId, recordingId) {
523
+ return `${this.http.baseUrlValue}/api/v1/calls/${callId}/recording/${recordingId}/play`;
524
+ }
525
+ /**
526
+ * Get calculated metrics for a call.
527
+ */
528
+ async getMetrics(callId) {
529
+ return this.http.get(`/api/v1/calls/${callId}/metrics`);
530
+ }
531
+ /**
532
+ * Get chat messages (LLM conversation) for a call.
533
+ */
534
+ async getMessages(callId, params = {}) {
535
+ const queryParams = {};
536
+ if (params.role) queryParams.role = params.role;
537
+ return this.http.get(
538
+ `/api/v1/calls/${callId}/messages`,
539
+ queryParams
540
+ );
541
+ }
542
+ /**
543
+ * Get webhook logs for a call.
544
+ */
545
+ async getWebhookLogs(callId, params = {}) {
546
+ const queryParams = {};
547
+ if (params.webhookType) queryParams.webhook_type = params.webhookType;
548
+ return this.http.get(
549
+ `/api/v1/calls/${callId}/webhook-logs`,
550
+ queryParams
551
+ );
552
+ }
553
+ /**
554
+ * Terminate an ongoing call.
555
+ */
556
+ async terminate(callSid) {
557
+ return this.http.post(`/api/v1/calls/${callSid}/terminate`);
558
+ }
559
+ /**
560
+ * Get call analytics for your organization.
561
+ */
562
+ async getAnalytics(period = "7d") {
563
+ return this.http.get("/api/v1/calls/analytics", { period });
564
+ }
565
+ /**
566
+ * Get basic call statistics.
567
+ */
568
+ async getStats() {
569
+ return this.http.get("/api/v1/calls/stats");
570
+ }
571
+ /**
572
+ * Get the count of calls with optional filters.
573
+ */
574
+ async getCount(params = {}) {
575
+ const queryParams = {};
576
+ if (params.status) queryParams.status = params.status;
577
+ if (params.assistantId) queryParams.assistant_id = params.assistantId;
578
+ if (params.dateFrom) queryParams.date_from = params.dateFrom;
579
+ if (params.dateTo) queryParams.date_to = params.dateTo;
580
+ const response = await this.http.get(
581
+ "/api/v1/calls/count",
582
+ queryParams
583
+ );
584
+ return response?.count || 0;
585
+ }
586
+ /**
587
+ * Search calls by various criteria.
588
+ */
589
+ async search(query, limit = 50) {
590
+ return this.http.get("/api/v1/calls/search", { q: query, limit });
591
+ }
592
+ /**
593
+ * Export calls data.
594
+ */
595
+ async export(params = {}) {
596
+ const queryParams = {
597
+ format: params.format ?? "csv"
598
+ };
599
+ if (params.status) queryParams.status = params.status;
600
+ if (params.assistantId) queryParams.assistant_id = params.assistantId;
601
+ if (params.dateFrom) queryParams.date_from = params.dateFrom;
602
+ if (params.dateTo) queryParams.date_to = params.dateTo;
603
+ return this.http.get("/api/v1/calls/export", queryParams);
604
+ }
605
+ };
606
+
607
+ // src/resources/phone-numbers.ts
608
+ var PhoneNumbersResource = class extends BaseResource {
609
+ /**
610
+ * List all phone numbers in your organization.
611
+ */
612
+ async list() {
613
+ const response = await this.http.get(
614
+ "/api/v1/phone-numbers"
615
+ );
616
+ if (Array.isArray(response)) {
617
+ return response;
618
+ }
619
+ return response.items || [];
620
+ }
621
+ /**
622
+ * Search for available phone numbers to purchase.
623
+ */
624
+ async search(params) {
625
+ const data = {
626
+ provider: params.provider,
627
+ country_code: params.countryCode ?? "US",
628
+ limit: params.limit ?? 20
629
+ };
630
+ if (params.areaCode) data.area_code = params.areaCode;
631
+ if (params.contains) data.contains = params.contains;
632
+ if (params.locality) data.locality = params.locality;
633
+ if (params.region) data.region = params.region;
634
+ return this.http.post("/api/v1/phone-numbers/search", data);
635
+ }
636
+ /**
637
+ * Purchase a phone number.
638
+ */
639
+ async purchase(params) {
640
+ const data = {
641
+ phone_number: params.phoneNumber,
642
+ provider: params.provider
643
+ };
644
+ if (params.friendlyName) data.friendly_name = params.friendlyName;
645
+ if (params.assistantId) data.assistant_id = params.assistantId;
646
+ if (params.countryCode) data.country_code = params.countryCode;
647
+ return this.http.post("/api/v1/phone-numbers/purchase", data);
648
+ }
649
+ /**
650
+ * Release a phone number.
651
+ */
652
+ async release(phoneNumber, provider) {
653
+ const data = {
654
+ phone_number: phoneNumber
655
+ };
656
+ if (provider) data.provider = provider;
657
+ return this.http.post("/api/v1/phone-numbers/release", data);
658
+ }
659
+ /**
660
+ * Assign a phone number to an assistant.
661
+ */
662
+ async assign(phoneNumberId, params) {
663
+ return this.http.post(
664
+ `/api/v1/assistants/phonenumbers/${phoneNumberId}/assign`,
665
+ params
666
+ );
667
+ }
668
+ /**
669
+ * Unassign a phone number from its assistant.
670
+ */
671
+ async unassign(phoneNumberId) {
672
+ return this.http.post(
673
+ `/api/v1/assistants/phonenumbers/${phoneNumberId}/unassign`
674
+ );
675
+ }
676
+ /**
677
+ * Get available country codes for phone number search.
678
+ */
679
+ async getCountries(provider = "telnyx") {
680
+ return this.http.get(
681
+ "/api/v1/phone-numbers/countries",
682
+ { provider }
683
+ );
684
+ }
685
+ /**
686
+ * Diagnose the connection status of a phone number (Telnyx).
687
+ */
688
+ async diagnose(phoneNumber) {
689
+ return this.http.get(
690
+ `/api/v1/phone-numbers/${encodeURIComponent(phoneNumber)}/diagnose`
691
+ );
692
+ }
693
+ /**
694
+ * Get current webhook configuration for a phone number.
695
+ */
696
+ async getWebhooks(phoneNumber, provider) {
697
+ const queryParams = {};
698
+ if (provider) queryParams.provider = provider;
699
+ return this.http.get(
700
+ `/api/v1/phone-numbers/${encodeURIComponent(phoneNumber)}/webhooks`,
701
+ queryParams
702
+ );
703
+ }
704
+ /**
705
+ * Update voice webhook URL and/or SMS settings for a phone number.
706
+ */
707
+ async updateWebhooks(params) {
708
+ const data = {
709
+ phone_number: params.phoneNumber
710
+ };
711
+ if (params.voiceWebhookUrl) data.voice_webhook_url = params.voiceWebhookUrl;
712
+ if (params.disableSms) data.disable_sms = params.disableSms;
713
+ if (params.enableSms) data.enable_sms = params.enableSms;
714
+ if (params.provider) data.provider = params.provider;
715
+ return this.http.put("/api/v1/phone-numbers/webhooks", data);
716
+ }
717
+ /**
718
+ * Sync verified caller IDs from Twilio for your organization.
719
+ */
720
+ async syncVerifiedCallerIds() {
721
+ return this.http.post(
722
+ "/api/v1/phone-numbers/organization/sync-verified-caller-ids"
723
+ );
724
+ }
725
+ /**
726
+ * Add a new verified caller ID (for outbound calls with unowned numbers).
727
+ */
728
+ async addVerifiedCallerId(params) {
729
+ const data = {
730
+ phone_number: params.phoneNumber
731
+ };
732
+ if (params.friendlyName) data.friendly_name = params.friendlyName;
733
+ return this.http.post(
734
+ "/api/v1/phone-numbers/organization/add-verified-caller-id",
735
+ data
736
+ );
737
+ }
738
+ /**
739
+ * Sync phone numbers from telephony providers.
740
+ */
741
+ async sync() {
742
+ return this.http.post("/api/v1/organization/phone-numbers/sync");
743
+ }
744
+ };
745
+
746
+ // src/resources/documents.ts
747
+ var DocumentsResource = class extends BaseResource {
748
+ /**
749
+ * List all documents for an assistant.
750
+ */
751
+ async list(assistantId) {
752
+ const response = await this.http.get(
753
+ `/api/v1/assistants/${assistantId}/documents`
754
+ );
755
+ if (Array.isArray(response)) {
756
+ return response;
757
+ }
758
+ return response.items || [];
759
+ }
760
+ /**
761
+ * Upload a document to an assistant's knowledge base.
762
+ *
763
+ * Note: For browser usage, pass a File object. For Node.js, use uploadFromUrl instead.
764
+ */
765
+ async upload(assistantId, file, filename, autoProcess = true) {
766
+ return this.http.uploadFile(
767
+ `/api/v1/assistants/${assistantId}/documents`,
768
+ file,
769
+ filename,
770
+ { auto_process: String(autoProcess) }
771
+ );
772
+ }
773
+ /**
774
+ * Upload a document from a URL.
775
+ */
776
+ async uploadFromUrl(params) {
777
+ return this.http.post(
778
+ `/api/v1/assistants/${params.assistantId}/documents/url`,
779
+ {
780
+ url: params.url,
781
+ filename: params.filename,
782
+ auto_process: params.autoProcess ?? true
783
+ }
784
+ );
785
+ }
786
+ /**
787
+ * Get the processing status of a document.
788
+ */
789
+ async getStatus(documentId) {
790
+ return this.http.get(
791
+ `/api/v1/assistants/documents/${documentId}/status`
792
+ );
793
+ }
794
+ /**
795
+ * Delete a document.
796
+ */
797
+ async delete(documentId) {
798
+ await this.http.delete(`/api/v1/assistants/documents/${documentId}`);
799
+ }
800
+ /**
801
+ * Reprocess a document.
802
+ */
803
+ async reprocess(documentId) {
804
+ return this.http.post(
805
+ `/api/v1/assistants/documents/${documentId}/reprocess`
806
+ );
807
+ }
808
+ };
809
+
810
+ // src/resources/tools.ts
811
+ var ToolsResource = class extends BaseResource {
812
+ /**
813
+ * List all tools in your organization.
814
+ */
815
+ async list() {
816
+ const response = await this.http.get("/api/v1/tools");
817
+ if (Array.isArray(response)) {
818
+ return response;
819
+ }
820
+ return response.items || [];
821
+ }
822
+ /**
823
+ * Get a specific tool by ID.
824
+ */
825
+ async get(toolId) {
826
+ return this.http.get(`/api/v1/tools/${toolId}`);
827
+ }
828
+ /**
829
+ * Create a new tool.
830
+ */
831
+ async create(params) {
832
+ return this.http.post("/api/v1/tools", params);
833
+ }
834
+ /**
835
+ * Update an existing tool.
836
+ */
837
+ async update(toolId, params) {
838
+ return this.http.patch(`/api/v1/tools/${toolId}`, params);
839
+ }
840
+ /**
841
+ * Delete a tool.
842
+ */
843
+ async delete(toolId) {
844
+ await this.http.delete(`/api/v1/tools/${toolId}`);
845
+ }
846
+ /**
847
+ * Assign a tool to an assistant.
848
+ */
849
+ async assign(toolId, assistantId) {
850
+ return this.http.post(`/api/v1/tools/${toolId}/assign`, {
851
+ assistant_id: assistantId
852
+ });
853
+ }
854
+ /**
855
+ * Unassign a tool from an assistant.
856
+ */
857
+ async unassign(toolId, assistantId) {
858
+ return this.http.post(`/api/v1/tools/${toolId}/unassign`, {
859
+ assistant_id: assistantId
860
+ });
861
+ }
862
+ /**
863
+ * Discover AWS Lambda functions for creating Lambda tools.
864
+ */
865
+ async discoverLambda(region = "us-east-1") {
866
+ const response = await this.http.get("/api/v1/tools/discover-lambda", { region });
867
+ if (Array.isArray(response)) {
868
+ return response;
869
+ }
870
+ return response.functions || [];
871
+ }
872
+ };
873
+
874
+ // src/resources/sms.ts
875
+ var SMSResource = class extends BaseResource {
876
+ /**
877
+ * Send an SMS message through an assistant.
878
+ *
879
+ * The system will automatically:
880
+ * 1. Find the assistant associated with the from_phone_number
881
+ * 2. Use the assistant's configured telephony provider
882
+ * 3. Queue the SMS for delivery with per-provider rate limiting (default)
883
+ * 4. Persist the outbound message to the SMS conversation
884
+ */
885
+ async send(params) {
886
+ const data = {
887
+ from_phone_number: params.fromPhoneNumber,
888
+ to_phone_number: params.toPhoneNumber,
889
+ message: params.message,
890
+ queue: params.queue ?? true
891
+ };
892
+ if (params.mediaUrls && params.mediaUrls.length > 0) {
893
+ data.media_urls = params.mediaUrls;
894
+ }
895
+ if (params.idempotencyKey) {
896
+ data.idempotency_key = params.idempotencyKey;
897
+ }
898
+ return this.http.post("/sms/send", data);
899
+ }
900
+ /**
901
+ * Get the status of a sent SMS message.
902
+ */
903
+ async getStatus(messageId) {
904
+ return this.http.get(`/sms/status/${messageId}`);
905
+ }
906
+ /**
907
+ * Cancel a queued SMS message (before it's sent).
908
+ */
909
+ async cancel(messageId) {
910
+ return this.http.post(`/sms/cancel/${messageId}`);
911
+ }
912
+ /**
913
+ * Get SMS queue statistics.
914
+ */
915
+ async getQueueStats() {
916
+ return this.http.get("/sms/queue/stats");
917
+ }
918
+ // SMS Conversations API
919
+ /**
920
+ * List SMS conversations.
921
+ */
922
+ async listConversations(params = {}) {
923
+ const queryParams = {
924
+ skip: params.skip ?? 0,
925
+ limit: params.limit ?? 50
926
+ };
927
+ if (params.status) queryParams.status = params.status;
928
+ if (params.assistantId) queryParams.assistant_id = params.assistantId;
929
+ if (params.customerPhone) queryParams.customer_phone = params.customerPhone;
930
+ if (params.dateFrom) queryParams.date_from = params.dateFrom;
931
+ if (params.dateTo) queryParams.date_to = params.dateTo;
932
+ return this.http.get("/api/v1/sms-conversations/", queryParams);
933
+ }
934
+ /**
935
+ * Get a specific SMS conversation by ID.
936
+ */
937
+ async getConversation(conversationId) {
938
+ return this.http.get(
939
+ `/api/v1/sms-conversations/${conversationId}`
940
+ );
941
+ }
942
+ /**
943
+ * Get all messages in an SMS conversation.
944
+ */
945
+ async getMessages(conversationId) {
946
+ return this.http.get(
947
+ `/api/v1/sms-conversations/${conversationId}/messages`
948
+ );
949
+ }
950
+ /**
951
+ * Get related calls and SMS conversations that share the same unified session.
952
+ */
953
+ async getRelatedConversations(conversationId) {
954
+ return this.http.get(
955
+ `/api/v1/sms-conversations/${conversationId}/related`
956
+ );
957
+ }
958
+ /**
959
+ * Archive an SMS conversation and purge associated data.
960
+ */
961
+ async deleteConversation(conversationId) {
962
+ return this.http.delete(
963
+ `/api/v1/sms-conversations/${conversationId}`
964
+ );
965
+ }
966
+ /**
967
+ * Export an SMS conversation in various formats.
968
+ */
969
+ async exportConversation(conversationId, params = {}) {
970
+ return this.http.get(
971
+ `/api/v1/sms-conversations/${conversationId}/export`,
972
+ { format: params.format ?? "txt" }
973
+ );
974
+ }
975
+ // Backward compatibility aliases
976
+ /**
977
+ * @deprecated Use listConversations() instead
978
+ */
979
+ async getConversations(params = {}) {
980
+ return this.listConversations(params);
981
+ }
982
+ };
983
+
984
+ // src/resources/campaigns.ts
985
+ var CampaignsResource = class extends BaseResource {
986
+ /**
987
+ * List campaigns.
988
+ */
989
+ async list(params = {}) {
990
+ const response = await this.http.get(
991
+ "/api/v1/campaigns",
992
+ params
993
+ );
994
+ if (Array.isArray(response)) {
995
+ return response;
996
+ }
997
+ return response.items || [];
998
+ }
999
+ /**
1000
+ * Get a specific campaign by ID.
1001
+ */
1002
+ async get(campaignId) {
1003
+ return this.http.get(`/api/v1/campaigns/${campaignId}`);
1004
+ }
1005
+ /**
1006
+ * Create a new campaign.
1007
+ */
1008
+ async create(params) {
1009
+ return this.http.post("/api/v1/campaigns", {
1010
+ name: params.name,
1011
+ description: params.description,
1012
+ assistant_id: params.assistantId,
1013
+ campaign_type: params.campaignType || "call",
1014
+ contacts: params.contacts,
1015
+ phone_number_id: params.phoneNumberId,
1016
+ schedule: params.schedule,
1017
+ settings: params.settings
1018
+ });
1019
+ }
1020
+ /**
1021
+ * Update a campaign.
1022
+ */
1023
+ async update(campaignId, params) {
1024
+ return this.http.patch(`/api/v1/campaigns/${campaignId}`, params);
1025
+ }
1026
+ /**
1027
+ * Delete a campaign.
1028
+ */
1029
+ async delete(campaignId) {
1030
+ await this.http.delete(`/api/v1/campaigns/${campaignId}`);
1031
+ }
1032
+ /**
1033
+ * Start a campaign.
1034
+ */
1035
+ async start(campaignId) {
1036
+ return this.http.post(`/api/v1/campaigns/${campaignId}/start`);
1037
+ }
1038
+ /**
1039
+ * Pause a running campaign.
1040
+ */
1041
+ async pause(campaignId) {
1042
+ return this.http.post(`/api/v1/campaigns/${campaignId}/pause`);
1043
+ }
1044
+ /**
1045
+ * Resume a paused campaign.
1046
+ */
1047
+ async resume(campaignId) {
1048
+ return this.http.post(`/api/v1/campaigns/${campaignId}/resume`);
1049
+ }
1050
+ /**
1051
+ * Cancel a campaign.
1052
+ */
1053
+ async cancel(campaignId) {
1054
+ return this.http.post(`/api/v1/campaigns/${campaignId}/cancel`);
1055
+ }
1056
+ /**
1057
+ * Get the progress of a campaign.
1058
+ */
1059
+ async getProgress(campaignId) {
1060
+ return this.http.get(`/api/v1/campaigns/${campaignId}/progress`);
1061
+ }
1062
+ /**
1063
+ * Get contacts in a campaign.
1064
+ */
1065
+ async getContacts(campaignId, params = {}) {
1066
+ const response = await this.http.get(`/api/v1/campaigns/${campaignId}/contacts`, params);
1067
+ if (Array.isArray(response)) {
1068
+ return response;
1069
+ }
1070
+ return response.items || [];
1071
+ }
1072
+ /**
1073
+ * Add contacts to a campaign.
1074
+ */
1075
+ async addContacts(campaignId, contacts) {
1076
+ return this.http.post(
1077
+ `/api/v1/campaigns/${campaignId}/contacts`,
1078
+ { contacts }
1079
+ );
1080
+ }
1081
+ };
1082
+
1083
+ // src/realtime/live-transcript.ts
1084
+ var LiveTranscriptStream = class {
1085
+ wsUrl;
1086
+ token;
1087
+ websocket = null;
1088
+ running = false;
1089
+ constructor(wsUrl, token) {
1090
+ this.wsUrl = wsUrl;
1091
+ this.token = token;
1092
+ }
1093
+ /**
1094
+ * Connect to the WebSocket.
1095
+ */
1096
+ async connect() {
1097
+ return new Promise((resolve, reject) => {
1098
+ try {
1099
+ const url = `${this.wsUrl}?token=${this.token}`;
1100
+ this.websocket = new WebSocket(url);
1101
+ this.running = true;
1102
+ this.websocket.onopen = () => {
1103
+ resolve();
1104
+ };
1105
+ this.websocket.onerror = (error) => {
1106
+ reject(new WebSocketError(`Failed to connect to transcript stream: ${error}`));
1107
+ };
1108
+ } catch (error) {
1109
+ reject(new WebSocketError(`Failed to connect to transcript stream: ${error}`));
1110
+ }
1111
+ });
1112
+ }
1113
+ /**
1114
+ * Disconnect from the WebSocket.
1115
+ */
1116
+ disconnect() {
1117
+ this.running = false;
1118
+ if (this.websocket) {
1119
+ this.websocket.close();
1120
+ this.websocket = null;
1121
+ }
1122
+ }
1123
+ /**
1124
+ * Iterate over incoming events using async iteration.
1125
+ */
1126
+ async *[Symbol.asyncIterator]() {
1127
+ if (!this.websocket) {
1128
+ throw new WebSocketError("Not connected. Call connect() first.");
1129
+ }
1130
+ const messageQueue = [];
1131
+ let resolveMessage = null;
1132
+ let closed = false;
1133
+ this.websocket.onmessage = (event) => {
1134
+ try {
1135
+ const data = JSON.parse(event.data);
1136
+ const parsedEvent = this.parseEvent(data);
1137
+ if (parsedEvent) {
1138
+ if (resolveMessage) {
1139
+ resolveMessage(parsedEvent);
1140
+ resolveMessage = null;
1141
+ } else {
1142
+ messageQueue.push(parsedEvent);
1143
+ }
1144
+ }
1145
+ } catch {
1146
+ }
1147
+ };
1148
+ this.websocket.onclose = () => {
1149
+ closed = true;
1150
+ if (resolveMessage) {
1151
+ resolveMessage(null);
1152
+ }
1153
+ };
1154
+ this.websocket.onerror = () => {
1155
+ closed = true;
1156
+ if (resolveMessage) {
1157
+ resolveMessage(null);
1158
+ }
1159
+ };
1160
+ while (this.running && !closed) {
1161
+ if (messageQueue.length > 0) {
1162
+ const event = messageQueue.shift();
1163
+ yield event;
1164
+ } else {
1165
+ const event = await new Promise((resolve) => {
1166
+ resolveMessage = resolve;
1167
+ });
1168
+ if (event === null) {
1169
+ break;
1170
+ }
1171
+ yield event;
1172
+ }
1173
+ }
1174
+ }
1175
+ parseEvent(data) {
1176
+ const eventType = data.type;
1177
+ if (eventType === "transcript") {
1178
+ const transcriptData = data.data || {};
1179
+ return {
1180
+ type: "transcript",
1181
+ callSid: data.call_sid || "",
1182
+ timestamp: data.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
1183
+ content: transcriptData.content || "",
1184
+ speaker: transcriptData.speaker || "user",
1185
+ isFinal: transcriptData.is_final ?? true,
1186
+ confidence: transcriptData.confidence,
1187
+ segmentStart: transcriptData.segment_start,
1188
+ segmentEnd: transcriptData.segment_end
1189
+ };
1190
+ } else if (eventType === "call_status") {
1191
+ return {
1192
+ type: "call_status",
1193
+ callSid: data.call_sid || "",
1194
+ timestamp: data.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
1195
+ status: data.status || "",
1196
+ metadata: data.metadata || {}
1197
+ };
1198
+ }
1199
+ return null;
1200
+ }
1201
+ /**
1202
+ * Check if the WebSocket is connected.
1203
+ */
1204
+ get connected() {
1205
+ return this.websocket !== null && this.running;
1206
+ }
1207
+ };
1208
+
1209
+ // src/realtime/campaign-progress.ts
1210
+ var CampaignProgressStream = class {
1211
+ wsUrl;
1212
+ token;
1213
+ websocket = null;
1214
+ running = false;
1215
+ constructor(wsUrl, token) {
1216
+ this.wsUrl = wsUrl;
1217
+ this.token = token;
1218
+ }
1219
+ /**
1220
+ * Connect to the WebSocket.
1221
+ */
1222
+ async connect() {
1223
+ return new Promise((resolve, reject) => {
1224
+ try {
1225
+ const url = `${this.wsUrl}?token=${this.token}`;
1226
+ this.websocket = new WebSocket(url);
1227
+ this.running = true;
1228
+ this.websocket.onopen = () => {
1229
+ resolve();
1230
+ };
1231
+ this.websocket.onerror = (error) => {
1232
+ reject(new WebSocketError(`Failed to connect to campaign progress stream: ${error}`));
1233
+ };
1234
+ } catch (error) {
1235
+ reject(new WebSocketError(`Failed to connect to campaign progress stream: ${error}`));
1236
+ }
1237
+ });
1238
+ }
1239
+ /**
1240
+ * Disconnect from the WebSocket.
1241
+ */
1242
+ disconnect() {
1243
+ this.running = false;
1244
+ if (this.websocket) {
1245
+ this.websocket.close();
1246
+ this.websocket = null;
1247
+ }
1248
+ }
1249
+ /**
1250
+ * Iterate over incoming events using async iteration.
1251
+ */
1252
+ async *[Symbol.asyncIterator]() {
1253
+ if (!this.websocket) {
1254
+ throw new WebSocketError("Not connected. Call connect() first.");
1255
+ }
1256
+ const messageQueue = [];
1257
+ let resolveMessage = null;
1258
+ let closed = false;
1259
+ this.websocket.onmessage = (event) => {
1260
+ try {
1261
+ const data = JSON.parse(event.data);
1262
+ const parsedEvent = this.parseEvent(data);
1263
+ if (parsedEvent) {
1264
+ if (resolveMessage) {
1265
+ resolveMessage(parsedEvent);
1266
+ resolveMessage = null;
1267
+ } else {
1268
+ messageQueue.push(parsedEvent);
1269
+ }
1270
+ }
1271
+ } catch {
1272
+ }
1273
+ };
1274
+ this.websocket.onclose = () => {
1275
+ closed = true;
1276
+ if (resolveMessage) {
1277
+ resolveMessage(null);
1278
+ }
1279
+ };
1280
+ this.websocket.onerror = () => {
1281
+ closed = true;
1282
+ if (resolveMessage) {
1283
+ resolveMessage(null);
1284
+ }
1285
+ };
1286
+ while (this.running && !closed) {
1287
+ if (messageQueue.length > 0) {
1288
+ const event = messageQueue.shift();
1289
+ yield event;
1290
+ } else {
1291
+ const event = await new Promise((resolve) => {
1292
+ resolveMessage = resolve;
1293
+ });
1294
+ if (event === null) {
1295
+ break;
1296
+ }
1297
+ yield event;
1298
+ }
1299
+ }
1300
+ }
1301
+ parseEvent(data) {
1302
+ const eventType = data.type;
1303
+ const timestamp = data.timestamp || (/* @__PURE__ */ new Date()).toISOString();
1304
+ const campaignId = data.campaign_id || 0;
1305
+ if (eventType === "progress") {
1306
+ return {
1307
+ type: "progress",
1308
+ campaignId,
1309
+ timestamp,
1310
+ totalContacts: data.total_contacts || 0,
1311
+ completedContacts: data.completed_contacts || 0,
1312
+ failedContacts: data.failed_contacts || 0,
1313
+ pendingContacts: data.pending_contacts || 0,
1314
+ inProgressContacts: data.in_progress_contacts || 0,
1315
+ completionPercentage: data.completion_percentage || 0,
1316
+ contactId: data.contact_id,
1317
+ contactPhone: data.contact_phone,
1318
+ contactStatus: data.contact_status,
1319
+ contactError: data.contact_error
1320
+ };
1321
+ } else if (eventType === "contact_update") {
1322
+ return {
1323
+ type: "contact_update",
1324
+ campaignId,
1325
+ timestamp,
1326
+ contactId: data.contact_id || 0,
1327
+ phoneNumber: data.phone_number || "",
1328
+ status: data.status || "",
1329
+ callSid: data.call_sid,
1330
+ callDuration: data.call_duration,
1331
+ errorMessage: data.error_message
1332
+ };
1333
+ } else if (eventType === "campaign_completed") {
1334
+ return {
1335
+ type: "campaign_completed",
1336
+ campaignId,
1337
+ timestamp,
1338
+ totalContacts: data.total_contacts || 0,
1339
+ completedContacts: data.completed_contacts || 0,
1340
+ failedContacts: data.failed_contacts || 0,
1341
+ successRate: data.success_rate || 0,
1342
+ totalDuration: data.total_duration || 0,
1343
+ totalCost: data.total_cost || 0
1344
+ };
1345
+ }
1346
+ return null;
1347
+ }
1348
+ /**
1349
+ * Send a ping message to keep the connection alive.
1350
+ */
1351
+ sendPing() {
1352
+ if (this.websocket) {
1353
+ this.websocket.send(JSON.stringify({ type: "ping" }));
1354
+ }
1355
+ }
1356
+ /**
1357
+ * Check if the WebSocket is connected.
1358
+ */
1359
+ get connected() {
1360
+ return this.websocket !== null && this.running;
1361
+ }
1362
+ };
1363
+
1364
+ // src/realtime/client.ts
1365
+ var RealtimeClient = class {
1366
+ auth;
1367
+ wsBaseUrl;
1368
+ constructor(auth, baseUrl) {
1369
+ this.auth = auth;
1370
+ this.wsBaseUrl = baseUrl.replace("https://", "wss://").replace("http://", "ws://").replace(/\/$/, "");
1371
+ }
1372
+ /**
1373
+ * Create a live transcript stream for a call.
1374
+ */
1375
+ liveTranscript(callSid) {
1376
+ return new LiveTranscriptStream(
1377
+ `${this.wsBaseUrl}/live-transcript/${callSid}`,
1378
+ this.auth.getWebSocketToken()
1379
+ );
1380
+ }
1381
+ /**
1382
+ * Create a campaign progress stream.
1383
+ */
1384
+ campaignProgress(campaignId) {
1385
+ return new CampaignProgressStream(
1386
+ `${this.wsBaseUrl}/ws/campaigns/${campaignId}/progress`,
1387
+ this.auth.getWebSocketToken()
1388
+ );
1389
+ }
1390
+ };
1391
+
1392
+ // src/client.ts
1393
+ var BurkiClient = class {
1394
+ auth;
1395
+ httpClient;
1396
+ baseUrl;
1397
+ _assistants;
1398
+ _calls;
1399
+ _phoneNumbers;
1400
+ _documents;
1401
+ _tools;
1402
+ _sms;
1403
+ _campaigns;
1404
+ _realtime;
1405
+ constructor(options) {
1406
+ this.auth = new BurkiAuth(options.apiKey);
1407
+ this.baseUrl = options.baseUrl || DEFAULT_BASE_URL;
1408
+ this.httpClient = new HTTPClient({
1409
+ auth: this.auth,
1410
+ baseUrl: this.baseUrl,
1411
+ timeout: options.timeout || DEFAULT_TIMEOUT
1412
+ });
1413
+ }
1414
+ /**
1415
+ * Access the Assistants resource.
1416
+ */
1417
+ get assistants() {
1418
+ if (!this._assistants) {
1419
+ this._assistants = new AssistantsResource(this.httpClient);
1420
+ }
1421
+ return this._assistants;
1422
+ }
1423
+ /**
1424
+ * Access the Calls resource.
1425
+ */
1426
+ get calls() {
1427
+ if (!this._calls) {
1428
+ this._calls = new CallsResource(this.httpClient);
1429
+ }
1430
+ return this._calls;
1431
+ }
1432
+ /**
1433
+ * Access the Phone Numbers resource.
1434
+ */
1435
+ get phoneNumbers() {
1436
+ if (!this._phoneNumbers) {
1437
+ this._phoneNumbers = new PhoneNumbersResource(this.httpClient);
1438
+ }
1439
+ return this._phoneNumbers;
1440
+ }
1441
+ /**
1442
+ * Access the Documents resource.
1443
+ */
1444
+ get documents() {
1445
+ if (!this._documents) {
1446
+ this._documents = new DocumentsResource(this.httpClient);
1447
+ }
1448
+ return this._documents;
1449
+ }
1450
+ /**
1451
+ * Access the Tools resource.
1452
+ */
1453
+ get tools() {
1454
+ if (!this._tools) {
1455
+ this._tools = new ToolsResource(this.httpClient);
1456
+ }
1457
+ return this._tools;
1458
+ }
1459
+ /**
1460
+ * Access the SMS resource.
1461
+ */
1462
+ get sms() {
1463
+ if (!this._sms) {
1464
+ this._sms = new SMSResource(this.httpClient);
1465
+ }
1466
+ return this._sms;
1467
+ }
1468
+ /**
1469
+ * Access the Campaigns resource.
1470
+ */
1471
+ get campaigns() {
1472
+ if (!this._campaigns) {
1473
+ this._campaigns = new CampaignsResource(this.httpClient);
1474
+ }
1475
+ return this._campaigns;
1476
+ }
1477
+ /**
1478
+ * Access the Realtime (WebSocket) client.
1479
+ */
1480
+ get realtime() {
1481
+ if (!this._realtime) {
1482
+ this._realtime = new RealtimeClient(this.auth, this.baseUrl);
1483
+ }
1484
+ return this._realtime;
1485
+ }
1486
+ };
1487
+ export {
1488
+ AssistantsResource,
1489
+ AuthenticationError,
1490
+ BurkiAuth,
1491
+ BurkiClient,
1492
+ BurkiError,
1493
+ CallsResource,
1494
+ CampaignProgressStream,
1495
+ CampaignsResource,
1496
+ DocumentsResource,
1497
+ LiveTranscriptStream,
1498
+ NotFoundError,
1499
+ PhoneNumbersResource,
1500
+ RateLimitError,
1501
+ RealtimeClient,
1502
+ SMSResource,
1503
+ ServerError,
1504
+ ToolsResource,
1505
+ ValidationError,
1506
+ WebSocketError
1507
+ };