@customerhero/js 2.2.0 → 2.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/README.md +19 -0
- package/dist/index.cjs +221 -21
- package/dist/index.d.cts +181 -2
- package/dist/index.d.ts +181 -2
- package/dist/index.js +215 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,29 @@ var DEFAULTS = {
|
|
|
7
7
|
position: "bottom-right",
|
|
8
8
|
placeholderText: "Type your message...",
|
|
9
9
|
welcomeMessage: "Hi! How can I help you today?",
|
|
10
|
-
title: "CustomerHero"
|
|
10
|
+
title: "CustomerHero",
|
|
11
|
+
// Appearance pack (B1–B6) defaults.
|
|
12
|
+
colorScheme: "light",
|
|
13
|
+
// Dark fallbacks used when the effective scheme is dark and no per-chatbot
|
|
14
|
+
// dark color is configured. Operators can — and should — override these.
|
|
15
|
+
primaryColorDark: "#A78BFA",
|
|
16
|
+
backgroundColorDark: "#0F172A",
|
|
17
|
+
textColorDark: "#E5E7EB",
|
|
18
|
+
size: "default",
|
|
19
|
+
cornerStyle: "rounded",
|
|
20
|
+
offsetBottom: 20,
|
|
21
|
+
offsetSide: 20,
|
|
22
|
+
zIndex: 99999
|
|
23
|
+
};
|
|
24
|
+
var SIZE_PRESETS = {
|
|
25
|
+
compact: { bubble: 48, width: 320, height: 480, fontSize: 13 },
|
|
26
|
+
default: { bubble: 56, width: 380, height: 520, fontSize: 14 },
|
|
27
|
+
large: { bubble: 64, width: 440, height: 600, fontSize: 15 }
|
|
28
|
+
};
|
|
29
|
+
var CORNER_RADIUS = {
|
|
30
|
+
soft: 8,
|
|
31
|
+
rounded: 16,
|
|
32
|
+
square: 0
|
|
11
33
|
};
|
|
12
34
|
|
|
13
35
|
// src/i18n/locales/en.ts
|
|
@@ -38,7 +60,10 @@ var en = {
|
|
|
38
60
|
drop_files_here: "Drop files here",
|
|
39
61
|
incident_dismiss: "Dismiss",
|
|
40
62
|
incident_default_link_label: "Learn more",
|
|
41
|
-
attachment_unsupported_type: "Unsupported file type"
|
|
63
|
+
attachment_unsupported_type: "Unsupported file type",
|
|
64
|
+
attachment_open: "Open attachment",
|
|
65
|
+
attachment_image_alt: "Image attachment",
|
|
66
|
+
attachment_location: "Shared location"
|
|
42
67
|
};
|
|
43
68
|
|
|
44
69
|
// src/i18n/locales/es.ts
|
|
@@ -69,7 +94,10 @@ var es = {
|
|
|
69
94
|
drop_files_here: "Suelta los archivos aqu\xED",
|
|
70
95
|
incident_dismiss: "Descartar",
|
|
71
96
|
incident_default_link_label: "M\xE1s informaci\xF3n",
|
|
72
|
-
attachment_unsupported_type: "Tipo de archivo no admitido"
|
|
97
|
+
attachment_unsupported_type: "Tipo de archivo no admitido",
|
|
98
|
+
attachment_open: "Abrir adjunto",
|
|
99
|
+
attachment_image_alt: "Imagen adjunta",
|
|
100
|
+
attachment_location: "Ubicaci\xF3n compartida"
|
|
73
101
|
};
|
|
74
102
|
|
|
75
103
|
// src/i18n/locales/pt-BR.ts
|
|
@@ -100,7 +128,10 @@ var ptBR = {
|
|
|
100
128
|
drop_files_here: "Solte os arquivos aqui",
|
|
101
129
|
incident_dismiss: "Dispensar",
|
|
102
130
|
incident_default_link_label: "Saiba mais",
|
|
103
|
-
attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado"
|
|
131
|
+
attachment_unsupported_type: "Tipo de arquivo n\xE3o suportado",
|
|
132
|
+
attachment_open: "Abrir anexo",
|
|
133
|
+
attachment_image_alt: "Imagem anexada",
|
|
134
|
+
attachment_location: "Localiza\xE7\xE3o compartilhada"
|
|
104
135
|
};
|
|
105
136
|
|
|
106
137
|
// src/i18n/locales/pt-PT.ts
|
|
@@ -131,7 +162,10 @@ var ptPT = {
|
|
|
131
162
|
drop_files_here: "Largue os ficheiros aqui",
|
|
132
163
|
incident_dismiss: "Dispensar",
|
|
133
164
|
incident_default_link_label: "Saiba mais",
|
|
134
|
-
attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado"
|
|
165
|
+
attachment_unsupported_type: "Tipo de ficheiro n\xE3o suportado",
|
|
166
|
+
attachment_open: "Abrir anexo",
|
|
167
|
+
attachment_image_alt: "Imagem anexa",
|
|
168
|
+
attachment_location: "Localiza\xE7\xE3o partilhada"
|
|
135
169
|
};
|
|
136
170
|
|
|
137
171
|
// src/i18n/locales/fr.ts
|
|
@@ -162,7 +196,10 @@ var fr = {
|
|
|
162
196
|
drop_files_here: "D\xE9posez les fichiers ici",
|
|
163
197
|
incident_dismiss: "Ignorer",
|
|
164
198
|
incident_default_link_label: "En savoir plus",
|
|
165
|
-
attachment_unsupported_type: "Type de fichier non pris en charge"
|
|
199
|
+
attachment_unsupported_type: "Type de fichier non pris en charge",
|
|
200
|
+
attachment_open: "Ouvrir la pi\xE8ce jointe",
|
|
201
|
+
attachment_image_alt: "Pi\xE8ce jointe (image)",
|
|
202
|
+
attachment_location: "Position partag\xE9e"
|
|
166
203
|
};
|
|
167
204
|
|
|
168
205
|
// src/i18n/locales/de.ts
|
|
@@ -193,7 +230,10 @@ var de = {
|
|
|
193
230
|
drop_files_here: "Dateien hier ablegen",
|
|
194
231
|
incident_dismiss: "Schlie\xDFen",
|
|
195
232
|
incident_default_link_label: "Mehr erfahren",
|
|
196
|
-
attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt"
|
|
233
|
+
attachment_unsupported_type: "Dateityp nicht unterst\xFCtzt",
|
|
234
|
+
attachment_open: "Anhang \xF6ffnen",
|
|
235
|
+
attachment_image_alt: "Bildanhang",
|
|
236
|
+
attachment_location: "Geteilter Standort"
|
|
197
237
|
};
|
|
198
238
|
|
|
199
239
|
// src/i18n/locales/it.ts
|
|
@@ -224,7 +264,10 @@ var it = {
|
|
|
224
264
|
drop_files_here: "Trascina qui i file",
|
|
225
265
|
incident_dismiss: "Chiudi",
|
|
226
266
|
incident_default_link_label: "Scopri di pi\xF9",
|
|
227
|
-
attachment_unsupported_type: "Tipo di file non supportato"
|
|
267
|
+
attachment_unsupported_type: "Tipo di file non supportato",
|
|
268
|
+
attachment_open: "Apri allegato",
|
|
269
|
+
attachment_image_alt: "Allegato immagine",
|
|
270
|
+
attachment_location: "Posizione condivisa"
|
|
228
271
|
};
|
|
229
272
|
|
|
230
273
|
// src/i18n/locales/nl.ts
|
|
@@ -255,7 +298,10 @@ var nl = {
|
|
|
255
298
|
drop_files_here: "Sleep bestanden hier",
|
|
256
299
|
incident_dismiss: "Sluiten",
|
|
257
300
|
incident_default_link_label: "Meer informatie",
|
|
258
|
-
attachment_unsupported_type: "Bestandstype niet ondersteund"
|
|
301
|
+
attachment_unsupported_type: "Bestandstype niet ondersteund",
|
|
302
|
+
attachment_open: "Bijlage openen",
|
|
303
|
+
attachment_image_alt: "Afbeeldingsbijlage",
|
|
304
|
+
attachment_location: "Gedeelde locatie"
|
|
259
305
|
};
|
|
260
306
|
|
|
261
307
|
// src/i18n/locales/pl.ts
|
|
@@ -286,7 +332,10 @@ var pl = {
|
|
|
286
332
|
drop_files_here: "Upu\u015B\u0107 pliki tutaj",
|
|
287
333
|
incident_dismiss: "Zamknij",
|
|
288
334
|
incident_default_link_label: "Dowiedz si\u0119 wi\u0119cej",
|
|
289
|
-
attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku"
|
|
335
|
+
attachment_unsupported_type: "Nieobs\u0142ugiwany typ pliku",
|
|
336
|
+
attachment_open: "Otw\xF3rz za\u0142\u0105cznik",
|
|
337
|
+
attachment_image_alt: "Za\u0142\u0105cznik obrazu",
|
|
338
|
+
attachment_location: "Udost\u0119pniona lokalizacja"
|
|
290
339
|
};
|
|
291
340
|
|
|
292
341
|
// src/i18n/locales/tr.ts
|
|
@@ -317,7 +366,10 @@ var tr = {
|
|
|
317
366
|
drop_files_here: "Dosyalar\u0131 buraya b\u0131rak",
|
|
318
367
|
incident_dismiss: "Kapat",
|
|
319
368
|
incident_default_link_label: "Daha fazla bilgi",
|
|
320
|
-
attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC"
|
|
369
|
+
attachment_unsupported_type: "Desteklenmeyen dosya t\xFCr\xFC",
|
|
370
|
+
attachment_open: "Eki a\xE7",
|
|
371
|
+
attachment_image_alt: "Resim eki",
|
|
372
|
+
attachment_location: "Payla\u015F\u0131lan konum"
|
|
321
373
|
};
|
|
322
374
|
|
|
323
375
|
// src/i18n/locales/ar.ts
|
|
@@ -348,7 +400,10 @@ var ar = {
|
|
|
348
400
|
drop_files_here: "\u0623\u0641\u0644\u062A \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0647\u0646\u0627",
|
|
349
401
|
incident_dismiss: "\u0625\u063A\u0644\u0627\u0642",
|
|
350
402
|
incident_default_link_label: "\u0627\u0639\u0631\u0641 \u0627\u0644\u0645\u0632\u064A\u062F",
|
|
351
|
-
attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645"
|
|
403
|
+
attachment_unsupported_type: "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645",
|
|
404
|
+
attachment_open: "\u0641\u062A\u062D \u0627\u0644\u0645\u0631\u0641\u0642",
|
|
405
|
+
attachment_image_alt: "\u0635\u0648\u0631\u0629 \u0645\u0631\u0641\u0642\u0629",
|
|
406
|
+
attachment_location: "\u0645\u0648\u0642\u0639 \u0645\u0634\u062A\u0631\u0643"
|
|
352
407
|
};
|
|
353
408
|
|
|
354
409
|
// src/i18n/locales/ja.ts
|
|
@@ -379,7 +434,10 @@ var ja = {
|
|
|
379
434
|
drop_files_here: "\u30D5\u30A1\u30A4\u30EB\u3092\u3053\u3053\u306B\u30C9\u30ED\u30C3\u30D7",
|
|
380
435
|
incident_dismiss: "\u9589\u3058\u308B",
|
|
381
436
|
incident_default_link_label: "\u8A73\u7D30\u3092\u898B\u308B",
|
|
382
|
-
attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F"
|
|
437
|
+
attachment_unsupported_type: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F",
|
|
438
|
+
attachment_open: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u958B\u304F",
|
|
439
|
+
attachment_image_alt: "\u753B\u50CF\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB",
|
|
440
|
+
attachment_location: "\u5171\u6709\u3055\u308C\u305F\u4F4D\u7F6E\u60C5\u5831"
|
|
383
441
|
};
|
|
384
442
|
|
|
385
443
|
// src/i18n/locales/ko.ts
|
|
@@ -410,7 +468,10 @@ var ko = {
|
|
|
410
468
|
drop_files_here: "\uD30C\uC77C\uC744 \uC5EC\uAE30\uC5D0 \uB193\uAE30",
|
|
411
469
|
incident_dismiss: "\uB2EB\uAE30",
|
|
412
470
|
incident_default_link_label: "\uC790\uC138\uD788 \uC54C\uC544\uBCF4\uAE30",
|
|
413
|
-
attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD"
|
|
471
|
+
attachment_unsupported_type: "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 \uD30C\uC77C \uD615\uC2DD",
|
|
472
|
+
attachment_open: "\uCCA8\uBD80 \uD30C\uC77C \uC5F4\uAE30",
|
|
473
|
+
attachment_image_alt: "\uC774\uBBF8\uC9C0 \uCCA8\uBD80 \uD30C\uC77C",
|
|
474
|
+
attachment_location: "\uACF5\uC720\uB41C \uC704\uCE58"
|
|
414
475
|
};
|
|
415
476
|
|
|
416
477
|
// src/i18n/locales/zh-CN.ts
|
|
@@ -441,7 +502,10 @@ var zhCN = {
|
|
|
441
502
|
drop_files_here: "\u5C06\u6587\u4EF6\u62D6\u653E\u5230\u6B64\u5904",
|
|
442
503
|
incident_dismiss: "\u5173\u95ED",
|
|
443
504
|
incident_default_link_label: "\u4E86\u89E3\u66F4\u591A",
|
|
444
|
-
attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B"
|
|
505
|
+
attachment_unsupported_type: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B",
|
|
506
|
+
attachment_open: "\u6253\u5F00\u9644\u4EF6",
|
|
507
|
+
attachment_image_alt: "\u56FE\u7247\u9644\u4EF6",
|
|
508
|
+
attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
|
|
445
509
|
};
|
|
446
510
|
|
|
447
511
|
// src/i18n/locales/zh-TW.ts
|
|
@@ -472,7 +536,10 @@ var zhTW = {
|
|
|
472
536
|
drop_files_here: "\u5C07\u6A94\u6848\u62D6\u653E\u5230\u6B64\u8655",
|
|
473
537
|
incident_dismiss: "\u95DC\u9589",
|
|
474
538
|
incident_default_link_label: "\u77AD\u89E3\u66F4\u591A",
|
|
475
|
-
attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B"
|
|
539
|
+
attachment_unsupported_type: "\u4E0D\u652F\u63F4\u7684\u6A94\u6848\u985E\u578B",
|
|
540
|
+
attachment_open: "\u958B\u555F\u9644\u4EF6",
|
|
541
|
+
attachment_image_alt: "\u5716\u7247\u9644\u4EF6",
|
|
542
|
+
attachment_location: "\u5171\u4EAB\u7684\u4F4D\u7F6E"
|
|
476
543
|
};
|
|
477
544
|
|
|
478
545
|
// src/i18n/index.ts
|
|
@@ -975,7 +1042,14 @@ function startTriggersRuntime(options) {
|
|
|
975
1042
|
}
|
|
976
1043
|
|
|
977
1044
|
// src/client.ts
|
|
1045
|
+
function clampInt(value, min, max, fallback) {
|
|
1046
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
|
|
1047
|
+
return Math.max(min, Math.min(max, Math.trunc(value)));
|
|
1048
|
+
}
|
|
978
1049
|
function resolveConfig(userConfig, fetched) {
|
|
1050
|
+
const launcherUser = userConfig.launcher ?? {};
|
|
1051
|
+
const launcherFetched = fetched?.launcher ?? {};
|
|
1052
|
+
const offsetUser = userConfig.offset ?? {};
|
|
979
1053
|
return {
|
|
980
1054
|
chatbotId: userConfig.chatbotId,
|
|
981
1055
|
apiBase: userConfig.apiBase ?? DEFAULTS.apiBase,
|
|
@@ -988,7 +1062,32 @@ function resolveConfig(userConfig, fetched) {
|
|
|
988
1062
|
title: userConfig.title ?? fetched?.title ?? DEFAULTS.title,
|
|
989
1063
|
avatarUrl: userConfig.avatarUrl ?? fetched?.avatarUrl,
|
|
990
1064
|
suggestedMessages: userConfig.suggestedMessages ?? fetched?.suggestedMessages ?? [],
|
|
991
|
-
stringOverrides: fetched?.stringOverrides
|
|
1065
|
+
stringOverrides: fetched?.stringOverrides,
|
|
1066
|
+
// Appearance pack. Color palette + size + corner style + launcher all
|
|
1067
|
+
// come from the server widget_config (with host-side override). The
|
|
1068
|
+
// *runtime* knobs — colorScheme, offset, zIndex — are host-only because
|
|
1069
|
+
// they depend on the page the widget is embedded in, not the chatbot.
|
|
1070
|
+
primaryColorDark: userConfig.primaryColorDark ?? fetched?.primaryColorDark,
|
|
1071
|
+
backgroundColorDark: userConfig.backgroundColorDark ?? fetched?.backgroundColorDark,
|
|
1072
|
+
textColorDark: userConfig.textColorDark ?? fetched?.textColorDark,
|
|
1073
|
+
size: userConfig.size ?? fetched?.size ?? DEFAULTS.size,
|
|
1074
|
+
cornerStyle: userConfig.cornerStyle ?? fetched?.cornerStyle ?? DEFAULTS.cornerStyle,
|
|
1075
|
+
launcher: {
|
|
1076
|
+
iconUrl: launcherUser.iconUrl ?? launcherFetched.iconUrl,
|
|
1077
|
+
label: launcherUser.label ?? launcherFetched.label,
|
|
1078
|
+
showOnlineDot: launcherUser.showOnlineDot ?? launcherFetched.showOnlineDot ?? false
|
|
1079
|
+
},
|
|
1080
|
+
colorScheme: userConfig.colorScheme ?? DEFAULTS.colorScheme,
|
|
1081
|
+
offset: {
|
|
1082
|
+
bottom: clampInt(offsetUser.bottom, 0, 1e3, DEFAULTS.offsetBottom),
|
|
1083
|
+
side: clampInt(offsetUser.side, 0, 1e3, DEFAULTS.offsetSide)
|
|
1084
|
+
},
|
|
1085
|
+
zIndex: clampInt(userConfig.zIndex, 0, 2e9, DEFAULTS.zIndex),
|
|
1086
|
+
// Defaults to true — the widget shows the attach button unless the
|
|
1087
|
+
// chatbot explicitly opts out via widget_config or the host passes
|
|
1088
|
+
// allowAttachments=false. Server still enforces the same flag at the
|
|
1089
|
+
// upload endpoint either way.
|
|
1090
|
+
allowAttachments: userConfig.allowAttachments ?? fetched?.allowAttachments ?? true
|
|
992
1091
|
};
|
|
993
1092
|
}
|
|
994
1093
|
function sanitizeIncidentBanner(input) {
|
|
@@ -1078,9 +1177,40 @@ var CustomerHeroChat = class {
|
|
|
1078
1177
|
pendingTriggerId: null,
|
|
1079
1178
|
pendingPrefill: null,
|
|
1080
1179
|
incidentBanner: null,
|
|
1081
|
-
incidentBannerDismissed: false
|
|
1180
|
+
incidentBannerDismissed: false,
|
|
1181
|
+
readOnly: false
|
|
1082
1182
|
};
|
|
1083
1183
|
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Mark the config as loaded and put the client into read-only preview
|
|
1186
|
+
* mode without hitting the API. Used by `@customerhero/react/preview` to
|
|
1187
|
+
* render the widget against a host-supplied config (the dashboard preview
|
|
1188
|
+
* pane). Public API consumers should not call this.
|
|
1189
|
+
*
|
|
1190
|
+
* Pass a config to re-resolve and update the rendered colors/size/launcher
|
|
1191
|
+
* in place. Callers should reuse the same client instance across config
|
|
1192
|
+
* changes so the open animation only fires once.
|
|
1193
|
+
*
|
|
1194
|
+
* @internal
|
|
1195
|
+
*/
|
|
1196
|
+
__seedForPreview(config, extras) {
|
|
1197
|
+
const resolved = config ? resolveConfig(config) : this.state.config;
|
|
1198
|
+
if (config) this.userConfig = config;
|
|
1199
|
+
const seededMessages = resolved.welcomeMessage ? [{ role: "bot", content: resolved.welcomeMessage }] : [];
|
|
1200
|
+
const sanitizedBanner = extras && "banner" in extras ? sanitizeIncidentBanner(extras.banner ?? null) : this.state.incidentBanner;
|
|
1201
|
+
this.setState({
|
|
1202
|
+
config: resolved,
|
|
1203
|
+
configLoaded: true,
|
|
1204
|
+
configError: null,
|
|
1205
|
+
readOnly: true,
|
|
1206
|
+
isOpen: true,
|
|
1207
|
+
messages: seededMessages,
|
|
1208
|
+
incidentBanner: sanitizedBanner,
|
|
1209
|
+
// Reset the dismissed flag so toggling the banner on in the dashboard
|
|
1210
|
+
// re-renders it after a previous preview-side dismiss.
|
|
1211
|
+
incidentBannerDismissed: false
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1084
1214
|
// ── Proactive engagement state ─────────────────────────────────────
|
|
1085
1215
|
triggersRuntime = null;
|
|
1086
1216
|
preChatFormSubmitted = false;
|
|
@@ -1189,12 +1319,15 @@ var CustomerHeroChat = class {
|
|
|
1189
1319
|
const { chatbotId, apiBase } = this.state.config;
|
|
1190
1320
|
const { conversationId } = this.state;
|
|
1191
1321
|
if (!conversationId) return;
|
|
1322
|
+
const readToken = this.storage?.getItem(`ch_conv_token_${chatbotId}`);
|
|
1323
|
+
const messagesUrl = `${apiBase}/api/chat/${chatbotId}/messages/${conversationId}`;
|
|
1192
1324
|
try {
|
|
1193
1325
|
const response = await fetch(
|
|
1194
|
-
`${
|
|
1326
|
+
readToken ? `${messagesUrl}?t=${encodeURIComponent(readToken)}` : messagesUrl
|
|
1195
1327
|
);
|
|
1196
1328
|
if (!response.ok) {
|
|
1197
1329
|
this.storage?.removeItem(`ch_conv_${chatbotId}`);
|
|
1330
|
+
this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
|
|
1198
1331
|
this.setState({ conversationId: null });
|
|
1199
1332
|
return;
|
|
1200
1333
|
}
|
|
@@ -1206,7 +1339,8 @@ var CustomerHeroChat = class {
|
|
|
1206
1339
|
content: m.content,
|
|
1207
1340
|
...m.sources ? { sources: m.sources } : {},
|
|
1208
1341
|
...m.blocks ? { blocks: m.blocks } : {},
|
|
1209
|
-
...m.suggestions ? { suggestions: m.suggestions } : {}
|
|
1342
|
+
...m.suggestions ? { suggestions: m.suggestions } : {},
|
|
1343
|
+
...m.attachments?.length ? { attachments: m.attachments } : {}
|
|
1210
1344
|
}));
|
|
1211
1345
|
const lastBotIndex = findLastIndex(
|
|
1212
1346
|
messages,
|
|
@@ -1226,6 +1360,7 @@ var CustomerHeroChat = class {
|
|
|
1226
1360
|
}
|
|
1227
1361
|
}
|
|
1228
1362
|
async sendMessage(message, options) {
|
|
1363
|
+
if (this.state.readOnly) return;
|
|
1229
1364
|
const trimmed = message.trim();
|
|
1230
1365
|
const attachmentTokens = options?.attachmentTokens ?? [];
|
|
1231
1366
|
if (!trimmed || this.state.isLoading) return;
|
|
@@ -1309,6 +1444,16 @@ var CustomerHeroChat = class {
|
|
|
1309
1444
|
}
|
|
1310
1445
|
break;
|
|
1311
1446
|
}
|
|
1447
|
+
case "read-token": {
|
|
1448
|
+
const tok = safeParse(evt.data);
|
|
1449
|
+
if (tok?.readToken) {
|
|
1450
|
+
this.storage?.setItem(
|
|
1451
|
+
`ch_conv_token_${chatbotId}`,
|
|
1452
|
+
tok.readToken
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
break;
|
|
1456
|
+
}
|
|
1312
1457
|
case "token": {
|
|
1313
1458
|
const tok = safeParse(evt.data);
|
|
1314
1459
|
const text = tok?.text ?? "";
|
|
@@ -1421,6 +1566,9 @@ var CustomerHeroChat = class {
|
|
|
1421
1566
|
await this.loadHistory();
|
|
1422
1567
|
return;
|
|
1423
1568
|
}
|
|
1569
|
+
const decisionBlock = this.state.messages[targetIndex].blocks?.find(
|
|
1570
|
+
(b) => b.type === "action_confirmation" && b.pendingToolCallId === pendingId
|
|
1571
|
+
);
|
|
1424
1572
|
const messages = this.state.messages.slice();
|
|
1425
1573
|
const original = messages[targetIndex];
|
|
1426
1574
|
messages[targetIndex] = {
|
|
@@ -1429,7 +1577,8 @@ var CustomerHeroChat = class {
|
|
|
1429
1577
|
};
|
|
1430
1578
|
this.setState({ messages, error: null });
|
|
1431
1579
|
const { chatbotId, apiBase } = this.state.config;
|
|
1432
|
-
const
|
|
1580
|
+
const href = decision === "approve" ? decisionBlock?.approveHref : decisionBlock?.cancelHref;
|
|
1581
|
+
const url = href ? `${apiBase}${href}` : `${apiBase}/api/chat/${chatbotId}/tool-calls/${pendingId}/decision`;
|
|
1433
1582
|
try {
|
|
1434
1583
|
const response = await fetch(url, {
|
|
1435
1584
|
method: "POST",
|
|
@@ -1461,6 +1610,16 @@ var CustomerHeroChat = class {
|
|
|
1461
1610
|
}
|
|
1462
1611
|
break;
|
|
1463
1612
|
}
|
|
1613
|
+
case "read-token": {
|
|
1614
|
+
const tok = safeParse(evt.data);
|
|
1615
|
+
if (tok?.readToken) {
|
|
1616
|
+
this.storage?.setItem(
|
|
1617
|
+
`ch_conv_token_${chatbotId}`,
|
|
1618
|
+
tok.readToken
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1464
1623
|
case "token": {
|
|
1465
1624
|
const tok = safeParse(evt.data);
|
|
1466
1625
|
const text = tok?.text ?? "";
|
|
@@ -1567,6 +1726,7 @@ var CustomerHeroChat = class {
|
|
|
1567
1726
|
reset() {
|
|
1568
1727
|
const { chatbotId, welcomeMessage } = this.state.config;
|
|
1569
1728
|
this.storage?.removeItem(`ch_conv_${chatbotId}`);
|
|
1729
|
+
this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
|
|
1570
1730
|
this.setState({
|
|
1571
1731
|
messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
|
|
1572
1732
|
conversationId: null,
|
|
@@ -1734,6 +1894,7 @@ var CustomerHeroChat = class {
|
|
|
1734
1894
|
};
|
|
1735
1895
|
const { chatbotId, welcomeMessage } = this.state.config;
|
|
1736
1896
|
this.storage?.removeItem(`ch_conv_${chatbotId}`);
|
|
1897
|
+
this.storage?.removeItem(`ch_conv_token_${chatbotId}`);
|
|
1737
1898
|
this.setState({
|
|
1738
1899
|
messages: welcomeMessage ? [{ role: "bot", content: welcomeMessage }] : [],
|
|
1739
1900
|
conversationId: null,
|
|
@@ -1778,6 +1939,33 @@ function pickExtension(mime) {
|
|
|
1778
1939
|
return "jpg";
|
|
1779
1940
|
}
|
|
1780
1941
|
|
|
1942
|
+
// src/theme.ts
|
|
1943
|
+
function resolveScheme(colorScheme, prefersDark) {
|
|
1944
|
+
if (colorScheme === "dark") return "dark";
|
|
1945
|
+
if (colorScheme === "light") return "light";
|
|
1946
|
+
return prefersDark ? "dark" : "light";
|
|
1947
|
+
}
|
|
1948
|
+
function effectiveColors(config, scheme) {
|
|
1949
|
+
if (scheme === "dark") {
|
|
1950
|
+
return {
|
|
1951
|
+
primary: config.primaryColorDark ?? DEFAULTS.primaryColorDark,
|
|
1952
|
+
background: config.backgroundColorDark ?? DEFAULTS.backgroundColorDark,
|
|
1953
|
+
text: config.textColorDark ?? DEFAULTS.textColorDark
|
|
1954
|
+
};
|
|
1955
|
+
}
|
|
1956
|
+
return {
|
|
1957
|
+
primary: config.primaryColor,
|
|
1958
|
+
background: config.backgroundColor,
|
|
1959
|
+
text: config.textColor
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
function sizePreset(size) {
|
|
1963
|
+
return SIZE_PRESETS[size];
|
|
1964
|
+
}
|
|
1965
|
+
function panelRadius(cornerStyle) {
|
|
1966
|
+
return CORNER_RADIUS[cornerStyle];
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1781
1969
|
// src/screenshot.ts
|
|
1782
1970
|
var ScreenshotCancelled = class extends Error {
|
|
1783
1971
|
constructor(message = "Screenshot cancelled") {
|
|
@@ -1911,8 +2099,10 @@ async function canvasToBlob(canvas, quality) {
|
|
|
1911
2099
|
});
|
|
1912
2100
|
}
|
|
1913
2101
|
export {
|
|
2102
|
+
CORNER_RADIUS,
|
|
1914
2103
|
CustomerHeroChat,
|
|
1915
2104
|
DEFAULTS,
|
|
2105
|
+
SIZE_PRESETS,
|
|
1916
2106
|
SUPPORTED_LOCALES,
|
|
1917
2107
|
ScreenshotCancelled,
|
|
1918
2108
|
ScreenshotUnavailable,
|
|
@@ -1920,9 +2110,13 @@ export {
|
|
|
1920
2110
|
captureScreenshot,
|
|
1921
2111
|
createTranslator,
|
|
1922
2112
|
detectLocale,
|
|
2113
|
+
effectiveColors,
|
|
1923
2114
|
evaluate,
|
|
1924
2115
|
isRtlLocale,
|
|
2116
|
+
panelRadius,
|
|
1925
2117
|
pickFire,
|
|
1926
2118
|
resolveLocale,
|
|
2119
|
+
resolveScheme,
|
|
2120
|
+
sizePreset,
|
|
1927
2121
|
startTriggersRuntime
|
|
1928
2122
|
};
|