@retrivora-ai/rag-engine 1.7.0 → 1.7.2
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/{chunk-OHXRQTQH.mjs → chunk-M32ZXLTT.mjs} +399 -20
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +402 -22
- package/dist/handlers/index.mjs +5 -3
- package/dist/{index-kUXnRvuI.d.mts → index-BejNscWZ.d.mts} +4 -2
- package/dist/{index-B67KQ9NN.d.ts → index-CbkMJvu5.d.ts} +4 -2
- package/dist/index.js +29 -32
- package/dist/index.mjs +29 -32
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +400 -20
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/components/MessageBubble.tsx +43 -55
- package/src/components/VisualizationRenderer.tsx +341 -0
- package/src/core/Pipeline.ts +39 -19
- package/src/handlers/index.ts +21 -3
- package/src/hooks/useUITransform.ts +54 -0
- package/src/utils/UITransformer.ts +535 -0
package/dist/index.js
CHANGED
|
@@ -405,7 +405,7 @@ function sanitizeJson(raw) {
|
|
|
405
405
|
return `: ${result}`;
|
|
406
406
|
}
|
|
407
407
|
);
|
|
408
|
-
s = s.replace(
|
|
408
|
+
s = s.replace(/\/\/[^\n]*/g, "");
|
|
409
409
|
s = s.replace(/([{,]\s*)([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g, '$1"$2":');
|
|
410
410
|
s = s.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'/g, '"$1"');
|
|
411
411
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
@@ -456,7 +456,7 @@ function extractLikelyJsonBlock(raw) {
|
|
|
456
456
|
return trimmed.slice(Math.min(...starts));
|
|
457
457
|
}
|
|
458
458
|
function looksLikeStructuredPayload(raw) {
|
|
459
|
-
return /"?(view|chartType|type|data|items|rows|products|results
|
|
459
|
+
return /"?(view|chartType|type|data|items|rows|products|results)"?\s*:/.test(raw);
|
|
460
460
|
}
|
|
461
461
|
function stripMarkdownTables(raw) {
|
|
462
462
|
return raw.replace(
|
|
@@ -535,23 +535,12 @@ function isLikelyUiOnlyMessage(text) {
|
|
|
535
535
|
return trimmed.length === 0 || /^(chart data|table data|visualization|visual representation|product catalog|product recommendations|catalog summary)\s*:?\s*$/i.test(trimmed);
|
|
536
536
|
}
|
|
537
537
|
function resolveImage(data) {
|
|
538
|
-
const
|
|
539
|
-
for (const key of candidates) {
|
|
538
|
+
for (const key of ["image", "img", "thumbnail"]) {
|
|
540
539
|
const v = data[key];
|
|
541
|
-
if (typeof v === "string" && v
|
|
542
|
-
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
543
|
-
const subVal = v.url || v.link || v.src;
|
|
544
|
-
if (typeof subVal === "string" && subVal.startsWith("http")) return subVal;
|
|
545
|
-
}
|
|
540
|
+
if (typeof v === "string" && v) return v;
|
|
546
541
|
}
|
|
547
|
-
if (Array.isArray(data.images)) {
|
|
548
|
-
|
|
549
|
-
if (typeof item === "string" && item.startsWith("http")) return item;
|
|
550
|
-
if (item && typeof item === "object") {
|
|
551
|
-
const url = item.url || item.link || item.src;
|
|
552
|
-
if (typeof url === "string" && url.startsWith("http")) return url;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
542
|
+
if (Array.isArray(data.images) && typeof data.images[0] === "string") {
|
|
543
|
+
return data.images[0];
|
|
555
544
|
}
|
|
556
545
|
return void 0;
|
|
557
546
|
}
|
|
@@ -654,13 +643,10 @@ function resolveStructuredRows(config) {
|
|
|
654
643
|
if (Array.isArray(config.results) && config.results.length > 0) return config.results;
|
|
655
644
|
return [];
|
|
656
645
|
}
|
|
657
|
-
function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, viewportSize = "large" }) {
|
|
646
|
+
function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAddToCart, viewportSize = "large" }) {
|
|
658
647
|
var _a;
|
|
659
648
|
const result = import_react5.default.useMemo(() => {
|
|
660
|
-
if (isStreaming) {
|
|
661
|
-
const looksLikeCarousel = rawContent.includes('"view": "carousel"') || rawContent.includes('"view":"carousel"') || rawContent.includes('"type": "products"') || rawContent.includes('"type":"products"');
|
|
662
|
-
return { loading: true, silent: looksLikeCarousel };
|
|
663
|
-
}
|
|
649
|
+
if (isStreaming) return { loading: true };
|
|
664
650
|
try {
|
|
665
651
|
const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
|
|
666
652
|
const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
|
|
@@ -693,7 +679,6 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, view
|
|
|
693
679
|
}
|
|
694
680
|
}, [rawContent, isStreaming]);
|
|
695
681
|
if ("loading" in result) {
|
|
696
|
-
if (result.silent) return null;
|
|
697
682
|
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "my-4 p-8 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex flex-col items-center justify-center gap-3 animate-pulse" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-5 h-5 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ import_react5.default.createElement("p", { className: "text-xs text-slate-500 font-medium italic" }, "Preparing view..."));
|
|
698
683
|
}
|
|
699
684
|
if ("error" in result) {
|
|
@@ -728,7 +713,12 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, view
|
|
|
728
713
|
insight
|
|
729
714
|
))));
|
|
730
715
|
case "carousel":
|
|
731
|
-
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ import_react5.default.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ import_react5.default.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description))
|
|
716
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ import_react5.default.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ import_react5.default.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ import_react5.default.createElement(ProductCarousel, { products: config.data.map((item) => {
|
|
717
|
+
var _a2;
|
|
718
|
+
return __spreadProps(__spreadValues({}, item), {
|
|
719
|
+
image: (_a2 = item.image) != null ? _a2 : typeof resolveImage === "function" ? resolveImage(item) : void 0
|
|
720
|
+
});
|
|
721
|
+
}), primaryColor, onAddToCart }));
|
|
732
722
|
case "table":
|
|
733
723
|
return /* @__PURE__ */ import_react5.default.createElement("div", { className: `${isCompact ? "my-3 p-3 max-h-[320px]" : "my-4 p-4 max-h-[400px]"} bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-auto` }, config.title && /* @__PURE__ */ import_react5.default.createElement("h4", { className: `${isCompact ? "text-[11px]" : "text-xs"} font-semibold text-slate-500 mb-2` }, config.title), hasDescription && /* @__PURE__ */ import_react5.default.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ import_react5.default.createElement(DataTable, { config: {
|
|
734
724
|
type: "table",
|
|
@@ -756,6 +746,10 @@ function MessageBubble({
|
|
|
756
746
|
const isCompact = viewportSize === "compact";
|
|
757
747
|
const isMedium = viewportSize === "medium";
|
|
758
748
|
const [showSources, setShowSources] = import_react5.default.useState(false);
|
|
749
|
+
const hasStructuredProductBlock = import_react5.default.useMemo(
|
|
750
|
+
() => /```(?:ui|json|chart)\s*[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products|table)"?/i.test(message.content) || /\{[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products)"?[\s\S]*\}/i.test(message.content) && looksLikeStructuredPayload(message.content),
|
|
751
|
+
[message.content]
|
|
752
|
+
);
|
|
759
753
|
const structuredContent = import_react5.default.useMemo(
|
|
760
754
|
() => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
|
|
761
755
|
[isUser, message.content]
|
|
@@ -847,16 +841,15 @@ function MessageBubble({
|
|
|
847
841
|
let raw = structuredContent.payload ? structuredContent.text : cleanContent || message.content;
|
|
848
842
|
const hasStructuredUiBlock = Boolean(structuredContent.payload) || /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
|
|
849
843
|
raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
|
|
850
|
-
if (!isStreaming
|
|
851
|
-
raw = raw.replace(/(?:^|\n)\s
|
|
844
|
+
if (!isStreaming) {
|
|
845
|
+
raw = raw.replace(/(?:^|\n)\s*\{[\s\S]*\}\s*(?:\n|$)/g, (match) => {
|
|
852
846
|
if (match.includes("```")) return match;
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
const type = trimmedBody.includes('"view"') || trimmedBody.includes('"chartType"') || trimmedBody.includes('"type"') || trimmedBody.includes('"xAxisKey"') ? "ui" : "json";
|
|
847
|
+
if (!looksLikeStructuredPayload(match)) return match;
|
|
848
|
+
const type = match.includes('"view"') || match.includes('"chartType"') || match.includes('"type": "pie"') || match.includes('"type":"pie"') || match.includes('"type": "bar"') || match.includes('"type":"bar"') || match.includes('"type": "line"') || match.includes('"type":"line"') ? "ui" : "json";
|
|
856
849
|
return `
|
|
857
850
|
|
|
858
851
|
\`\`\`${type}
|
|
859
|
-
${
|
|
852
|
+
${match.trim()}
|
|
860
853
|
\`\`\`
|
|
861
854
|
|
|
862
855
|
`;
|
|
@@ -956,6 +949,7 @@ ${match.trim()}
|
|
|
956
949
|
primaryColor,
|
|
957
950
|
accentColor,
|
|
958
951
|
isStreaming,
|
|
952
|
+
onAddToCart,
|
|
959
953
|
viewportSize
|
|
960
954
|
}
|
|
961
955
|
);
|
|
@@ -970,6 +964,7 @@ ${match.trim()}
|
|
|
970
964
|
primaryColor,
|
|
971
965
|
accentColor,
|
|
972
966
|
isStreaming,
|
|
967
|
+
onAddToCart,
|
|
973
968
|
viewportSize
|
|
974
969
|
}
|
|
975
970
|
);
|
|
@@ -985,6 +980,7 @@ ${match.trim()}
|
|
|
985
980
|
primaryColor,
|
|
986
981
|
accentColor,
|
|
987
982
|
isStreaming,
|
|
983
|
+
onAddToCart,
|
|
988
984
|
viewportSize
|
|
989
985
|
}
|
|
990
986
|
);
|
|
@@ -996,7 +992,7 @@ ${match.trim()}
|
|
|
996
992
|
return /* @__PURE__ */ import_react5.default.createElement("code", __spreadValues({ className }, props), typeof children === "string" || typeof children === "number" ? children : JSON.stringify(children));
|
|
997
993
|
}
|
|
998
994
|
}),
|
|
999
|
-
[primaryColor, accentColor, isStreaming, viewportSize]
|
|
995
|
+
[primaryColor, accentColor, isStreaming, onAddToCart, viewportSize]
|
|
1000
996
|
);
|
|
1001
997
|
return /* @__PURE__ */ import_react5.default.createElement("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react5.default.createElement(
|
|
1002
998
|
"div",
|
|
@@ -1018,10 +1014,11 @@ ${match.trim()}
|
|
|
1018
1014
|
primaryColor,
|
|
1019
1015
|
accentColor,
|
|
1020
1016
|
isStreaming,
|
|
1017
|
+
onAddToCart,
|
|
1021
1018
|
viewportSize
|
|
1022
1019
|
}
|
|
1023
1020
|
), !shouldRenderStructuredOnly && /* @__PURE__ */ import_react5.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], components: markdownComponents }, processedMarkdown), isStreaming && message.content && /* @__PURE__ */ import_react5.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
1024
|
-
), !isUser && allProducts.length > 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
1021
|
+
), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
1025
1022
|
ProductCarousel,
|
|
1026
1023
|
{
|
|
1027
1024
|
products: allProducts,
|
package/dist/index.mjs
CHANGED
|
@@ -368,7 +368,7 @@ function sanitizeJson(raw) {
|
|
|
368
368
|
return `: ${result}`;
|
|
369
369
|
}
|
|
370
370
|
);
|
|
371
|
-
s = s.replace(
|
|
371
|
+
s = s.replace(/\/\/[^\n]*/g, "");
|
|
372
372
|
s = s.replace(/([{,]\s*)([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g, '$1"$2":');
|
|
373
373
|
s = s.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'/g, '"$1"');
|
|
374
374
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
@@ -419,7 +419,7 @@ function extractLikelyJsonBlock(raw) {
|
|
|
419
419
|
return trimmed.slice(Math.min(...starts));
|
|
420
420
|
}
|
|
421
421
|
function looksLikeStructuredPayload(raw) {
|
|
422
|
-
return /"?(view|chartType|type|data|items|rows|products|results
|
|
422
|
+
return /"?(view|chartType|type|data|items|rows|products|results)"?\s*:/.test(raw);
|
|
423
423
|
}
|
|
424
424
|
function stripMarkdownTables(raw) {
|
|
425
425
|
return raw.replace(
|
|
@@ -498,23 +498,12 @@ function isLikelyUiOnlyMessage(text) {
|
|
|
498
498
|
return trimmed.length === 0 || /^(chart data|table data|visualization|visual representation|product catalog|product recommendations|catalog summary)\s*:?\s*$/i.test(trimmed);
|
|
499
499
|
}
|
|
500
500
|
function resolveImage(data) {
|
|
501
|
-
const
|
|
502
|
-
for (const key of candidates) {
|
|
501
|
+
for (const key of ["image", "img", "thumbnail"]) {
|
|
503
502
|
const v = data[key];
|
|
504
|
-
if (typeof v === "string" && v
|
|
505
|
-
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
506
|
-
const subVal = v.url || v.link || v.src;
|
|
507
|
-
if (typeof subVal === "string" && subVal.startsWith("http")) return subVal;
|
|
508
|
-
}
|
|
503
|
+
if (typeof v === "string" && v) return v;
|
|
509
504
|
}
|
|
510
|
-
if (Array.isArray(data.images)) {
|
|
511
|
-
|
|
512
|
-
if (typeof item === "string" && item.startsWith("http")) return item;
|
|
513
|
-
if (item && typeof item === "object") {
|
|
514
|
-
const url = item.url || item.link || item.src;
|
|
515
|
-
if (typeof url === "string" && url.startsWith("http")) return url;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
505
|
+
if (Array.isArray(data.images) && typeof data.images[0] === "string") {
|
|
506
|
+
return data.images[0];
|
|
518
507
|
}
|
|
519
508
|
return void 0;
|
|
520
509
|
}
|
|
@@ -617,13 +606,10 @@ function resolveStructuredRows(config) {
|
|
|
617
606
|
if (Array.isArray(config.results) && config.results.length > 0) return config.results;
|
|
618
607
|
return [];
|
|
619
608
|
}
|
|
620
|
-
function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, viewportSize = "large" }) {
|
|
609
|
+
function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAddToCart, viewportSize = "large" }) {
|
|
621
610
|
var _a;
|
|
622
611
|
const result = React5.useMemo(() => {
|
|
623
|
-
if (isStreaming) {
|
|
624
|
-
const looksLikeCarousel = rawContent.includes('"view": "carousel"') || rawContent.includes('"view":"carousel"') || rawContent.includes('"type": "products"') || rawContent.includes('"type":"products"');
|
|
625
|
-
return { loading: true, silent: looksLikeCarousel };
|
|
626
|
-
}
|
|
612
|
+
if (isStreaming) return { loading: true };
|
|
627
613
|
try {
|
|
628
614
|
const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
|
|
629
615
|
const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
|
|
@@ -656,7 +642,6 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, view
|
|
|
656
642
|
}
|
|
657
643
|
}, [rawContent, isStreaming]);
|
|
658
644
|
if ("loading" in result) {
|
|
659
|
-
if (result.silent) return null;
|
|
660
645
|
return /* @__PURE__ */ React5.createElement("div", { className: "my-4 p-8 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex flex-col items-center justify-center gap-3 animate-pulse" }, /* @__PURE__ */ React5.createElement("div", { className: "w-5 h-5 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React5.createElement("p", { className: "text-xs text-slate-500 font-medium italic" }, "Preparing view..."));
|
|
661
646
|
}
|
|
662
647
|
if ("error" in result) {
|
|
@@ -691,7 +676,12 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, view
|
|
|
691
676
|
insight
|
|
692
677
|
))));
|
|
693
678
|
case "carousel":
|
|
694
|
-
return /* @__PURE__ */ React5.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description))
|
|
679
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React5.createElement(ProductCarousel, { products: config.data.map((item) => {
|
|
680
|
+
var _a2;
|
|
681
|
+
return __spreadProps(__spreadValues({}, item), {
|
|
682
|
+
image: (_a2 = item.image) != null ? _a2 : typeof resolveImage === "function" ? resolveImage(item) : void 0
|
|
683
|
+
});
|
|
684
|
+
}), primaryColor, onAddToCart }));
|
|
695
685
|
case "table":
|
|
696
686
|
return /* @__PURE__ */ React5.createElement("div", { className: `${isCompact ? "my-3 p-3 max-h-[320px]" : "my-4 p-4 max-h-[400px]"} bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-auto` }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "text-[11px]" : "text-xs"} font-semibold text-slate-500 mb-2` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React5.createElement(DataTable, { config: {
|
|
697
687
|
type: "table",
|
|
@@ -719,6 +709,10 @@ function MessageBubble({
|
|
|
719
709
|
const isCompact = viewportSize === "compact";
|
|
720
710
|
const isMedium = viewportSize === "medium";
|
|
721
711
|
const [showSources, setShowSources] = React5.useState(false);
|
|
712
|
+
const hasStructuredProductBlock = React5.useMemo(
|
|
713
|
+
() => /```(?:ui|json|chart)\s*[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products|table)"?/i.test(message.content) || /\{[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products)"?[\s\S]*\}/i.test(message.content) && looksLikeStructuredPayload(message.content),
|
|
714
|
+
[message.content]
|
|
715
|
+
);
|
|
722
716
|
const structuredContent = React5.useMemo(
|
|
723
717
|
() => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
|
|
724
718
|
[isUser, message.content]
|
|
@@ -810,16 +804,15 @@ function MessageBubble({
|
|
|
810
804
|
let raw = structuredContent.payload ? structuredContent.text : cleanContent || message.content;
|
|
811
805
|
const hasStructuredUiBlock = Boolean(structuredContent.payload) || /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
|
|
812
806
|
raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
|
|
813
|
-
if (!isStreaming
|
|
814
|
-
raw = raw.replace(/(?:^|\n)\s
|
|
807
|
+
if (!isStreaming) {
|
|
808
|
+
raw = raw.replace(/(?:^|\n)\s*\{[\s\S]*\}\s*(?:\n|$)/g, (match) => {
|
|
815
809
|
if (match.includes("```")) return match;
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
const type = trimmedBody.includes('"view"') || trimmedBody.includes('"chartType"') || trimmedBody.includes('"type"') || trimmedBody.includes('"xAxisKey"') ? "ui" : "json";
|
|
810
|
+
if (!looksLikeStructuredPayload(match)) return match;
|
|
811
|
+
const type = match.includes('"view"') || match.includes('"chartType"') || match.includes('"type": "pie"') || match.includes('"type":"pie"') || match.includes('"type": "bar"') || match.includes('"type":"bar"') || match.includes('"type": "line"') || match.includes('"type":"line"') ? "ui" : "json";
|
|
819
812
|
return `
|
|
820
813
|
|
|
821
814
|
\`\`\`${type}
|
|
822
|
-
${
|
|
815
|
+
${match.trim()}
|
|
823
816
|
\`\`\`
|
|
824
817
|
|
|
825
818
|
`;
|
|
@@ -919,6 +912,7 @@ ${match.trim()}
|
|
|
919
912
|
primaryColor,
|
|
920
913
|
accentColor,
|
|
921
914
|
isStreaming,
|
|
915
|
+
onAddToCart,
|
|
922
916
|
viewportSize
|
|
923
917
|
}
|
|
924
918
|
);
|
|
@@ -933,6 +927,7 @@ ${match.trim()}
|
|
|
933
927
|
primaryColor,
|
|
934
928
|
accentColor,
|
|
935
929
|
isStreaming,
|
|
930
|
+
onAddToCart,
|
|
936
931
|
viewportSize
|
|
937
932
|
}
|
|
938
933
|
);
|
|
@@ -948,6 +943,7 @@ ${match.trim()}
|
|
|
948
943
|
primaryColor,
|
|
949
944
|
accentColor,
|
|
950
945
|
isStreaming,
|
|
946
|
+
onAddToCart,
|
|
951
947
|
viewportSize
|
|
952
948
|
}
|
|
953
949
|
);
|
|
@@ -959,7 +955,7 @@ ${match.trim()}
|
|
|
959
955
|
return /* @__PURE__ */ React5.createElement("code", __spreadValues({ className }, props), typeof children === "string" || typeof children === "number" ? children : JSON.stringify(children));
|
|
960
956
|
}
|
|
961
957
|
}),
|
|
962
|
-
[primaryColor, accentColor, isStreaming, viewportSize]
|
|
958
|
+
[primaryColor, accentColor, isStreaming, onAddToCart, viewportSize]
|
|
963
959
|
);
|
|
964
960
|
return /* @__PURE__ */ React5.createElement("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React5.createElement(
|
|
965
961
|
"div",
|
|
@@ -981,10 +977,11 @@ ${match.trim()}
|
|
|
981
977
|
primaryColor,
|
|
982
978
|
accentColor,
|
|
983
979
|
isStreaming,
|
|
980
|
+
onAddToCart,
|
|
984
981
|
viewportSize
|
|
985
982
|
}
|
|
986
983
|
), !shouldRenderStructuredOnly && /* @__PURE__ */ React5.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), isStreaming && message.content && /* @__PURE__ */ React5.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
987
|
-
), !isUser && allProducts.length > 0 && /* @__PURE__ */ React5.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React5.createElement(
|
|
984
|
+
), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ React5.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React5.createElement(
|
|
988
985
|
ProductCarousel,
|
|
989
986
|
{
|
|
990
987
|
products: allProducts,
|
package/dist/server.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-Cti1u0y1.mjs';
|
|
2
2
|
import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-D1dg5iCi.mjs';
|
|
3
3
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-D1dg5iCi.mjs';
|
|
4
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
5
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
4
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-BejNscWZ.mjs';
|
|
5
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-BejNscWZ.mjs';
|
|
6
6
|
import 'next/server';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-Cti1u0y1.js';
|
|
2
2
|
import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-BXOUMKoP.js';
|
|
3
3
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-BXOUMKoP.js';
|
|
4
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
5
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
4
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-CbkMJvu5.js';
|
|
5
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-CbkMJvu5.js';
|
|
6
6
|
import 'next/server';
|
|
7
7
|
|
|
8
8
|
/**
|