@lichen-ai/chatkit-web-shared 0.4.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.js ADDED
@@ -0,0 +1,817 @@
1
+ class EventEmitter {
2
+ callbacks = /* @__PURE__ */ new Map();
3
+ on(event, callback) {
4
+ if (!this.callbacks.has(event)) {
5
+ this.callbacks.set(event, /* @__PURE__ */ new Set());
6
+ }
7
+ this.callbacks.get(event).add(callback);
8
+ }
9
+ emit(event, ...args) {
10
+ const data = args[0];
11
+ this.callbacks.get(event)?.forEach((callback) => callback(data));
12
+ }
13
+ off(event, callback) {
14
+ if (!callback) {
15
+ this.callbacks.delete(event);
16
+ } else {
17
+ this.callbacks.get(event)?.delete(callback);
18
+ }
19
+ }
20
+ allOff() {
21
+ this.callbacks.clear();
22
+ }
23
+ }
24
+ async function getBytes(stream, onChunk) {
25
+ const reader = stream.getReader();
26
+ let result;
27
+ while (!(result = await reader.read()).done) {
28
+ onChunk(result.value);
29
+ }
30
+ }
31
+ function getLines(onLine) {
32
+ let buffer;
33
+ let position;
34
+ let fieldLength;
35
+ let discardTrailingNewline = false;
36
+ return function onChunk(arr) {
37
+ if (buffer === void 0) {
38
+ buffer = arr;
39
+ position = 0;
40
+ fieldLength = -1;
41
+ } else {
42
+ buffer = concat(buffer, arr);
43
+ }
44
+ const bufLength = buffer.length;
45
+ let lineStart = 0;
46
+ while (position < bufLength) {
47
+ if (discardTrailingNewline) {
48
+ if (buffer[position] === 10) {
49
+ lineStart = ++position;
50
+ }
51
+ discardTrailingNewline = false;
52
+ }
53
+ let lineEnd = -1;
54
+ for (; position < bufLength && lineEnd === -1; ++position) {
55
+ switch (buffer[position]) {
56
+ case 58:
57
+ if (fieldLength === -1) {
58
+ fieldLength = position - lineStart;
59
+ }
60
+ break;
61
+ case 13:
62
+ discardTrailingNewline = true;
63
+ case 10:
64
+ lineEnd = position;
65
+ break;
66
+ }
67
+ }
68
+ if (lineEnd === -1) {
69
+ break;
70
+ }
71
+ onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
72
+ lineStart = position;
73
+ fieldLength = -1;
74
+ }
75
+ if (lineStart === bufLength) {
76
+ buffer = void 0;
77
+ } else if (lineStart !== 0) {
78
+ buffer = buffer.subarray(lineStart);
79
+ position -= lineStart;
80
+ }
81
+ };
82
+ }
83
+ function getMessages(onId, onRetry, onMessage) {
84
+ let message = newMessage();
85
+ const decoder = new TextDecoder();
86
+ return function onLine(line, fieldLength) {
87
+ if (line.length === 0) {
88
+ onMessage === null || onMessage === void 0 ? void 0 : onMessage(message);
89
+ message = newMessage();
90
+ } else if (fieldLength > 0) {
91
+ const field = decoder.decode(line.subarray(0, fieldLength));
92
+ const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1);
93
+ const value = decoder.decode(line.subarray(valueOffset));
94
+ switch (field) {
95
+ case "data":
96
+ message.data = message.data ? message.data + "\n" + value : value;
97
+ break;
98
+ case "event":
99
+ message.event = value;
100
+ break;
101
+ case "id":
102
+ onId(message.id = value);
103
+ break;
104
+ case "retry":
105
+ const retry = parseInt(value, 10);
106
+ if (!isNaN(retry)) {
107
+ onRetry(message.retry = retry);
108
+ }
109
+ break;
110
+ }
111
+ }
112
+ };
113
+ }
114
+ function concat(a, b) {
115
+ const res = new Uint8Array(a.length + b.length);
116
+ res.set(a);
117
+ res.set(b, a.length);
118
+ return res;
119
+ }
120
+ function newMessage() {
121
+ return {
122
+ data: "",
123
+ event: "",
124
+ id: "",
125
+ retry: void 0
126
+ };
127
+ }
128
+ var __rest = function(s, e) {
129
+ var t = {};
130
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
131
+ t[p] = s[p];
132
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
133
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
134
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
135
+ t[p[i]] = s[p[i]];
136
+ }
137
+ return t;
138
+ };
139
+ const EventStreamContentType = "text/event-stream";
140
+ const DefaultRetryInterval = 1e3;
141
+ const LastEventId = "last-event-id";
142
+ function fetchEventSource(input, _a) {
143
+ var { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, fetch: inputFetch } = _a, rest = __rest(_a, ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden", "fetch"]);
144
+ return new Promise((resolve, reject) => {
145
+ const headers = Object.assign({}, inputHeaders);
146
+ if (!headers.accept) {
147
+ headers.accept = EventStreamContentType;
148
+ }
149
+ let curRequestController;
150
+ function onVisibilityChange() {
151
+ curRequestController.abort();
152
+ if (!document.hidden) {
153
+ create();
154
+ }
155
+ }
156
+ if (!openWhenHidden) {
157
+ document.addEventListener("visibilitychange", onVisibilityChange);
158
+ }
159
+ let retryInterval = DefaultRetryInterval;
160
+ let retryTimer = 0;
161
+ function dispose() {
162
+ document.removeEventListener("visibilitychange", onVisibilityChange);
163
+ window.clearTimeout(retryTimer);
164
+ curRequestController.abort();
165
+ }
166
+ inputSignal === null || inputSignal === void 0 ? void 0 : inputSignal.addEventListener("abort", () => {
167
+ dispose();
168
+ resolve();
169
+ });
170
+ const fetch = inputFetch !== null && inputFetch !== void 0 ? inputFetch : window.fetch;
171
+ const onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
172
+ async function create() {
173
+ var _a2;
174
+ curRequestController = new AbortController();
175
+ try {
176
+ const response = await fetch(input, Object.assign(Object.assign({}, rest), { headers, signal: curRequestController.signal }));
177
+ await onopen(response);
178
+ await getBytes(response.body, getLines(getMessages((id) => {
179
+ if (id) {
180
+ headers[LastEventId] = id;
181
+ } else {
182
+ delete headers[LastEventId];
183
+ }
184
+ }, (retry) => {
185
+ retryInterval = retry;
186
+ }, onmessage)));
187
+ onclose === null || onclose === void 0 ? void 0 : onclose();
188
+ dispose();
189
+ resolve();
190
+ } catch (err) {
191
+ if (!curRequestController.signal.aborted) {
192
+ try {
193
+ const interval = (_a2 = onerror === null || onerror === void 0 ? void 0 : onerror(err)) !== null && _a2 !== void 0 ? _a2 : retryInterval;
194
+ window.clearTimeout(retryTimer);
195
+ retryTimer = window.setTimeout(create, interval);
196
+ } catch (innerErr) {
197
+ dispose();
198
+ reject(innerErr);
199
+ }
200
+ }
201
+ }
202
+ }
203
+ create();
204
+ });
205
+ }
206
+ function defaultOnOpen(response) {
207
+ const contentType = response.headers.get("content-type");
208
+ if (!(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(EventStreamContentType))) {
209
+ throw new Error(`Expected content-type to be ${EventStreamContentType}, Actual: ${contentType}`);
210
+ }
211
+ }
212
+ const FRAME_SAFE_ERROR_KEY = "__chatkit_error__";
213
+ class HttpError extends Error {
214
+ status;
215
+ statusText;
216
+ metadata;
217
+ constructor(message, res, metadata) {
218
+ super(message);
219
+ this.name = "HttpError";
220
+ this.statusText = res.statusText;
221
+ this.status = res.status;
222
+ this.metadata = metadata;
223
+ }
224
+ static fromPossibleFrameSafeError(error) {
225
+ if (error instanceof HttpError) {
226
+ return error;
227
+ }
228
+ if (error && typeof error === "object" && FRAME_SAFE_ERROR_KEY in error && error[FRAME_SAFE_ERROR_KEY] === "HttpError") {
229
+ const safeError = error;
230
+ const parsedError = new HttpError(
231
+ safeError.message,
232
+ {
233
+ status: safeError.status,
234
+ statusText: safeError.statusText
235
+ },
236
+ safeError.metadata
237
+ );
238
+ parsedError.stack = safeError.stack;
239
+ return parsedError;
240
+ }
241
+ return null;
242
+ }
243
+ }
244
+ class FrameSafeHttpError {
245
+ [FRAME_SAFE_ERROR_KEY] = "HttpError";
246
+ message;
247
+ stack;
248
+ status;
249
+ statusText;
250
+ metadata;
251
+ constructor(message, res, metadata) {
252
+ this.message = message;
253
+ this.stack = new Error(message).stack;
254
+ this.status = res.status;
255
+ this.statusText = res.statusText;
256
+ this.metadata = metadata;
257
+ }
258
+ static fromHttpError(error) {
259
+ return new FrameSafeHttpError(
260
+ error.message,
261
+ {
262
+ status: error.status,
263
+ statusText: error.statusText
264
+ },
265
+ error.metadata
266
+ );
267
+ }
268
+ }
269
+ const BASE_RETRY_DELAY_MS = 1e3;
270
+ const MAX_RETRY_DELAY_MS = 1e4;
271
+ const MAX_RETRY_ATTEMPTS = 5;
272
+ const nextDelay = (attempt, maxRetryDelay = MAX_RETRY_DELAY_MS, baseDelayMs = BASE_RETRY_DELAY_MS) => {
273
+ const max = Math.min(maxRetryDelay, baseDelayMs * 2 ** attempt);
274
+ return Math.floor(max * (0.5 + Math.random() * 0.5));
275
+ };
276
+ class RetryableError extends Error {
277
+ constructor(cause) {
278
+ super();
279
+ this.cause = cause;
280
+ }
281
+ }
282
+ const fetchEventSourceWithRetry = async (url, params) => {
283
+ let retryAttempt = 0;
284
+ const { onopen, ...restParams } = params;
285
+ await fetchEventSource(url, {
286
+ ...restParams,
287
+ onopen: async (res) => {
288
+ onopen?.(res);
289
+ if (res.ok && res.headers.get("content-type")?.startsWith("text/event-stream")) {
290
+ retryAttempt = 0;
291
+ return;
292
+ }
293
+ const httpError = new FrameSafeHttpError(`Streaming failed: ${res.statusText}`, res);
294
+ if (res.status >= 400 && res.status < 500) {
295
+ throw httpError;
296
+ } else {
297
+ throw new RetryableError(httpError);
298
+ }
299
+ },
300
+ onerror: (error) => {
301
+ if (error instanceof RetryableError) {
302
+ if (retryAttempt >= MAX_RETRY_ATTEMPTS) {
303
+ throw error.cause;
304
+ }
305
+ retryAttempt += 1;
306
+ return nextDelay(retryAttempt);
307
+ }
308
+ throw error;
309
+ }
310
+ });
311
+ };
312
+ function safeRandomUUID() {
313
+ const cryptoRef = globalThis.crypto;
314
+ if (typeof cryptoRef?.randomUUID === "function") {
315
+ return cryptoRef.randomUUID();
316
+ }
317
+ if (typeof cryptoRef?.getRandomValues === "function") {
318
+ const bytes = new Uint8Array(16);
319
+ cryptoRef.getRandomValues(bytes);
320
+ bytes[6] = bytes[6] & 15 | 64;
321
+ bytes[8] = bytes[8] & 63 | 128;
322
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "$1-$2-$3-$4-$5");
323
+ }
324
+ return `ck_${Date.now()}_${Math.random().toString(16).slice(2)}`;
325
+ }
326
+ let IntegrationError$1 = class IntegrationError extends Error {
327
+ _name;
328
+ constructor(message) {
329
+ super(message);
330
+ this.name = "IntegrationError";
331
+ this._name = this.name;
332
+ }
333
+ static fromPossibleFrameSafeError(error) {
334
+ if (error && typeof error === "object" && FRAME_SAFE_ERROR_KEY in error && error[FRAME_SAFE_ERROR_KEY] === "IntegrationError") {
335
+ const safeError = error;
336
+ const parsedError = new IntegrationError(safeError.message);
337
+ parsedError.stack = safeError.stack;
338
+ return parsedError;
339
+ }
340
+ return null;
341
+ }
342
+ };
343
+ class FrameSafeIntegrationError {
344
+ [FRAME_SAFE_ERROR_KEY] = "IntegrationError";
345
+ message;
346
+ stack;
347
+ constructor(message) {
348
+ this.message = message;
349
+ this.stack = new Error(message).stack;
350
+ }
351
+ }
352
+ class BaseMessenger {
353
+ targetOrigin;
354
+ target;
355
+ commandHandlers;
356
+ _fetch;
357
+ constructor({
358
+ handlers,
359
+ target,
360
+ targetOrigin,
361
+ fetch = window.fetch
362
+ }) {
363
+ this.commandHandlers = handlers;
364
+ this.target = target;
365
+ this.targetOrigin = targetOrigin;
366
+ this._fetch = ((...args) => fetch(...args));
367
+ }
368
+ emitter = new EventEmitter();
369
+ handlers = /* @__PURE__ */ new Map();
370
+ fetchEventSourceHandlers = /* @__PURE__ */ new Map();
371
+ setTargetOrigin(targetOrigin) {
372
+ this.targetOrigin = targetOrigin;
373
+ }
374
+ abortControllers = /* @__PURE__ */ new Map();
375
+ sendMessage(data, transfer) {
376
+ const message = {
377
+ __xpaiChatKit: true,
378
+ ...data
379
+ };
380
+ this.target()?.postMessage(message, this.targetOrigin, transfer);
381
+ }
382
+ connect() {
383
+ window.addEventListener("message", this.handleMessage);
384
+ }
385
+ disconnect() {
386
+ window.removeEventListener("message", this.handleMessage);
387
+ }
388
+ fetch(url, params) {
389
+ return new Promise((resolve, reject) => {
390
+ const nonce = safeRandomUUID();
391
+ this.handlers.set(nonce, { resolve, reject, stack: new Error().stack || "" });
392
+ let formData;
393
+ if (params.body instanceof FormData) {
394
+ formData = {};
395
+ for (const [key, value] of params.body.entries()) {
396
+ formData[key] = value;
397
+ }
398
+ params.body = void 0;
399
+ }
400
+ if (params.signal) {
401
+ params.signal.addEventListener("abort", () => {
402
+ this.sendMessage({
403
+ type: "abortSignal",
404
+ nonce,
405
+ reason: params.signal?.reason
406
+ });
407
+ });
408
+ params.signal = void 0;
409
+ }
410
+ this.sendMessage({ type: "fetch", nonce, params, formData, url });
411
+ });
412
+ }
413
+ // Supporting onopen would require a good way for us to serialize the Response object
414
+ // across the iframe boundary, which is not trivial and also not really necessary.
415
+ fetchEventSource(url, params) {
416
+ return new Promise((resolve, reject) => {
417
+ const { onmessage, signal, ...rest } = params;
418
+ const nonce = safeRandomUUID();
419
+ this.handlers.set(nonce, { resolve, reject, stack: new Error().stack || "" });
420
+ this.fetchEventSourceHandlers.set(nonce, {
421
+ onmessage
422
+ });
423
+ if (signal) {
424
+ signal.addEventListener("abort", () => {
425
+ this.sendMessage({
426
+ type: "abortSignal",
427
+ nonce,
428
+ reason: signal.reason
429
+ });
430
+ });
431
+ }
432
+ this.sendMessage({ type: "fetchEventSource", nonce, params: rest, url });
433
+ });
434
+ }
435
+ commands = new Proxy(
436
+ {},
437
+ {
438
+ get: (_, command) => {
439
+ return (data, transfer) => {
440
+ return new Promise((resolve, reject) => {
441
+ const nonce = safeRandomUUID();
442
+ this.handlers.set(nonce, { resolve, reject, stack: new Error().stack || "" });
443
+ this.sendMessage(
444
+ {
445
+ type: "command",
446
+ nonce,
447
+ command: `on${command.charAt(0).toUpperCase()}${command.slice(1)}`,
448
+ data
449
+ },
450
+ transfer
451
+ );
452
+ });
453
+ };
454
+ }
455
+ }
456
+ );
457
+ emit(...[event, data, transfer]) {
458
+ this.sendMessage(
459
+ {
460
+ type: "event",
461
+ event,
462
+ data
463
+ },
464
+ transfer
465
+ );
466
+ }
467
+ on(...[event, callback]) {
468
+ this.emitter.on(event, callback);
469
+ }
470
+ destroy() {
471
+ window.removeEventListener("message", this.handleMessage);
472
+ this.emitter.allOff();
473
+ this.handlers.clear();
474
+ }
475
+ handleMessage = async (event) => {
476
+ if (!event.data || event.data.__xpaiChatKit !== true || event.origin !== this.targetOrigin || event.source !== this.target()) {
477
+ return;
478
+ }
479
+ const data = event.data;
480
+ switch (data.type) {
481
+ case "event": {
482
+ this.emitter.emit(data.event, data.data);
483
+ break;
484
+ }
485
+ case "fetch": {
486
+ try {
487
+ if (data.formData) {
488
+ const formData = new FormData();
489
+ for (const [key, value] of Object.entries(data.formData)) {
490
+ formData.append(key, value);
491
+ }
492
+ data.params.body = formData;
493
+ }
494
+ const controller = new AbortController();
495
+ this.abortControllers.set(data.nonce, controller);
496
+ data.params.signal = controller.signal;
497
+ const res = await this._fetch(data.url, data.params);
498
+ if (!res.ok) {
499
+ const message = await res.json().then((json2) => json2.message || res.statusText).catch(() => res.statusText);
500
+ throw new FrameSafeHttpError(message, res);
501
+ }
502
+ const json = await res.json().catch(() => ({}));
503
+ this.sendMessage({
504
+ type: "response",
505
+ response: json,
506
+ nonce: data.nonce
507
+ });
508
+ } catch (error) {
509
+ this.sendMessage({
510
+ type: "response",
511
+ error,
512
+ nonce: data.nonce
513
+ });
514
+ }
515
+ break;
516
+ }
517
+ case "fetchEventSource": {
518
+ try {
519
+ const controller = new AbortController();
520
+ this.abortControllers.set(data.nonce, controller);
521
+ await fetchEventSourceWithRetry(data.url, {
522
+ ...data.params,
523
+ signal: controller.signal,
524
+ fetch: this._fetch,
525
+ onmessage: (message) => {
526
+ this.sendMessage({
527
+ type: "fetchEventSourceMessage",
528
+ message,
529
+ nonce: data.nonce
530
+ });
531
+ }
532
+ });
533
+ this.sendMessage({
534
+ type: "response",
535
+ response: void 0,
536
+ nonce: data.nonce
537
+ });
538
+ } catch (error) {
539
+ this.sendMessage({
540
+ type: "response",
541
+ error,
542
+ nonce: data.nonce
543
+ });
544
+ }
545
+ break;
546
+ }
547
+ case "command": {
548
+ if (!this.canReceiveCommand(data.command)) {
549
+ this.sendMessage({
550
+ type: "response",
551
+ error: new FrameSafeIntegrationError(`Command ${data.command} not supported`),
552
+ nonce: data.nonce
553
+ });
554
+ return;
555
+ }
556
+ try {
557
+ const response = await this.commandHandlers[data.command]?.(data.data);
558
+ this.sendMessage({
559
+ type: "response",
560
+ response,
561
+ nonce: data.nonce
562
+ });
563
+ } catch (error) {
564
+ this.sendMessage({
565
+ type: "response",
566
+ error,
567
+ nonce: data.nonce
568
+ });
569
+ }
570
+ break;
571
+ }
572
+ case "response": {
573
+ const handler = this.handlers.get(data.nonce);
574
+ if (!handler) {
575
+ console.error("No handler found for nonce", data.nonce);
576
+ return;
577
+ }
578
+ if (data.error) {
579
+ const integrationError = IntegrationError$1.fromPossibleFrameSafeError(data.error);
580
+ const httpError = HttpError.fromPossibleFrameSafeError(data.error);
581
+ if (integrationError) {
582
+ integrationError.stack = handler.stack;
583
+ handler.reject(integrationError);
584
+ } else if (httpError) {
585
+ handler.reject(httpError);
586
+ } else {
587
+ handler.reject(data.error);
588
+ }
589
+ } else {
590
+ handler.resolve(data.response);
591
+ }
592
+ this.handlers.delete(data.nonce);
593
+ break;
594
+ }
595
+ case "fetchEventSourceMessage": {
596
+ const handler = this.fetchEventSourceHandlers.get(data.nonce);
597
+ if (!handler) {
598
+ console.error("No handler found for nonce", data.nonce);
599
+ return;
600
+ }
601
+ this.fetchEventSourceHandlers.get(data.nonce)?.onmessage?.(data.message);
602
+ break;
603
+ }
604
+ case "abortSignal": {
605
+ const controller = this.abortControllers.get(data.nonce);
606
+ if (controller) {
607
+ controller.abort(data.reason);
608
+ this.abortControllers.delete(data.nonce);
609
+ }
610
+ break;
611
+ }
612
+ }
613
+ };
614
+ }
615
+ const toUrlBase64 = (bin) => btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
616
+ const fromUrlBase64 = (b64) => atob(b64.replace(/-/g, "+").replace(/_/g, "/"));
617
+ const encodeBase64 = (value) => {
618
+ if (value === void 0) {
619
+ throw new TypeError("encodeBase64: `undefined` cannot be encoded to valid JSON. Pass null instead.");
620
+ }
621
+ const json = JSON.stringify(value);
622
+ const bytes = new TextEncoder().encode(json);
623
+ let bin = "";
624
+ for (const b of bytes) bin += String.fromCharCode(b);
625
+ return toUrlBase64(bin);
626
+ };
627
+ const decodeBase64 = (b64) => {
628
+ const bin = fromUrlBase64(b64);
629
+ const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));
630
+ const json = new TextDecoder().decode(bytes);
631
+ return JSON.parse(json);
632
+ };
633
+ class IntegrationError2 extends Error {
634
+ }
635
+ function fromPossibleFrameSafeError(err) {
636
+ return err.message;
637
+ }
638
+ const BASE_CAPABILITY_ALLOWLIST = [
639
+ // commands
640
+ "command.setOptions",
641
+ "command.sendUserMessage",
642
+ "command.setComposerValue",
643
+ "command.setThreadId",
644
+ "command.focusComposer",
645
+ "command.fetchUpdates",
646
+ "command.sendCustomAction",
647
+ "command.showHistory",
648
+ "command.hideHistory",
649
+ // events
650
+ "event.ready",
651
+ "event.error",
652
+ "event.log",
653
+ "event.response.start",
654
+ "event.response.end",
655
+ "event.response.stop",
656
+ "event.thread.change",
657
+ "event.tool.change",
658
+ "event.thread.load.start",
659
+ "event.thread.load.end",
660
+ "event.deeplink",
661
+ "event.effect",
662
+ // errors
663
+ "error.StreamError",
664
+ "error.StreamEventParsingError",
665
+ "error.WidgetItemError",
666
+ "error.InitialThreadLoadError",
667
+ "error.FileAttachmentError",
668
+ "error.HistoryViewError",
669
+ "error.FatalAppError",
670
+ "error.IntegrationError",
671
+ "error.EntitySearchError",
672
+ "error.DomainVerificationRequestError",
673
+ // backend
674
+ "backend.threads.get_by_id",
675
+ "backend.threads.list",
676
+ "backend.threads.update",
677
+ "backend.threads.delete",
678
+ "backend.threads.create",
679
+ "backend.threads.add_user_message",
680
+ "backend.threads.add_client_tool_output",
681
+ "backend.threads.retry_after_item",
682
+ "backend.threads.custom_action",
683
+ "backend.attachments.create",
684
+ "backend.attachments.get_preview",
685
+ "backend.attachments.delete",
686
+ "backend.items.list",
687
+ "backend.items.feedback",
688
+ // thread item types
689
+ "thread.item.generated_image",
690
+ "thread.item.user_message",
691
+ "thread.item.assistant_message",
692
+ "thread.item.client_tool_call",
693
+ "thread.item.widget",
694
+ "thread.item.task",
695
+ "thread.item.workflow",
696
+ "thread.item.end_of_turn",
697
+ "thread.item.image_generation",
698
+ // widgets
699
+ "widget.Basic",
700
+ "widget.Card",
701
+ "widget.ListView",
702
+ "widget.ListViewItem",
703
+ "widget.Badge",
704
+ "widget.Box",
705
+ "widget.Row",
706
+ "widget.Col",
707
+ "widget.Button",
708
+ "widget.Caption",
709
+ "widget.Chart",
710
+ "widget.Checkbox",
711
+ "widget.DatePicker",
712
+ "widget.Divider",
713
+ "widget.Form",
714
+ "widget.Icon",
715
+ "widget.Image",
716
+ "widget.Input",
717
+ "widget.Label",
718
+ "widget.Markdown",
719
+ "widget.RadioGroup",
720
+ "widget.Select",
721
+ "widget.Spacer",
722
+ "widget.Text",
723
+ "widget.Textarea",
724
+ "widget.Title",
725
+ "widget.Transition"
726
+ ];
727
+ const BASE_CAPABILITY_DENYLIST = [
728
+ // --- commands
729
+ "command.shareThread",
730
+ "command.setTrainingOptOut",
731
+ // --- events
732
+ "event.thread.restore",
733
+ "event.message.share",
734
+ "event.image.download",
735
+ "event.history.open",
736
+ "event.history.close",
737
+ "event.log.chatgpt",
738
+ // --- errors
739
+ // These errors considered internal and are not exposed to the user by default.
740
+ "error.HttpError",
741
+ "error.NetworkError",
742
+ "error.UnhandledError",
743
+ "error.UnhandledPromiseRejectionError",
744
+ "error.StreamEventHandlingError",
745
+ "error.StreamStopError",
746
+ "error.ThreadRenderingError",
747
+ "error.IntlError",
748
+ "error.AppError",
749
+ // --- backend
750
+ "backend.threads.stop",
751
+ "backend.threads.share",
752
+ "backend.threads.create_from_shared",
753
+ "backend.threads.init",
754
+ "backend.attachments.process",
755
+ // widgets
756
+ "widget.CardCarousel",
757
+ "widget.Favicon",
758
+ "widget.CardLinkItem",
759
+ "widget.Map"
760
+ ];
761
+ const PROFILE_TO_RULES = {
762
+ chatkit: {
763
+ allow: [...BASE_CAPABILITY_ALLOWLIST, "thread.item.image_generation"],
764
+ deny: BASE_CAPABILITY_DENYLIST
765
+ }
766
+ };
767
+ const getCapabilities = (profile) => {
768
+ const rules = PROFILE_TO_RULES[profile];
769
+ const effective = new Set(rules.allow);
770
+ for (const capability of rules.deny ?? []) {
771
+ effective.delete(capability);
772
+ }
773
+ const commands = /* @__PURE__ */ new Set();
774
+ const events = /* @__PURE__ */ new Set();
775
+ const backend = /* @__PURE__ */ new Set();
776
+ const threadItems = /* @__PURE__ */ new Set();
777
+ const errors = /* @__PURE__ */ new Set();
778
+ const widgets = /* @__PURE__ */ new Set();
779
+ for (const capability of effective) {
780
+ if (capability.startsWith("command.")) {
781
+ commands.add(capability.slice("command.".length));
782
+ continue;
783
+ }
784
+ if (capability.startsWith("event.")) {
785
+ events.add(capability.slice("event.".length));
786
+ continue;
787
+ }
788
+ if (capability.startsWith("backend.")) {
789
+ backend.add(capability.slice("backend.".length));
790
+ continue;
791
+ }
792
+ if (capability.startsWith("thread.item.")) {
793
+ threadItems.add(capability.slice("thread.item.".length));
794
+ }
795
+ if (capability.startsWith("error.")) {
796
+ errors.add(capability.slice("error.".length));
797
+ continue;
798
+ }
799
+ if (capability.startsWith("widget.")) {
800
+ widgets.add(capability.slice("widget.".length));
801
+ continue;
802
+ }
803
+ }
804
+ return { commands, events, backend, threadItems, errors, widgets };
805
+ };
806
+ export {
807
+ BASE_CAPABILITY_ALLOWLIST,
808
+ BASE_CAPABILITY_DENYLIST,
809
+ BaseMessenger,
810
+ IntegrationError2 as IntegrationError,
811
+ PROFILE_TO_RULES,
812
+ decodeBase64,
813
+ encodeBase64,
814
+ fromPossibleFrameSafeError,
815
+ getCapabilities
816
+ };
817
+ //# sourceMappingURL=index.js.map