sagedesk 1.0.0 → 2.0.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 +277 -35
- package/dist/next/{SageDeskWidget-P3H2VJR5.js → SageDeskWidget-R3XJ5OUY.js} +149 -25
- package/dist/next/SageDeskWidget-R3XJ5OUY.js.map +1 -0
- package/dist/next/index.cjs +164 -27
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +10 -3
- package/dist/next/index.d.ts +10 -3
- package/dist/next/index.js +10 -4
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +148 -24
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +14 -5
- package/dist/react/index.d.ts +14 -5
- package/dist/react/index.js +148 -24
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +348 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +62 -0
- package/dist/server/index.d.ts +62 -0
- package/dist/server/index.js +312 -0
- package/dist/server/index.js.map +1 -0
- package/dist/vanilla/index.cjs +6 -2
- package/dist/vanilla/index.cjs.map +1 -1
- package/dist/vanilla/index.d.cts +4 -2
- package/dist/vanilla/index.d.ts +4 -2
- package/dist/vanilla/index.js +6 -2
- package/dist/vanilla/index.js.map +1 -1
- package/package.json +10 -3
- package/dist/next/SageDeskWidget-P3H2VJR5.js.map +0 -1
package/dist/next/index.cjs
CHANGED
|
@@ -275,6 +275,17 @@ var init_fallback = __esm({
|
|
|
275
275
|
});
|
|
276
276
|
|
|
277
277
|
// src/react/useSageDesk.ts
|
|
278
|
+
function logFallbackWarning(reason) {
|
|
279
|
+
if (!reason) return;
|
|
280
|
+
const messages = {
|
|
281
|
+
"auth-error": "[sagedesk] Support service authentication failed. Showing relevant knowledge instead.",
|
|
282
|
+
"quota-exceeded": "[sagedesk] Support service quota exhausted. Showing relevant knowledge instead.",
|
|
283
|
+
"timeout": "[sagedesk] Support service took too long to respond. Showing relevant knowledge instead.",
|
|
284
|
+
"api-error": "[sagedesk] Support service error. Showing relevant knowledge instead.",
|
|
285
|
+
"malformed-response": "[sagedesk] Support service returned invalid response. Showing relevant knowledge instead."
|
|
286
|
+
};
|
|
287
|
+
console.warn(messages[reason] || "[sagedesk] Support service unavailable. Showing relevant knowledge instead.");
|
|
288
|
+
}
|
|
278
289
|
function reducer(state, action) {
|
|
279
290
|
switch (action.type) {
|
|
280
291
|
case "OPEN":
|
|
@@ -319,6 +330,11 @@ function useSageDesk(config) {
|
|
|
319
330
|
const startEngine = (0, import_react.useCallback)(async () => {
|
|
320
331
|
if (engineStartedRef.current) return;
|
|
321
332
|
engineStartedRef.current = true;
|
|
333
|
+
if (config.mode === "llm") {
|
|
334
|
+
setChips(config.agent.suggestedChips ?? []);
|
|
335
|
+
dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
322
338
|
dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "loading-index" } });
|
|
323
339
|
try {
|
|
324
340
|
indexRef.current = await fetchIndex(config.indexUrl);
|
|
@@ -345,7 +361,7 @@ function useSageDesk(config) {
|
|
|
345
361
|
embedderRef.current = new EmbedderRuntime();
|
|
346
362
|
dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "degraded" } });
|
|
347
363
|
}
|
|
348
|
-
}, [config.indexUrl, config.agent.suggestedChips, addMessage]);
|
|
364
|
+
}, [config.mode, config.indexUrl, config.agent.suggestedChips, addMessage]);
|
|
349
365
|
const greetingShownRef = (0, import_react.useRef)(false);
|
|
350
366
|
const open = (0, import_react.useCallback)(() => {
|
|
351
367
|
dispatch({ type: "OPEN" });
|
|
@@ -388,8 +404,37 @@ function useSageDesk(config) {
|
|
|
388
404
|
}
|
|
389
405
|
let botText;
|
|
390
406
|
let isFallback = false;
|
|
391
|
-
let
|
|
392
|
-
|
|
407
|
+
let fallbackReason;
|
|
408
|
+
let retrievalMode = "keyword";
|
|
409
|
+
if (config.mode === "llm") {
|
|
410
|
+
if (!config.endpoint) {
|
|
411
|
+
console.warn('[sagedesk] LLM mode requires an "endpoint" prop.');
|
|
412
|
+
botText = getFallback(config.agent);
|
|
413
|
+
isFallback = true;
|
|
414
|
+
} else {
|
|
415
|
+
try {
|
|
416
|
+
const res = await fetch(config.endpoint, {
|
|
417
|
+
method: "POST",
|
|
418
|
+
headers: { "Content-Type": "application/json" },
|
|
419
|
+
body: JSON.stringify({ query: trimmed })
|
|
420
|
+
});
|
|
421
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
422
|
+
const data = await res.json();
|
|
423
|
+
if (data.isFallback || !data.answer) {
|
|
424
|
+
fallbackReason = data.fallbackReason;
|
|
425
|
+
logFallbackWarning(fallbackReason);
|
|
426
|
+
botText = getFallback(config.agent);
|
|
427
|
+
isFallback = true;
|
|
428
|
+
} else {
|
|
429
|
+
botText = data.answer;
|
|
430
|
+
}
|
|
431
|
+
} catch (err) {
|
|
432
|
+
console.warn("[sagedesk] Support service unavailable. Using cached knowledge instead.");
|
|
433
|
+
botText = getFallback(config.agent);
|
|
434
|
+
isFallback = true;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
} else if (!indexRef.current) {
|
|
393
438
|
botText = getFallback(config.agent);
|
|
394
439
|
isFallback = true;
|
|
395
440
|
} else {
|
|
@@ -400,7 +445,7 @@ function useSageDesk(config) {
|
|
|
400
445
|
embedderRef.current,
|
|
401
446
|
config.search
|
|
402
447
|
);
|
|
403
|
-
|
|
448
|
+
retrievalMode = res.mode;
|
|
404
449
|
if (res.results.length > 0) {
|
|
405
450
|
botText = buildAnswer(res.results);
|
|
406
451
|
} else {
|
|
@@ -413,11 +458,13 @@ function useSageDesk(config) {
|
|
|
413
458
|
isFallback = true;
|
|
414
459
|
}
|
|
415
460
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
461
|
+
if (config.mode !== "llm") {
|
|
462
|
+
const elapsed = Date.now() - typingStart;
|
|
463
|
+
const delayBase = retrievalMode === "keyword" || isFallback ? 800 : 3e3;
|
|
464
|
+
const minTypingMs = delayBase + Math.random() * 2e3;
|
|
465
|
+
const remaining = minTypingMs - elapsed;
|
|
466
|
+
if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
|
|
467
|
+
}
|
|
421
468
|
dispatch({ type: "SET_TYPING", payload: false });
|
|
422
469
|
addMessage({ role: "bot", text: botText, isFallback });
|
|
423
470
|
},
|
|
@@ -460,6 +507,60 @@ var init_useSageDesk = __esm({
|
|
|
460
507
|
}
|
|
461
508
|
});
|
|
462
509
|
|
|
510
|
+
// src/react/markdownUtils.ts
|
|
511
|
+
function parseMarkdown(markdown) {
|
|
512
|
+
const html = import_marked.marked.parse(markdown);
|
|
513
|
+
const sanitized = import_dompurify.default.sanitize(html, PURIFY_CONFIG);
|
|
514
|
+
return sanitized;
|
|
515
|
+
}
|
|
516
|
+
var import_marked, import_dompurify, PURIFY_CONFIG, HOOK_ALLOWLIST;
|
|
517
|
+
var init_markdownUtils = __esm({
|
|
518
|
+
"src/react/markdownUtils.ts"() {
|
|
519
|
+
"use strict";
|
|
520
|
+
import_marked = require("marked");
|
|
521
|
+
import_dompurify = __toESM(require("dompurify"), 1);
|
|
522
|
+
import_marked.marked.setOptions({
|
|
523
|
+
breaks: true,
|
|
524
|
+
gfm: true,
|
|
525
|
+
pedantic: false
|
|
526
|
+
});
|
|
527
|
+
PURIFY_CONFIG = {
|
|
528
|
+
ALLOWED_TAGS: [
|
|
529
|
+
"p",
|
|
530
|
+
"br",
|
|
531
|
+
"strong",
|
|
532
|
+
"em",
|
|
533
|
+
"u",
|
|
534
|
+
"h1",
|
|
535
|
+
"h2",
|
|
536
|
+
"h3",
|
|
537
|
+
"h4",
|
|
538
|
+
"h5",
|
|
539
|
+
"h6",
|
|
540
|
+
"ul",
|
|
541
|
+
"ol",
|
|
542
|
+
"li",
|
|
543
|
+
"blockquote",
|
|
544
|
+
"code",
|
|
545
|
+
"pre",
|
|
546
|
+
"a",
|
|
547
|
+
"hr"
|
|
548
|
+
],
|
|
549
|
+
ALLOWED_ATTR: ["href", "title", "target", "rel"],
|
|
550
|
+
ALLOW_DATA_ATTR: false
|
|
551
|
+
};
|
|
552
|
+
HOOK_ALLOWLIST = ["a"];
|
|
553
|
+
import_dompurify.default.addHook("afterSanitizeAttributes", (node) => {
|
|
554
|
+
if (HOOK_ALLOWLIST.includes(node.tagName.toLowerCase())) {
|
|
555
|
+
if (node.tagName.toLowerCase() === "a") {
|
|
556
|
+
node.setAttribute("target", "_blank");
|
|
557
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
|
|
463
564
|
// src/react/SageDeskWidget.tsx
|
|
464
565
|
var SageDeskWidget_exports = {};
|
|
465
566
|
__export(SageDeskWidget_exports, {
|
|
@@ -476,6 +577,7 @@ function injectStyles(theme) {
|
|
|
476
577
|
}
|
|
477
578
|
function ClassicMessageBubble({ msg, accent }) {
|
|
478
579
|
const isBot = msg.role === "bot";
|
|
580
|
+
const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
|
|
479
581
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: isBot ? "flex-start" : "flex-end", gap: "4px" }, children: [
|
|
480
582
|
msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", fontWeight: 500, color: "#9b9aa3", margin: 0, padding: "0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
|
|
481
583
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
@@ -488,10 +590,9 @@ function ClassicMessageBubble({ msg, accent }) {
|
|
|
488
590
|
color: isBot ? "#1a1a2e" : "#fff",
|
|
489
591
|
border: isBot ? "1px solid rgba(20,20,40,0.06)" : "none",
|
|
490
592
|
boxShadow: isBot ? "0 1px 2px rgba(20,20,40,0.04)" : `0 6px 16px -6px color-mix(in oklab, ${accent} 60%, transparent)`,
|
|
491
|
-
whiteSpace: "pre-wrap",
|
|
492
593
|
wordBreak: "break-word",
|
|
493
594
|
fontFamily: "inherit"
|
|
494
|
-
}, children: msg.text }),
|
|
595
|
+
}, className: "sd-r-markdown", children: isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text }) }),
|
|
495
596
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
|
|
496
597
|
fontSize: "11px",
|
|
497
598
|
color: "#a8a8b0",
|
|
@@ -521,6 +622,7 @@ function ClassicTypingIndicator() {
|
|
|
521
622
|
}
|
|
522
623
|
function LightMessageBubble({ msg, accent, agentName }) {
|
|
523
624
|
const isBot = msg.role === "bot";
|
|
625
|
+
const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
|
|
524
626
|
if (isBot) {
|
|
525
627
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
|
|
526
628
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
|
|
@@ -537,7 +639,7 @@ function LightMessageBubble({ msg, accent, agentName }) {
|
|
|
537
639
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "#a8a89e", fontVariantNumeric: "tabular-nums", fontFamily: "inherit" }, children: "just now" })
|
|
538
640
|
] }),
|
|
539
641
|
msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", color: "#9b9aa3", margin: "0 0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
|
|
540
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: "14px", lineHeight: 1.55, color: "#2a2a36", fontFamily: "inherit",
|
|
642
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: "14px", lineHeight: 1.55, color: "#2a2a36", fontFamily: "inherit", wordBreak: "break-word" }, className: "sd-r-markdown", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) })
|
|
541
643
|
] })
|
|
542
644
|
] });
|
|
543
645
|
}
|
|
@@ -585,6 +687,7 @@ function LightTypingIndicator({ accent }) {
|
|
|
585
687
|
}
|
|
586
688
|
function DarkMessageBubble({ msg, accent }) {
|
|
587
689
|
const isBot = msg.role === "bot";
|
|
690
|
+
const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
|
|
588
691
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
|
|
589
692
|
maxWidth: "85%",
|
|
590
693
|
padding: "12px 14px",
|
|
@@ -596,12 +699,11 @@ function DarkMessageBubble({ msg, accent }) {
|
|
|
596
699
|
color: isBot ? "rgba(255,255,255,0.92)" : "#fff",
|
|
597
700
|
alignSelf: isBot ? "flex-start" : "flex-end",
|
|
598
701
|
boxShadow: isBot ? "none" : `0 8px 20px -8px color-mix(in oklab, ${accent} 70%, transparent)`,
|
|
599
|
-
whiteSpace: "pre-wrap",
|
|
600
702
|
wordBreak: "break-word",
|
|
601
703
|
fontFamily: "inherit"
|
|
602
|
-
}, children: [
|
|
704
|
+
}, className: isBot ? "sd-r-markdown" : "", children: [
|
|
603
705
|
msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "rgba(255,255,255,0.5)", display: "block", marginBottom: "4px" }, children: "Not sure about that one" }),
|
|
604
|
-
msg.text
|
|
706
|
+
isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text })
|
|
605
707
|
] });
|
|
606
708
|
}
|
|
607
709
|
function DarkTypingIndicator() {
|
|
@@ -1221,16 +1323,22 @@ function renderDark(p) {
|
|
|
1221
1323
|
] })
|
|
1222
1324
|
] });
|
|
1223
1325
|
}
|
|
1224
|
-
function SageDeskWidget({ indexUrl, agent, search: search2 }) {
|
|
1225
|
-
|
|
1326
|
+
function SageDeskWidget({ mode, indexUrl, endpoint, agent, search: search2 }) {
|
|
1327
|
+
const resolvedMode = mode ?? "local";
|
|
1328
|
+
if (!agent?.name) {
|
|
1329
|
+
throw new Error('[sagedesk] Required prop "agent.name" is missing.');
|
|
1330
|
+
}
|
|
1331
|
+
if (resolvedMode === "local" && !indexUrl) {
|
|
1226
1332
|
throw new Error(
|
|
1227
|
-
'[sagedesk] Required prop "indexUrl" is missing. Run `npx sagedesk build` and pass the output path, e.g. indexUrl="/support-index.json".'
|
|
1333
|
+
'[sagedesk] Required prop "indexUrl" is missing for local mode. Run `npx sagedesk build` and pass the output path, e.g. indexUrl="/support-index.json".'
|
|
1228
1334
|
);
|
|
1229
1335
|
}
|
|
1230
|
-
if (!
|
|
1231
|
-
throw new Error(
|
|
1336
|
+
if (resolvedMode === "llm" && !endpoint) {
|
|
1337
|
+
throw new Error(
|
|
1338
|
+
'[sagedesk] Required prop "endpoint" is missing for llm mode. Provide your backend route, e.g. endpoint="/api/sagedesk".'
|
|
1339
|
+
);
|
|
1232
1340
|
}
|
|
1233
|
-
const config = { indexUrl, agent, search: search2 };
|
|
1341
|
+
const config = { mode: resolvedMode, indexUrl, endpoint, agent, search: search2 };
|
|
1234
1342
|
const { state, chips, open, close, submit } = useSageDesk(config);
|
|
1235
1343
|
const theme = agent.theme ?? "classic";
|
|
1236
1344
|
const accent = agent.accentColor ?? "#534AB7";
|
|
@@ -1243,7 +1351,7 @@ function SageDeskWidget({ indexUrl, agent, search: search2 }) {
|
|
|
1243
1351
|
const triggerRef = (0, import_react2.useRef)(null);
|
|
1244
1352
|
const [mounted, setMounted] = (0, import_react2.useState)(false);
|
|
1245
1353
|
(0, import_react2.useEffect)(() => {
|
|
1246
|
-
if (!indexUrl.startsWith("/") && !indexUrl.startsWith("http")) {
|
|
1354
|
+
if (resolvedMode === "local" && indexUrl && !indexUrl.startsWith("/") && !indexUrl.startsWith("http")) {
|
|
1247
1355
|
console.warn(
|
|
1248
1356
|
`[sagedesk] indexUrl "${indexUrl}" looks like a relative path. It should start with "/" so it resolves correctly from any page.`
|
|
1249
1357
|
);
|
|
@@ -1285,7 +1393,7 @@ function SageDeskWidget({ indexUrl, agent, search: search2 }) {
|
|
|
1285
1393
|
[handleSubmit]
|
|
1286
1394
|
);
|
|
1287
1395
|
if (!mounted || typeof document === "undefined") return null;
|
|
1288
|
-
const showPoweredBy =
|
|
1396
|
+
const showPoweredBy = true;
|
|
1289
1397
|
const showChips = chips.length > 0;
|
|
1290
1398
|
const panelClass = isClosing ? "sd-r-closing" : state.isOpen ? "sd-r-opening" : "";
|
|
1291
1399
|
const props = {
|
|
@@ -1319,6 +1427,7 @@ var init_SageDeskWidget = __esm({
|
|
|
1319
1427
|
import_react2 = require("react");
|
|
1320
1428
|
import_react_dom = require("react-dom");
|
|
1321
1429
|
init_useSageDesk();
|
|
1430
|
+
init_markdownUtils();
|
|
1322
1431
|
import_jsx_runtime = require("react/jsx-runtime");
|
|
1323
1432
|
STYLE_ID = "sagedesk-widget-styles";
|
|
1324
1433
|
SHARED = `
|
|
@@ -1347,6 +1456,28 @@ var init_SageDeskWidget = __esm({
|
|
|
1347
1456
|
}
|
|
1348
1457
|
.sd-r-scrollable::-webkit-scrollbar { display: none !important; }
|
|
1349
1458
|
.sd-r-scrollable > * { flex-shrink: 0 !important; }
|
|
1459
|
+
.sd-r-markdown h1, .sd-r-markdown h2, .sd-r-markdown h3, .sd-r-markdown h4, .sd-r-markdown h5, .sd-r-markdown h6 {
|
|
1460
|
+
margin: 12px 0 8px 0 !important; font-weight: 600 !important; line-height: 1.3 !important;
|
|
1461
|
+
}
|
|
1462
|
+
.sd-r-markdown h1 { font-size: 1.3em !important; }
|
|
1463
|
+
.sd-r-markdown h2 { font-size: 1.2em !important; }
|
|
1464
|
+
.sd-r-markdown h3 { font-size: 1.1em !important; }
|
|
1465
|
+
.sd-r-markdown h4, .sd-r-markdown h5, .sd-r-markdown h6 { font-size: 1em !important; }
|
|
1466
|
+
.sd-r-markdown strong { font-weight: 600 !important; }
|
|
1467
|
+
.sd-r-markdown em { font-style: italic !important; }
|
|
1468
|
+
.sd-r-markdown u { text-decoration: underline !important; }
|
|
1469
|
+
.sd-r-markdown ul, .sd-r-markdown ol { margin: 8px 0 !important; padding-left: 20px !important; }
|
|
1470
|
+
.sd-r-markdown li { margin: 4px 0 !important; }
|
|
1471
|
+
.sd-r-markdown blockquote { margin: 8px 0 !important; padding-left: 12px !important; border-left: 3px solid currentColor !important; opacity: 0.8 !important; }
|
|
1472
|
+
.sd-r-markdown code { font-family: 'Monaco', 'Courier New', monospace !important; font-size: 0.9em !important; padding: 2px 4px !important; background: rgba(0,0,0,0.05) !important; border-radius: 3px !important; }
|
|
1473
|
+
.sd-r-markdown pre { background: rgba(0,0,0,0.05) !important; padding: 8px 10px !important; border-radius: 6px !important; overflow-x: auto !important; margin: 8px 0 !important; }
|
|
1474
|
+
.sd-r-markdown pre code { background: none !important; padding: 0 !important; }
|
|
1475
|
+
.sd-r-markdown hr { border: none !important; border-top: 1px solid currentColor !important; opacity: 0.3 !important; margin: 10px 0 !important; }
|
|
1476
|
+
.sd-r-markdown a { text-decoration: underline !important; opacity: 0.9 !important; }
|
|
1477
|
+
.sd-r-markdown a:hover { opacity: 1 !important; }
|
|
1478
|
+
.sd-r-markdown p { margin: 6px 0 !important; }
|
|
1479
|
+
.sd-r-markdown > *:first-child { margin-top: 0 !important; }
|
|
1480
|
+
.sd-r-markdown > *:last-child { margin-bottom: 0 !important; }
|
|
1350
1481
|
@media (max-width: 420px) {
|
|
1351
1482
|
.sd-r-panel {
|
|
1352
1483
|
bottom: 0 !important; right: 0 !important; left: 0 !important;
|
|
@@ -1424,7 +1555,7 @@ var init_SageDeskWidget = __esm({
|
|
|
1424
1555
|
{
|
|
1425
1556
|
href: "https://github.com/mzeeshanwahid/sagedesk",
|
|
1426
1557
|
target: "_blank",
|
|
1427
|
-
rel: "noopener
|
|
1558
|
+
rel: "noopener",
|
|
1428
1559
|
style: {
|
|
1429
1560
|
color: dark ? "rgba(255,255,255,0.7)" : "#5a5a64",
|
|
1430
1561
|
fontWeight: 500,
|
|
@@ -1457,17 +1588,23 @@ var LazyWidget = (0, import_react3.lazy)(
|
|
|
1457
1588
|
function SageDeskNext(props) {
|
|
1458
1589
|
const [mounted, setMounted] = (0, import_react3.useState)(false);
|
|
1459
1590
|
(0, import_react3.useEffect)(() => {
|
|
1460
|
-
|
|
1591
|
+
const mode = props.mode ?? "local";
|
|
1592
|
+
if (mode === "local" && !props.indexUrl) {
|
|
1461
1593
|
console.warn(
|
|
1462
1594
|
'[sagedesk] Missing required prop: indexUrl. The widget will not load.\nMake sure you ran `npx sagedesk build` and are passing indexUrl="/support-index.json" (or wherever you placed the output file in public/).'
|
|
1463
1595
|
);
|
|
1464
|
-
} else if (
|
|
1596
|
+
} else if (mode === "llm" && !props.endpoint) {
|
|
1597
|
+
console.warn(
|
|
1598
|
+
'[sagedesk] Missing required prop: endpoint for LLM mode. The widget will not load.\nProvide your backend route, e.g. endpoint="/api/sagedesk".'
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
if (props.indexUrl && !props.indexUrl.startsWith("/") && !props.indexUrl.startsWith("http")) {
|
|
1465
1602
|
console.warn(
|
|
1466
1603
|
`[sagedesk] indexUrl "${props.indexUrl}" looks like a relative path. It should start with "/" (e.g. "/support-index.json") so it resolves correctly from any page.`
|
|
1467
1604
|
);
|
|
1468
1605
|
}
|
|
1469
1606
|
setMounted(true);
|
|
1470
|
-
}, []);
|
|
1607
|
+
}, [props.mode, props.indexUrl, props.endpoint]);
|
|
1471
1608
|
if (!mounted) return null;
|
|
1472
1609
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LazyWidget, { ...props }) });
|
|
1473
1610
|
}
|