chatbotlite 0.6.0 → 0.6.1
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/client/index.cjs +28 -8
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +15 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +28 -8
- package/dist/client/index.js.map +1 -1
- package/dist/core/index.cjs +15 -6
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +26 -5
- package/dist/core/index.d.ts +26 -5
- package/dist/core/index.js +15 -6
- package/dist/core/index.js.map +1 -1
- package/dist/embed.global.js +21 -21
- package/dist/embed.global.js.map +1 -1
- package/dist/index.cjs +28 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -8
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +135 -45
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +13 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.js +136 -46
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -95,6 +95,19 @@ interface ChatWidgetDirectProps extends ChatWidgetCommonProps {
|
|
|
95
95
|
knowledge: Knowledge;
|
|
96
96
|
/** Provider chain + API keys. */
|
|
97
97
|
providers: ProviderConfig;
|
|
98
|
+
/**
|
|
99
|
+
* Append per-vertical behaviour tweaks to the default system prompt
|
|
100
|
+
* (tone, escalation rules, "don't quote price too early", etc.).
|
|
101
|
+
* Only used in direct (client-side) mode — in endpoint mode the server
|
|
102
|
+
* controls the prompt.
|
|
103
|
+
*/
|
|
104
|
+
extraInstructions?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Power-user hook to modify our default scaffolding inline.
|
|
107
|
+
* Receives the assembled default prompt, returns a transformed string.
|
|
108
|
+
* Direct mode only.
|
|
109
|
+
*/
|
|
110
|
+
systemPromptTransform?: (defaultPrompt: string) => string;
|
|
98
111
|
endpoint?: never;
|
|
99
112
|
}
|
|
100
113
|
interface ChatWidgetEndpointProps extends ChatWidgetCommonProps {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -95,6 +95,19 @@ interface ChatWidgetDirectProps extends ChatWidgetCommonProps {
|
|
|
95
95
|
knowledge: Knowledge;
|
|
96
96
|
/** Provider chain + API keys. */
|
|
97
97
|
providers: ProviderConfig;
|
|
98
|
+
/**
|
|
99
|
+
* Append per-vertical behaviour tweaks to the default system prompt
|
|
100
|
+
* (tone, escalation rules, "don't quote price too early", etc.).
|
|
101
|
+
* Only used in direct (client-side) mode — in endpoint mode the server
|
|
102
|
+
* controls the prompt.
|
|
103
|
+
*/
|
|
104
|
+
extraInstructions?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Power-user hook to modify our default scaffolding inline.
|
|
107
|
+
* Receives the assembled default prompt, returns a transformed string.
|
|
108
|
+
* Direct mode only.
|
|
109
|
+
*/
|
|
110
|
+
systemPromptTransform?: (defaultPrompt: string) => string;
|
|
98
111
|
endpoint?: never;
|
|
99
112
|
}
|
|
100
113
|
interface ChatWidgetEndpointProps extends ChatWidgetCommonProps {
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState,
|
|
1
|
+
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/react/ChatWidget.tsx
|
|
@@ -67,9 +67,11 @@ function buildToolsPromptAddendum(enabledTools) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// src/core/prompts.ts
|
|
70
|
-
function buildSystemPrompt(knowledge,
|
|
71
|
-
const
|
|
72
|
-
|
|
70
|
+
function buildSystemPrompt(knowledge, optionsOrEnabledTools = []) {
|
|
71
|
+
const opts = Array.isArray(optionsOrEnabledTools) ? { enabledTools: optionsOrEnabledTools } : optionsOrEnabledTools;
|
|
72
|
+
const toolsAddendum = buildToolsPromptAddendum(opts.enabledTools ?? []);
|
|
73
|
+
const extras = opts.extraInstructions?.trim();
|
|
74
|
+
const parts = [
|
|
73
75
|
"You are an AI assistant on a business website. Use ONLY the knowledge below to answer.",
|
|
74
76
|
"",
|
|
75
77
|
"## Business knowledge",
|
|
@@ -81,9 +83,16 @@ function buildSystemPrompt(knowledge, enabledTools = []) {
|
|
|
81
83
|
"- For anything not covered in the knowledge above, say the owner will follow up \u2014 do NOT guess.",
|
|
82
84
|
'- If the caller is clearly a vendor/sales pitch, say: "This does not look like a customer service request, so we will not continue this thread."',
|
|
83
85
|
`- If wrong number or asked to stop, say: "Sorry about that. We won't text again."`,
|
|
84
|
-
"- Match the caller's language automatically."
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
"- Match the caller's language automatically."
|
|
87
|
+
];
|
|
88
|
+
if (extras) {
|
|
89
|
+
parts.push("", "## Additional instructions", extras);
|
|
90
|
+
}
|
|
91
|
+
if (toolsAddendum) {
|
|
92
|
+
parts.push(toolsAddendum);
|
|
93
|
+
}
|
|
94
|
+
const defaultPrompt = parts.join("\n");
|
|
95
|
+
return opts.systemPromptTransform ? opts.systemPromptTransform(defaultPrompt) : defaultPrompt;
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
// src/core/guards.ts
|
|
@@ -207,6 +216,8 @@ var ChatBot = class {
|
|
|
207
216
|
cachedSystemPrompt;
|
|
208
217
|
guards;
|
|
209
218
|
knowledge;
|
|
219
|
+
extraInstructions;
|
|
220
|
+
systemPromptTransform;
|
|
210
221
|
constructor(init) {
|
|
211
222
|
if (!init.knowledge || typeof init.knowledge !== "string" || init.knowledge.trim().length === 0) {
|
|
212
223
|
throw new Error("chatbotlite: knowledge is required (a non-empty markdown string).");
|
|
@@ -216,14 +227,23 @@ var ChatBot = class {
|
|
|
216
227
|
this.steps = resolveChain(init.providers);
|
|
217
228
|
this.fetcher = init.options?.fetch ?? globalThis.fetch.bind(globalThis);
|
|
218
229
|
this.timeoutMs = init.options?.timeoutMs ?? 3e4;
|
|
219
|
-
this.
|
|
230
|
+
this.extraInstructions = init.extraInstructions;
|
|
231
|
+
this.systemPromptTransform = init.systemPromptTransform;
|
|
232
|
+
this.cachedSystemPrompt = buildSystemPrompt(init.knowledge, {
|
|
233
|
+
extraInstructions: this.extraInstructions,
|
|
234
|
+
systemPromptTransform: this.systemPromptTransform
|
|
235
|
+
});
|
|
220
236
|
this.guards = init.guards ?? {};
|
|
221
237
|
}
|
|
222
238
|
/** Build system prompt for given opts — uses cached if no enabledTools, else rebuilds. */
|
|
223
239
|
resolveSystemPrompt(opts) {
|
|
224
240
|
if (opts.systemPrompt) return opts.systemPrompt;
|
|
225
241
|
if (opts.enabledTools && opts.enabledTools.length > 0) {
|
|
226
|
-
return buildSystemPrompt(this.knowledge,
|
|
242
|
+
return buildSystemPrompt(this.knowledge, {
|
|
243
|
+
enabledTools: opts.enabledTools,
|
|
244
|
+
extraInstructions: this.extraInstructions,
|
|
245
|
+
systemPromptTransform: this.systemPromptTransform
|
|
246
|
+
});
|
|
227
247
|
}
|
|
228
248
|
return this.cachedSystemPrompt;
|
|
229
249
|
}
|
|
@@ -893,7 +913,7 @@ function RequestPayment(props) {
|
|
|
893
913
|
surface,
|
|
894
914
|
textBody,
|
|
895
915
|
textMuted,
|
|
896
|
-
showInterac =
|
|
916
|
+
showInterac = false,
|
|
897
917
|
stripeLink,
|
|
898
918
|
onPick,
|
|
899
919
|
submitting = false,
|
|
@@ -1009,8 +1029,12 @@ function RequestPayment(props) {
|
|
|
1009
1029
|
display: "flex",
|
|
1010
1030
|
alignItems: "center",
|
|
1011
1031
|
justifyContent: "center",
|
|
1012
|
-
flexShrink: 0
|
|
1013
|
-
|
|
1032
|
+
flexShrink: 0,
|
|
1033
|
+
color: "#635BFF"
|
|
1034
|
+
}, children: /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1035
|
+
/* @__PURE__ */ jsx("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2.5" }),
|
|
1036
|
+
/* @__PURE__ */ jsx("line", { x1: "2", y1: "10", x2: "22", y2: "10" })
|
|
1037
|
+
] }) }),
|
|
1014
1038
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
1015
1039
|
/* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: 13, fontWeight: 600, color: textBody }, children: "Pay by card" }),
|
|
1016
1040
|
/* @__PURE__ */ jsx("p", { style: { margin: "2px 0 0", fontSize: 11, color: textMuted }, children: "Visa \xB7 Mastercard \xB7 Amex" })
|
|
@@ -1151,6 +1175,33 @@ function ChatWidget(props) {
|
|
|
1151
1175
|
const voiceLang = voiceCfg?.lang ?? "en-US";
|
|
1152
1176
|
const speechSupported = typeof window !== "undefined" && (Boolean(window.SpeechRecognition) || Boolean(window.webkitSpeechRecognition));
|
|
1153
1177
|
const [open, setOpen] = useState(false);
|
|
1178
|
+
const [expanded, setExpanded] = useState(() => {
|
|
1179
|
+
if (typeof window === "undefined") return false;
|
|
1180
|
+
try {
|
|
1181
|
+
return window.localStorage.getItem("cbl-panel-size") === "expanded";
|
|
1182
|
+
} catch {
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
const [isMobile, setIsMobile] = useState(
|
|
1187
|
+
() => typeof window === "undefined" ? false : window.innerWidth < 640
|
|
1188
|
+
);
|
|
1189
|
+
useEffect(() => {
|
|
1190
|
+
if (typeof window === "undefined") return;
|
|
1191
|
+
const onResize = () => setIsMobile(window.innerWidth < 640);
|
|
1192
|
+
window.addEventListener("resize", onResize);
|
|
1193
|
+
return () => window.removeEventListener("resize", onResize);
|
|
1194
|
+
}, []);
|
|
1195
|
+
function toggleExpanded() {
|
|
1196
|
+
setExpanded((prev) => {
|
|
1197
|
+
const next = !prev;
|
|
1198
|
+
try {
|
|
1199
|
+
window.localStorage.setItem("cbl-panel-size", next ? "expanded" : "compact");
|
|
1200
|
+
} catch {
|
|
1201
|
+
}
|
|
1202
|
+
return next;
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1154
1205
|
const [messages, setMessages] = useState([
|
|
1155
1206
|
{ id: "g0", role: "assistant", content: resolvedGreeting, ts: Date.now() }
|
|
1156
1207
|
]);
|
|
@@ -1243,11 +1294,17 @@ function ChatWidget(props) {
|
|
|
1243
1294
|
useEffect(() => {
|
|
1244
1295
|
ensureStyles();
|
|
1245
1296
|
}, []);
|
|
1297
|
+
const directProps = isEndpointMode ? null : props;
|
|
1246
1298
|
const bot = useMemo(() => {
|
|
1247
|
-
if (
|
|
1248
|
-
if (!
|
|
1249
|
-
return new ChatBot({
|
|
1250
|
-
|
|
1299
|
+
if (!directProps) return null;
|
|
1300
|
+
if (!directProps.knowledge || !directProps.providers) return null;
|
|
1301
|
+
return new ChatBot({
|
|
1302
|
+
knowledge: directProps.knowledge,
|
|
1303
|
+
providers: directProps.providers,
|
|
1304
|
+
...directProps.extraInstructions ? { extraInstructions: directProps.extraInstructions } : {},
|
|
1305
|
+
...directProps.systemPromptTransform ? { systemPromptTransform: directProps.systemPromptTransform } : {}
|
|
1306
|
+
});
|
|
1307
|
+
}, [directProps]);
|
|
1251
1308
|
useEffect(() => {
|
|
1252
1309
|
if (scrollRef.current) {
|
|
1253
1310
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
@@ -1428,12 +1485,12 @@ function ChatWidget(props) {
|
|
|
1428
1485
|
["--cbl-primary"]: primary,
|
|
1429
1486
|
["--cbl-on-primary"]: onPrimary,
|
|
1430
1487
|
position: "fixed",
|
|
1431
|
-
bottom: 20,
|
|
1432
|
-
...panelPos,
|
|
1433
|
-
width: 380,
|
|
1434
|
-
maxWidth: "calc(100vw - 40px)",
|
|
1435
|
-
height: 580,
|
|
1436
|
-
maxHeight: "calc(100vh - 40px)",
|
|
1488
|
+
bottom: isMobile ? 0 : 20,
|
|
1489
|
+
...isMobile ? { left: 0, right: 0 } : panelPos,
|
|
1490
|
+
width: isMobile ? "100vw" : expanded ? 720 : 380,
|
|
1491
|
+
maxWidth: isMobile ? "100vw" : "calc(100vw - 40px)",
|
|
1492
|
+
height: isMobile ? "100vh" : expanded ? 800 : 580,
|
|
1493
|
+
maxHeight: isMobile ? "100vh" : "calc(100vh - 40px)",
|
|
1437
1494
|
background: SURFACE,
|
|
1438
1495
|
color: TEXT_BODY,
|
|
1439
1496
|
borderRadius: 20,
|
|
@@ -1491,30 +1548,63 @@ function ChatWidget(props) {
|
|
|
1491
1548
|
(subtitle || sending) && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: TEXT_MUTED, marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: subtitle ?? (sending ? "typing\u2026" : "") })
|
|
1492
1549
|
] })
|
|
1493
1550
|
] }),
|
|
1494
|
-
/* @__PURE__ */
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1551
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 2, flexShrink: 0 }, children: [
|
|
1552
|
+
!isMobile && /* @__PURE__ */ jsx(
|
|
1553
|
+
"button",
|
|
1554
|
+
{
|
|
1555
|
+
className: "chatbotlite-resize",
|
|
1556
|
+
onClick: toggleExpanded,
|
|
1557
|
+
"aria-label": expanded ? "Compact view" : "Expand view",
|
|
1558
|
+
title: expanded ? "Compact view" : "Expand view",
|
|
1559
|
+
style: {
|
|
1560
|
+
background: "transparent",
|
|
1561
|
+
border: "none",
|
|
1562
|
+
color: TEXT_MUTED,
|
|
1563
|
+
width: 32,
|
|
1564
|
+
height: 32,
|
|
1565
|
+
borderRadius: 10,
|
|
1566
|
+
cursor: "pointer",
|
|
1567
|
+
display: "flex",
|
|
1568
|
+
alignItems: "center",
|
|
1569
|
+
justifyContent: "center"
|
|
1570
|
+
},
|
|
1571
|
+
children: expanded ? /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1572
|
+
/* @__PURE__ */ jsx("polyline", { points: "9 4 4 4 4 9" }),
|
|
1573
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 4 20 4 20 9" }),
|
|
1574
|
+
/* @__PURE__ */ jsx("polyline", { points: "4 15 4 20 9 20" }),
|
|
1575
|
+
/* @__PURE__ */ jsx("polyline", { points: "20 15 20 20 15 20" })
|
|
1576
|
+
] }) : /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1577
|
+
/* @__PURE__ */ jsx("polyline", { points: "3 9 3 3 9 3" }),
|
|
1578
|
+
/* @__PURE__ */ jsx("polyline", { points: "21 9 21 3 15 3" }),
|
|
1579
|
+
/* @__PURE__ */ jsx("polyline", { points: "3 15 3 21 9 21" }),
|
|
1580
|
+
/* @__PURE__ */ jsx("polyline", { points: "21 15 21 21 15 21" })
|
|
1581
|
+
] })
|
|
1582
|
+
}
|
|
1583
|
+
),
|
|
1584
|
+
/* @__PURE__ */ jsx(
|
|
1585
|
+
"button",
|
|
1586
|
+
{
|
|
1587
|
+
className: "chatbotlite-close",
|
|
1588
|
+
onClick: () => setOpen(false),
|
|
1589
|
+
"aria-label": "Close chat",
|
|
1590
|
+
style: {
|
|
1591
|
+
background: "transparent",
|
|
1592
|
+
border: "none",
|
|
1593
|
+
color: TEXT_MUTED,
|
|
1594
|
+
width: 32,
|
|
1595
|
+
height: 32,
|
|
1596
|
+
borderRadius: 10,
|
|
1597
|
+
fontSize: 22,
|
|
1598
|
+
lineHeight: 1,
|
|
1599
|
+
cursor: "pointer",
|
|
1600
|
+
display: "flex",
|
|
1601
|
+
alignItems: "center",
|
|
1602
|
+
justifyContent: "center"
|
|
1603
|
+
},
|
|
1604
|
+
children: "\xD7"
|
|
1605
|
+
}
|
|
1606
|
+
)
|
|
1607
|
+
] })
|
|
1518
1608
|
] }),
|
|
1519
1609
|
/* @__PURE__ */ jsxs(
|
|
1520
1610
|
"div",
|