@apteva/apteva-kit 0.1.69 → 0.1.71
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.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +296 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +377 -153
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,13 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
|
|
6
6
|
// src/components/Chat/Chat.tsx
|
|
7
|
-
import { useState as
|
|
7
|
+
import { useState as useState6, useEffect as useEffect6, useRef as useRef7, useMemo as useMemo2, forwardRef, useImperativeHandle } from "react";
|
|
8
8
|
|
|
9
9
|
// src/components/Chat/MessageList.tsx
|
|
10
|
-
import { useEffect as
|
|
10
|
+
import { useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
11
11
|
|
|
12
12
|
// src/components/Chat/Message.tsx
|
|
13
|
-
import { useEffect as
|
|
13
|
+
import { useEffect as useEffect4, useRef as useRef3, useMemo } from "react";
|
|
14
14
|
|
|
15
15
|
// src/utils/cn.ts
|
|
16
16
|
import { clsx } from "clsx";
|
|
@@ -502,6 +502,71 @@ function validateFile(file) {
|
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
// src/utils/widget-parser.ts
|
|
505
|
+
var STREAMABLE_WIDGET_TYPES = ["list", "table"];
|
|
506
|
+
function parsePartialItemsArray(partialJson) {
|
|
507
|
+
const items = [];
|
|
508
|
+
let isStreaming = false;
|
|
509
|
+
const itemsMatch = partialJson.match(/"items"\s*:\s*\[/);
|
|
510
|
+
if (!itemsMatch) {
|
|
511
|
+
return { items, isStreaming: false };
|
|
512
|
+
}
|
|
513
|
+
const arrayStart = partialJson.indexOf("[", itemsMatch.index);
|
|
514
|
+
if (arrayStart === -1) {
|
|
515
|
+
return { items, isStreaming: true };
|
|
516
|
+
}
|
|
517
|
+
let depth = 0;
|
|
518
|
+
let inString = false;
|
|
519
|
+
let escapeNext = false;
|
|
520
|
+
let objectStart = -1;
|
|
521
|
+
for (let i = arrayStart + 1; i < partialJson.length; i++) {
|
|
522
|
+
const char = partialJson[i];
|
|
523
|
+
if (escapeNext) {
|
|
524
|
+
escapeNext = false;
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
if (char === "\\" && inString) {
|
|
528
|
+
escapeNext = true;
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
if (char === '"') {
|
|
532
|
+
inString = !inString;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
if (inString) continue;
|
|
536
|
+
if (char === "{") {
|
|
537
|
+
if (depth === 0) {
|
|
538
|
+
objectStart = i;
|
|
539
|
+
}
|
|
540
|
+
depth++;
|
|
541
|
+
} else if (char === "}") {
|
|
542
|
+
depth--;
|
|
543
|
+
if (depth === 0 && objectStart !== -1) {
|
|
544
|
+
const objectJson = partialJson.slice(objectStart, i + 1);
|
|
545
|
+
try {
|
|
546
|
+
const item = JSON.parse(objectJson);
|
|
547
|
+
if (!item.id) {
|
|
548
|
+
item.id = `item-${items.length}-${simpleHash(objectJson)}`;
|
|
549
|
+
}
|
|
550
|
+
items.push(item);
|
|
551
|
+
} catch (e) {
|
|
552
|
+
}
|
|
553
|
+
objectStart = -1;
|
|
554
|
+
}
|
|
555
|
+
} else if (char === "]" && depth === 0) {
|
|
556
|
+
isStreaming = false;
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (depth > 0 || objectStart !== -1) {
|
|
561
|
+
isStreaming = true;
|
|
562
|
+
}
|
|
563
|
+
const afterItems = partialJson.slice(arrayStart);
|
|
564
|
+
const closingBracket = findMatchingBracket(afterItems, 0);
|
|
565
|
+
if (closingBracket === -1) {
|
|
566
|
+
isStreaming = true;
|
|
567
|
+
}
|
|
568
|
+
return { items, isStreaming };
|
|
569
|
+
}
|
|
505
570
|
function simpleHash(str) {
|
|
506
571
|
let hash = 0;
|
|
507
572
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -563,9 +628,38 @@ function parseWidgetsFromText(text) {
|
|
|
563
628
|
const fullBracketStart = lastWidgetStart + bracketOpenIndex;
|
|
564
629
|
const bracketEnd = findMatchingBracket(text, fullBracketStart);
|
|
565
630
|
if (bracketEnd === -1) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
631
|
+
if (STREAMABLE_WIDGET_TYPES.includes(widgetType)) {
|
|
632
|
+
const partialContent = text.slice(fullBracketStart + 1);
|
|
633
|
+
const { items, isStreaming } = parsePartialItemsArray(partialContent);
|
|
634
|
+
if (items.length > 0) {
|
|
635
|
+
processText = text.slice(0, lastWidgetStart);
|
|
636
|
+
const widgetId = `widget-${widgetType}-streaming-${simpleHash(partialContent)}`;
|
|
637
|
+
const textBefore = processText.replace(/[\s:;\-–—\.]+$/g, "").trim();
|
|
638
|
+
if (textBefore) {
|
|
639
|
+
segments.push({ type: "text", content: textBefore });
|
|
640
|
+
}
|
|
641
|
+
segments.push({
|
|
642
|
+
type: "widget",
|
|
643
|
+
widget: {
|
|
644
|
+
type: widgetType,
|
|
645
|
+
id: widgetId,
|
|
646
|
+
props: widgetType === "table" ? { rows: items, columns: [] } : { items },
|
|
647
|
+
isStreaming: true
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
hasWidgets = true;
|
|
651
|
+
hasPendingWidget = false;
|
|
652
|
+
processText = "";
|
|
653
|
+
} else {
|
|
654
|
+
processText = text.slice(0, lastWidgetStart);
|
|
655
|
+
pendingWidgetType = widgetType;
|
|
656
|
+
hasPendingWidget = true;
|
|
657
|
+
}
|
|
658
|
+
} else {
|
|
659
|
+
processText = text.slice(0, lastWidgetStart);
|
|
660
|
+
pendingWidgetType = widgetType;
|
|
661
|
+
hasPendingWidget = true;
|
|
662
|
+
}
|
|
569
663
|
}
|
|
570
664
|
}
|
|
571
665
|
}
|
|
@@ -695,7 +789,7 @@ Widgets: @ui:type[{props}]. Types: ${widgets.join(", ")}. Add "meta" at root (no
|
|
|
695
789
|
}
|
|
696
790
|
|
|
697
791
|
// src/components/Widgets/Widgets.tsx
|
|
698
|
-
import { useEffect } from "react";
|
|
792
|
+
import { useEffect as useEffect3 } from "react";
|
|
699
793
|
|
|
700
794
|
// src/components/Widgets/widget-library/Card.tsx
|
|
701
795
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -728,39 +822,74 @@ function Card({ widget, onAction }) {
|
|
|
728
822
|
}
|
|
729
823
|
|
|
730
824
|
// src/components/Widgets/widget-library/List.tsx
|
|
825
|
+
import { useEffect, useRef, useState } from "react";
|
|
731
826
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
732
827
|
function List({ widget, onAction }) {
|
|
733
828
|
const { items } = widget.props;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
829
|
+
const isStreaming = widget.isStreaming ?? false;
|
|
830
|
+
const seenItemsRef = useRef(/* @__PURE__ */ new Set());
|
|
831
|
+
const [newItemIds, setNewItemIds] = useState(/* @__PURE__ */ new Set());
|
|
832
|
+
useEffect(() => {
|
|
833
|
+
const currentIds = new Set(items.map((item) => item.id));
|
|
834
|
+
const newIds = /* @__PURE__ */ new Set();
|
|
835
|
+
items.forEach((item) => {
|
|
836
|
+
if (!seenItemsRef.current.has(item.id)) {
|
|
837
|
+
newIds.add(item.id);
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
items.forEach((item) => seenItemsRef.current.add(item.id));
|
|
841
|
+
if (newIds.size > 0) {
|
|
842
|
+
setNewItemIds(newIds);
|
|
843
|
+
const timer = setTimeout(() => {
|
|
844
|
+
setNewItemIds(/* @__PURE__ */ new Set());
|
|
845
|
+
}, 500);
|
|
846
|
+
return () => clearTimeout(timer);
|
|
847
|
+
}
|
|
848
|
+
}, [items]);
|
|
849
|
+
return /* @__PURE__ */ jsxs2("div", { className: "border border-neutral-200 dark:border-neutral-700 rounded-xl bg-white dark:bg-neutral-900 overflow-hidden", children: [
|
|
850
|
+
items.map((item, index) => {
|
|
851
|
+
const isNew = newItemIds.has(item.id);
|
|
852
|
+
const isLast = index === items.length - 1;
|
|
853
|
+
return /* @__PURE__ */ jsxs2(
|
|
854
|
+
"div",
|
|
855
|
+
{
|
|
856
|
+
className: `apteva-list-item flex items-center p-4 transition-colors ${!isLast || isStreaming ? "border-b border-neutral-200 dark:border-neutral-700" : ""} ${!item.backgroundColor ? "hover:bg-neutral-50 dark:hover:bg-neutral-800" : ""} ${isNew ? "apteva-list-item-new" : ""}`,
|
|
857
|
+
style: item.backgroundColor ? { backgroundColor: item.backgroundColor } : void 0,
|
|
858
|
+
children: [
|
|
859
|
+
item.image && /* @__PURE__ */ jsx2("img", { src: item.image, alt: item.title, className: "w-16 h-16 rounded object-cover" }),
|
|
860
|
+
/* @__PURE__ */ jsxs2("div", { className: `flex-1 ${item.image ? "ml-4" : ""}`, children: [
|
|
861
|
+
/* @__PURE__ */ jsx2("h4", { className: "font-semibold !text-neutral-900 dark:!text-white", children: item.title }),
|
|
862
|
+
item.subtitle && /* @__PURE__ */ jsx2("p", { className: "!text-sm !text-neutral-600 dark:!text-neutral-400", children: item.subtitle }),
|
|
863
|
+
item.description && /* @__PURE__ */ jsx2("p", { className: "!text-xs !text-neutral-500 dark:!text-neutral-500 mt-1", children: item.description })
|
|
864
|
+
] }),
|
|
865
|
+
widget.actions && widget.actions.length > 0 && /* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: widget.actions.map((action, idx) => /* @__PURE__ */ jsx2(
|
|
866
|
+
"button",
|
|
867
|
+
{
|
|
868
|
+
onClick: () => onAction?.({
|
|
869
|
+
type: action.type,
|
|
870
|
+
payload: item.metadata || item,
|
|
871
|
+
widgetId: widget.id,
|
|
872
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
873
|
+
}),
|
|
874
|
+
className: "px-3 py-1.5 !text-sm rounded-lg font-medium transition-colors bg-blue-500 !text-white hover:bg-blue-600",
|
|
875
|
+
children: action.label
|
|
876
|
+
},
|
|
877
|
+
idx
|
|
878
|
+
)) })
|
|
879
|
+
]
|
|
880
|
+
},
|
|
881
|
+
item.id
|
|
882
|
+
);
|
|
883
|
+
}),
|
|
884
|
+
isStreaming && /* @__PURE__ */ jsxs2("div", { className: "apteva-list-streaming flex items-center gap-3 p-4 text-neutral-500 dark:text-neutral-400", children: [
|
|
885
|
+
/* @__PURE__ */ jsxs2("div", { className: "apteva-streaming-dots flex gap-1", children: [
|
|
886
|
+
/* @__PURE__ */ jsx2("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "0ms" } }),
|
|
887
|
+
/* @__PURE__ */ jsx2("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "150ms" } }),
|
|
888
|
+
/* @__PURE__ */ jsx2("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "300ms" } })
|
|
889
|
+
] }),
|
|
890
|
+
/* @__PURE__ */ jsx2("span", { className: "text-sm", children: "Loading more..." })
|
|
891
|
+
] })
|
|
892
|
+
] });
|
|
764
893
|
}
|
|
765
894
|
|
|
766
895
|
// src/components/Widgets/widget-library/Button.tsx
|
|
@@ -839,9 +968,33 @@ function ButtonGroup({ widget, onAction }) {
|
|
|
839
968
|
}
|
|
840
969
|
|
|
841
970
|
// src/components/Widgets/widget-library/Table.tsx
|
|
971
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
842
972
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
843
973
|
function Table({ widget, onAction }) {
|
|
844
974
|
const { columns, rows, caption, compact = false, striped = false } = widget.props;
|
|
975
|
+
const isStreaming = widget.isStreaming ?? false;
|
|
976
|
+
const seenRowsRef = useRef2(/* @__PURE__ */ new Set());
|
|
977
|
+
const [newRowIds, setNewRowIds] = useState2(/* @__PURE__ */ new Set());
|
|
978
|
+
useEffect2(() => {
|
|
979
|
+
const newIds = /* @__PURE__ */ new Set();
|
|
980
|
+
rows.forEach((row, index) => {
|
|
981
|
+
const rowId = row.id || `row-${index}`;
|
|
982
|
+
if (!seenRowsRef.current.has(rowId)) {
|
|
983
|
+
newIds.add(rowId);
|
|
984
|
+
}
|
|
985
|
+
});
|
|
986
|
+
rows.forEach((row, index) => {
|
|
987
|
+
const rowId = row.id || `row-${index}`;
|
|
988
|
+
seenRowsRef.current.add(rowId);
|
|
989
|
+
});
|
|
990
|
+
if (newIds.size > 0) {
|
|
991
|
+
setNewRowIds(newIds);
|
|
992
|
+
const timer = setTimeout(() => {
|
|
993
|
+
setNewRowIds(/* @__PURE__ */ new Set());
|
|
994
|
+
}, 500);
|
|
995
|
+
return () => clearTimeout(timer);
|
|
996
|
+
}
|
|
997
|
+
}, [rows]);
|
|
845
998
|
const getAlignment = (align) => {
|
|
846
999
|
switch (align) {
|
|
847
1000
|
case "center":
|
|
@@ -868,58 +1021,78 @@ function Table({ widget, onAction }) {
|
|
|
868
1021
|
column.key
|
|
869
1022
|
)) }) }),
|
|
870
1023
|
/* @__PURE__ */ jsxs3("tbody", { children: [
|
|
871
|
-
rows.map((row, rowIndex) =>
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
{
|
|
893
|
-
className: cn(
|
|
894
|
-
"text-neutral-700 dark:text-neutral-300",
|
|
895
|
-
compact ? "px-3 py-2 text-xs" : "px-4 py-3 text-sm",
|
|
896
|
-
getAlignment(column.align)
|
|
897
|
-
),
|
|
898
|
-
children: row[column.key] ?? "\u2014"
|
|
1024
|
+
rows.map((row, rowIndex) => {
|
|
1025
|
+
const rowId = row.id || `row-${rowIndex}`;
|
|
1026
|
+
const isNew = newRowIds.has(rowId);
|
|
1027
|
+
return /* @__PURE__ */ jsx5(
|
|
1028
|
+
"tr",
|
|
1029
|
+
{
|
|
1030
|
+
className: cn(
|
|
1031
|
+
"apteva-table-row border-b border-neutral-200 dark:border-neutral-700 last:border-b-0",
|
|
1032
|
+
"transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-800",
|
|
1033
|
+
striped && rowIndex % 2 === 1 && "bg-neutral-50/50 dark:bg-neutral-800/50",
|
|
1034
|
+
isNew && "apteva-table-row-new"
|
|
1035
|
+
),
|
|
1036
|
+
onClick: () => {
|
|
1037
|
+
if (widget.actions && widget.actions.length > 0) {
|
|
1038
|
+
onAction?.({
|
|
1039
|
+
type: widget.actions[0].type,
|
|
1040
|
+
payload: row,
|
|
1041
|
+
widgetId: widget.id,
|
|
1042
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
899
1045
|
},
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1046
|
+
style: { cursor: widget.actions?.length ? "pointer" : "default" },
|
|
1047
|
+
children: columns.map((column) => /* @__PURE__ */ jsx5(
|
|
1048
|
+
"td",
|
|
1049
|
+
{
|
|
1050
|
+
className: cn(
|
|
1051
|
+
"text-neutral-700 dark:text-neutral-300",
|
|
1052
|
+
compact ? "px-3 py-2 text-xs" : "px-4 py-3 text-sm",
|
|
1053
|
+
getAlignment(column.align)
|
|
1054
|
+
),
|
|
1055
|
+
children: row[column.key] ?? "\u2014"
|
|
1056
|
+
},
|
|
1057
|
+
column.key
|
|
1058
|
+
))
|
|
1059
|
+
},
|
|
1060
|
+
rowId
|
|
1061
|
+
);
|
|
1062
|
+
}),
|
|
1063
|
+
rows.length === 0 && !isStreaming && /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5(
|
|
906
1064
|
"td",
|
|
907
1065
|
{
|
|
908
|
-
colSpan: columns.length,
|
|
1066
|
+
colSpan: columns.length || 1,
|
|
909
1067
|
className: "px-4 py-8 text-center text-sm text-neutral-500 dark:text-neutral-400",
|
|
910
1068
|
children: "No data available"
|
|
911
1069
|
}
|
|
1070
|
+
) }),
|
|
1071
|
+
isStreaming && /* @__PURE__ */ jsx5("tr", { className: "apteva-table-streaming", children: /* @__PURE__ */ jsx5(
|
|
1072
|
+
"td",
|
|
1073
|
+
{
|
|
1074
|
+
colSpan: columns.length || 1,
|
|
1075
|
+
className: "px-4 py-3 text-center",
|
|
1076
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-center gap-3 text-neutral-500 dark:text-neutral-400", children: [
|
|
1077
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex gap-1", children: [
|
|
1078
|
+
/* @__PURE__ */ jsx5("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "0ms" } }),
|
|
1079
|
+
/* @__PURE__ */ jsx5("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "150ms" } }),
|
|
1080
|
+
/* @__PURE__ */ jsx5("span", { className: "w-2 h-2 bg-current rounded-full animate-pulse", style: { animationDelay: "300ms" } })
|
|
1081
|
+
] }),
|
|
1082
|
+
/* @__PURE__ */ jsx5("span", { className: "text-sm", children: "Loading more..." })
|
|
1083
|
+
] })
|
|
1084
|
+
}
|
|
912
1085
|
) })
|
|
913
1086
|
] })
|
|
914
1087
|
] }) }) });
|
|
915
1088
|
}
|
|
916
1089
|
|
|
917
1090
|
// src/components/Widgets/widget-library/Form.tsx
|
|
918
|
-
import { useState } from "react";
|
|
1091
|
+
import { useState as useState3 } from "react";
|
|
919
1092
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
920
1093
|
function Form({ widget, onAction }) {
|
|
921
1094
|
const { title, fields } = widget.props;
|
|
922
|
-
const [formData, setFormData] =
|
|
1095
|
+
const [formData, setFormData] = useState3(() => {
|
|
923
1096
|
const initial = {};
|
|
924
1097
|
fields.forEach((field) => {
|
|
925
1098
|
initial[field.name] = field.defaultValue ?? (field.type === "checkbox" ? false : "");
|
|
@@ -1069,7 +1242,7 @@ function Widgets({
|
|
|
1069
1242
|
columns = 3,
|
|
1070
1243
|
className
|
|
1071
1244
|
}) {
|
|
1072
|
-
|
|
1245
|
+
useEffect3(() => {
|
|
1073
1246
|
widgets.forEach((widget) => {
|
|
1074
1247
|
onWidgetMount?.(widget.id);
|
|
1075
1248
|
});
|
|
@@ -1345,14 +1518,39 @@ function MarkdownContent({ content, className = "" }) {
|
|
|
1345
1518
|
|
|
1346
1519
|
// src/components/Chat/ToolCall.tsx
|
|
1347
1520
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1348
|
-
function ToolCall({ name, status }) {
|
|
1521
|
+
function ToolCall({ name, status, isReceiving = false }) {
|
|
1522
|
+
if (status === "preparing") {
|
|
1523
|
+
return /* @__PURE__ */ jsxs8("div", { className: `apteva-tool-card apteva-tool-card-preparing ${isReceiving ? "apteva-tool-receiving" : ""}`, children: [
|
|
1524
|
+
/* @__PURE__ */ jsxs8("svg", { className: "apteva-tool-icon apteva-tool-icon-spin", fill: "none", viewBox: "0 0 24 24", children: [
|
|
1525
|
+
/* @__PURE__ */ jsx11("circle", { className: "apteva-tool-spinner-track", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1526
|
+
/* @__PURE__ */ jsx11("path", { className: "apteva-tool-spinner-fill", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
1527
|
+
] }),
|
|
1528
|
+
/* @__PURE__ */ jsxs8("span", { className: "apteva-tool-label", children: [
|
|
1529
|
+
/* @__PURE__ */ jsx11("strong", { children: name }),
|
|
1530
|
+
/* @__PURE__ */ jsx11("span", { className: "apteva-tool-status-text", children: " preparing" }),
|
|
1531
|
+
/* @__PURE__ */ jsxs8("span", { className: "apteva-tool-dots", children: [
|
|
1532
|
+
/* @__PURE__ */ jsx11("span", { children: "." }),
|
|
1533
|
+
/* @__PURE__ */ jsx11("span", { children: "." }),
|
|
1534
|
+
/* @__PURE__ */ jsx11("span", { children: "." })
|
|
1535
|
+
] })
|
|
1536
|
+
] })
|
|
1537
|
+
] });
|
|
1538
|
+
}
|
|
1349
1539
|
if (status === "running") {
|
|
1350
1540
|
return /* @__PURE__ */ jsxs8("div", { className: "apteva-tool-card apteva-tool-card-running", children: [
|
|
1351
1541
|
/* @__PURE__ */ jsxs8("svg", { className: "apteva-tool-icon apteva-tool-icon-spin", fill: "none", viewBox: "0 0 24 24", children: [
|
|
1352
1542
|
/* @__PURE__ */ jsx11("circle", { className: "apteva-tool-spinner-track", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1353
1543
|
/* @__PURE__ */ jsx11("path", { className: "apteva-tool-spinner-fill", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
1354
1544
|
] }),
|
|
1355
|
-
/* @__PURE__ */
|
|
1545
|
+
/* @__PURE__ */ jsxs8("span", { className: "apteva-tool-label", children: [
|
|
1546
|
+
/* @__PURE__ */ jsx11("strong", { children: name }),
|
|
1547
|
+
/* @__PURE__ */ jsx11("span", { className: "apteva-tool-status-text", children: " running" }),
|
|
1548
|
+
/* @__PURE__ */ jsxs8("span", { className: "apteva-tool-dots", children: [
|
|
1549
|
+
/* @__PURE__ */ jsx11("span", { children: "." }),
|
|
1550
|
+
/* @__PURE__ */ jsx11("span", { children: "." }),
|
|
1551
|
+
/* @__PURE__ */ jsx11("span", { children: "." })
|
|
1552
|
+
] })
|
|
1553
|
+
] })
|
|
1356
1554
|
] });
|
|
1357
1555
|
}
|
|
1358
1556
|
if (status === "completed") {
|
|
@@ -1377,7 +1575,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
|
|
|
1377
1575
|
const contentSegments = message.metadata?.content_segments;
|
|
1378
1576
|
const isStreaming = message.metadata?.isStreaming === true;
|
|
1379
1577
|
const hasContent = message.content || contentSegments && contentSegments.length > 0;
|
|
1380
|
-
const reportedWidgetsRef =
|
|
1578
|
+
const reportedWidgetsRef = useRef3(/* @__PURE__ */ new Set());
|
|
1381
1579
|
const parsedWidgets = useMemo(() => {
|
|
1382
1580
|
if (!enableWidgets || isUser || !message.content) {
|
|
1383
1581
|
return [];
|
|
@@ -1385,7 +1583,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
|
|
|
1385
1583
|
const parsed = parseWidgetsFromText(message.content);
|
|
1386
1584
|
return parsed.segments.filter((seg) => seg.type === "widget" && !!seg.widget).map((seg) => seg.widget);
|
|
1387
1585
|
}, [enableWidgets, isUser, message.content]);
|
|
1388
|
-
|
|
1586
|
+
useEffect4(() => {
|
|
1389
1587
|
if (onWidgetRender && message.widgets) {
|
|
1390
1588
|
for (const widget of message.widgets) {
|
|
1391
1589
|
if (!reportedWidgetsRef.current.has(widget.id)) {
|
|
@@ -1395,7 +1593,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
|
|
|
1395
1593
|
}
|
|
1396
1594
|
}
|
|
1397
1595
|
}, [message.widgets, onWidgetRender]);
|
|
1398
|
-
|
|
1596
|
+
useEffect4(() => {
|
|
1399
1597
|
if (onWidgetRender && parsedWidgets.length > 0) {
|
|
1400
1598
|
for (const widget of parsedWidgets) {
|
|
1401
1599
|
if (!reportedWidgetsRef.current.has(widget.id)) {
|
|
@@ -1566,7 +1764,8 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
|
|
|
1566
1764
|
ToolCall,
|
|
1567
1765
|
{
|
|
1568
1766
|
name: segment.name,
|
|
1569
|
-
status: segment.result !== void 0 ? "completed" : "running"
|
|
1767
|
+
status: segment.status || (segment.result !== void 0 ? "completed" : "running"),
|
|
1768
|
+
isReceiving: segment.isReceiving
|
|
1570
1769
|
}
|
|
1571
1770
|
) }, segment.id)
|
|
1572
1771
|
);
|
|
@@ -1767,16 +1966,16 @@ function MessageList({
|
|
|
1767
1966
|
enableWidgets,
|
|
1768
1967
|
onWidgetRender
|
|
1769
1968
|
}) {
|
|
1770
|
-
const listRef =
|
|
1771
|
-
const isNearBottomRef =
|
|
1772
|
-
const lastScrollHeightRef =
|
|
1969
|
+
const listRef = useRef4(null);
|
|
1970
|
+
const isNearBottomRef = useRef4(true);
|
|
1971
|
+
const lastScrollHeightRef = useRef4(0);
|
|
1773
1972
|
const handleScroll = () => {
|
|
1774
1973
|
if (listRef.current) {
|
|
1775
1974
|
const { scrollTop, scrollHeight, clientHeight } = listRef.current;
|
|
1776
1975
|
isNearBottomRef.current = scrollHeight - scrollTop - clientHeight < 100;
|
|
1777
1976
|
}
|
|
1778
1977
|
};
|
|
1779
|
-
|
|
1978
|
+
useEffect5(() => {
|
|
1780
1979
|
if (listRef.current && isNearBottomRef.current) {
|
|
1781
1980
|
const currentScrollHeight = listRef.current.scrollHeight;
|
|
1782
1981
|
if (currentScrollHeight !== lastScrollHeightRef.current) {
|
|
@@ -1800,16 +1999,16 @@ function MessageList({
|
|
|
1800
1999
|
}
|
|
1801
2000
|
|
|
1802
2001
|
// src/components/Chat/Composer.tsx
|
|
1803
|
-
import { useState as
|
|
2002
|
+
import { useState as useState4, useRef as useRef5 } from "react";
|
|
1804
2003
|
import { Fragment, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1805
2004
|
function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, isLoading = false, onStop, onFileUpload, onSwitchMode }) {
|
|
1806
|
-
const [text, setText] =
|
|
1807
|
-
const [showMenu, setShowMenu] =
|
|
1808
|
-
const [pendingFiles, setPendingFiles] =
|
|
1809
|
-
const [fileError, setFileError] =
|
|
1810
|
-
const textareaRef =
|
|
1811
|
-
const fileInputRef =
|
|
1812
|
-
const menuButtonRef =
|
|
2005
|
+
const [text, setText] = useState4("");
|
|
2006
|
+
const [showMenu, setShowMenu] = useState4(false);
|
|
2007
|
+
const [pendingFiles, setPendingFiles] = useState4([]);
|
|
2008
|
+
const [fileError, setFileError] = useState4(null);
|
|
2009
|
+
const textareaRef = useRef5(null);
|
|
2010
|
+
const fileInputRef = useRef5(null);
|
|
2011
|
+
const menuButtonRef = useRef5(null);
|
|
1813
2012
|
const handleKeyDown = (e) => {
|
|
1814
2013
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
1815
2014
|
e.preventDefault();
|
|
@@ -2013,7 +2212,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
|
|
|
2013
2212
|
}
|
|
2014
2213
|
|
|
2015
2214
|
// src/components/Chat/CommandComposer.tsx
|
|
2016
|
-
import { useState as
|
|
2215
|
+
import { useState as useState5, useRef as useRef6 } from "react";
|
|
2017
2216
|
import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2018
2217
|
function CommandComposer({
|
|
2019
2218
|
onExecute,
|
|
@@ -2031,13 +2230,13 @@ function CommandComposer({
|
|
|
2031
2230
|
placeholder = "Enter your command...",
|
|
2032
2231
|
disabled = false
|
|
2033
2232
|
}) {
|
|
2034
|
-
const [input, setInput] =
|
|
2035
|
-
const [pendingFiles, setPendingFiles] =
|
|
2036
|
-
const [fileError, setFileError] =
|
|
2037
|
-
const [showMenu, setShowMenu] =
|
|
2038
|
-
const inputRef =
|
|
2039
|
-
const fileInputRef =
|
|
2040
|
-
const menuButtonRef =
|
|
2233
|
+
const [input, setInput] = useState5("");
|
|
2234
|
+
const [pendingFiles, setPendingFiles] = useState5([]);
|
|
2235
|
+
const [fileError, setFileError] = useState5(null);
|
|
2236
|
+
const [showMenu, setShowMenu] = useState5(false);
|
|
2237
|
+
const inputRef = useRef6(null);
|
|
2238
|
+
const fileInputRef = useRef6(null);
|
|
2239
|
+
const menuButtonRef = useRef6(null);
|
|
2041
2240
|
const handleSubmit = () => {
|
|
2042
2241
|
const hasText = input.trim();
|
|
2043
2242
|
const hasFiles = pendingFiles.length > 0;
|
|
@@ -2566,25 +2765,25 @@ var Chat = forwardRef(function Chat2({
|
|
|
2566
2765
|
onWidgetRender,
|
|
2567
2766
|
className
|
|
2568
2767
|
}, ref) {
|
|
2569
|
-
const [messages, setMessages] =
|
|
2570
|
-
const [isLoading, setIsLoading] =
|
|
2571
|
-
const [currentThreadId, setCurrentThreadId] =
|
|
2572
|
-
const [mode, setMode] =
|
|
2573
|
-
const [chatToolName, setChatToolName] =
|
|
2574
|
-
const [commandState, setCommandState] =
|
|
2575
|
-
const [commandResult, setCommandResult] =
|
|
2576
|
-
const [commandError, setCommandError] =
|
|
2577
|
-
const [progress, setProgress] =
|
|
2578
|
-
const [commandInput, setCommandInput] =
|
|
2579
|
-
const [streamedContent, setStreamedContent] =
|
|
2580
|
-
const [currentToolName, setCurrentToolName] =
|
|
2581
|
-
const [currentRequestId, setCurrentRequestId] =
|
|
2582
|
-
const [plan, setPlan] =
|
|
2583
|
-
const [pendingCommand, setPendingCommand] =
|
|
2584
|
-
const [internalPlanMode, setInternalPlanMode] =
|
|
2585
|
-
const [showSettingsMenu, setShowSettingsMenu] =
|
|
2586
|
-
const fileInputRef =
|
|
2587
|
-
const handleSendMessageRef =
|
|
2768
|
+
const [messages, setMessages] = useState6(initialMessages);
|
|
2769
|
+
const [isLoading, setIsLoading] = useState6(false);
|
|
2770
|
+
const [currentThreadId, setCurrentThreadId] = useState6(threadId || null);
|
|
2771
|
+
const [mode, setMode] = useState6(initialMode);
|
|
2772
|
+
const [chatToolName, setChatToolName] = useState6(null);
|
|
2773
|
+
const [commandState, setCommandState] = useState6("idle");
|
|
2774
|
+
const [commandResult, setCommandResult] = useState6(null);
|
|
2775
|
+
const [commandError, setCommandError] = useState6(null);
|
|
2776
|
+
const [progress, setProgress] = useState6(0);
|
|
2777
|
+
const [commandInput, setCommandInput] = useState6("");
|
|
2778
|
+
const [streamedContent, setStreamedContent] = useState6("");
|
|
2779
|
+
const [currentToolName, setCurrentToolName] = useState6(null);
|
|
2780
|
+
const [currentRequestId, setCurrentRequestId] = useState6(null);
|
|
2781
|
+
const [plan, setPlan] = useState6("");
|
|
2782
|
+
const [pendingCommand, setPendingCommand] = useState6("");
|
|
2783
|
+
const [internalPlanMode, setInternalPlanMode] = useState6(planMode);
|
|
2784
|
+
const [showSettingsMenu, setShowSettingsMenu] = useState6(false);
|
|
2785
|
+
const fileInputRef = useRef7(null);
|
|
2786
|
+
const handleSendMessageRef = useRef7(null);
|
|
2588
2787
|
useImperativeHandle(ref, () => ({
|
|
2589
2788
|
sendMessage: async (text) => {
|
|
2590
2789
|
if (handleSendMessageRef.current) {
|
|
@@ -2605,7 +2804,7 @@ var Chat = forwardRef(function Chat2({
|
|
|
2605
2804
|
return context ? `${context}
|
|
2606
2805
|
${widgetContext}` : widgetContext;
|
|
2607
2806
|
}, [context, enableWidgets, availableWidgets, compactWidgetContext]);
|
|
2608
|
-
|
|
2807
|
+
useEffect6(() => {
|
|
2609
2808
|
if (apiUrl || apiKey) {
|
|
2610
2809
|
aptevaClient.configure({
|
|
2611
2810
|
...apiUrl && { apiUrl },
|
|
@@ -2613,15 +2812,15 @@ ${widgetContext}` : widgetContext;
|
|
|
2613
2812
|
});
|
|
2614
2813
|
}
|
|
2615
2814
|
}, [apiUrl, apiKey]);
|
|
2616
|
-
|
|
2815
|
+
useEffect6(() => {
|
|
2617
2816
|
if (threadId) {
|
|
2618
2817
|
onThreadChange?.(threadId);
|
|
2619
2818
|
}
|
|
2620
2819
|
}, [threadId, onThreadChange]);
|
|
2621
|
-
|
|
2820
|
+
useEffect6(() => {
|
|
2622
2821
|
setInternalPlanMode(planMode);
|
|
2623
2822
|
}, [planMode]);
|
|
2624
|
-
|
|
2823
|
+
useEffect6(() => {
|
|
2625
2824
|
const handleClickOutside = (event) => {
|
|
2626
2825
|
const target = event.target;
|
|
2627
2826
|
if (showSettingsMenu && !target.closest(".settings-menu-container")) {
|
|
@@ -2672,6 +2871,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2672
2871
|
let accumulatedWidgets = [];
|
|
2673
2872
|
let responseThreadId = currentThreadId;
|
|
2674
2873
|
let toolInputBuffer = "";
|
|
2874
|
+
let receivingTimeout = null;
|
|
2675
2875
|
const streamingMessageId = `msg-${Date.now()}`;
|
|
2676
2876
|
const updateMessage = () => {
|
|
2677
2877
|
const segments = [...contentSegments];
|
|
@@ -2748,7 +2948,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2748
2948
|
contentSegments.push({ type: "text", content: currentTextBuffer });
|
|
2749
2949
|
currentTextBuffer = "";
|
|
2750
2950
|
}
|
|
2751
|
-
contentSegments.push({ type: "tool", id: chunk.tool_id, name: displayName });
|
|
2951
|
+
contentSegments.push({ type: "tool", id: chunk.tool_id, name: displayName, status: "preparing" });
|
|
2752
2952
|
toolInputBuffer = "";
|
|
2753
2953
|
setChatToolName(displayName);
|
|
2754
2954
|
onToolCall?.(chunk.tool_name, chunk.tool_id);
|
|
@@ -2758,6 +2958,28 @@ ${widgetContext}` : widgetContext;
|
|
|
2758
2958
|
case "tool_input_delta":
|
|
2759
2959
|
if (chunk.tool_id && chunk.content) {
|
|
2760
2960
|
toolInputBuffer += chunk.content;
|
|
2961
|
+
const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
|
|
2962
|
+
if (toolSegment) {
|
|
2963
|
+
toolSegment.isReceiving = true;
|
|
2964
|
+
updateMessage();
|
|
2965
|
+
if (receivingTimeout) clearTimeout(receivingTimeout);
|
|
2966
|
+
receivingTimeout = setTimeout(() => {
|
|
2967
|
+
if (toolSegment.status === "preparing") {
|
|
2968
|
+
toolSegment.isReceiving = false;
|
|
2969
|
+
updateMessage();
|
|
2970
|
+
}
|
|
2971
|
+
}, 150);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
break;
|
|
2975
|
+
case "tool_use":
|
|
2976
|
+
if (chunk.tool_id) {
|
|
2977
|
+
const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
|
|
2978
|
+
if (toolSegment && toolSegment.status === "preparing") {
|
|
2979
|
+
toolSegment.status = "running";
|
|
2980
|
+
toolSegment.isReceiving = false;
|
|
2981
|
+
updateMessage();
|
|
2982
|
+
}
|
|
2761
2983
|
}
|
|
2762
2984
|
break;
|
|
2763
2985
|
case "tool_result":
|
|
@@ -2765,6 +2987,8 @@ ${widgetContext}` : widgetContext;
|
|
|
2765
2987
|
const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
|
|
2766
2988
|
if (toolSegment) {
|
|
2767
2989
|
toolSegment.result = chunk.content;
|
|
2990
|
+
toolSegment.status = "completed";
|
|
2991
|
+
toolSegment.isReceiving = false;
|
|
2768
2992
|
onToolResult?.(toolSegment.name, chunk.content);
|
|
2769
2993
|
}
|
|
2770
2994
|
setChatToolName(null);
|
|
@@ -3153,11 +3377,11 @@ ${planToExecute}`;
|
|
|
3153
3377
|
});
|
|
3154
3378
|
|
|
3155
3379
|
// src/components/Chat/CommandOutput.tsx
|
|
3156
|
-
import { useState as
|
|
3380
|
+
import { useState as useState7 } from "react";
|
|
3157
3381
|
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3158
3382
|
|
|
3159
3383
|
// src/components/Command/Command.tsx
|
|
3160
|
-
import React, { useState as
|
|
3384
|
+
import React, { useState as useState8, useEffect as useEffect7 } from "react";
|
|
3161
3385
|
import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3162
3386
|
function Command({
|
|
3163
3387
|
agentId,
|
|
@@ -3185,28 +3409,28 @@ function Command({
|
|
|
3185
3409
|
resultRenderer,
|
|
3186
3410
|
className
|
|
3187
3411
|
}) {
|
|
3188
|
-
const [state, setState] =
|
|
3189
|
-
const [result, setResult] =
|
|
3190
|
-
const [error, setError] =
|
|
3191
|
-
const [progress, setProgress] =
|
|
3192
|
-
const [command, setCommand] =
|
|
3193
|
-
const [streamedContent, setStreamedContent] =
|
|
3194
|
-
const [plan, setPlan] =
|
|
3195
|
-
const [pendingCommand, setPendingCommand] =
|
|
3196
|
-
const [showPlanDetails, setShowPlanDetails] =
|
|
3197
|
-
const [uploadedFiles, setUploadedFiles] =
|
|
3198
|
-
const [showSettingsMenu, setShowSettingsMenu] =
|
|
3199
|
-
const [internalPlanMode, setInternalPlanMode] =
|
|
3412
|
+
const [state, setState] = useState8("idle");
|
|
3413
|
+
const [result, setResult] = useState8(null);
|
|
3414
|
+
const [error, setError] = useState8(null);
|
|
3415
|
+
const [progress, setProgress] = useState8(0);
|
|
3416
|
+
const [command, setCommand] = useState8(initialCommand || "");
|
|
3417
|
+
const [streamedContent, setStreamedContent] = useState8("");
|
|
3418
|
+
const [plan, setPlan] = useState8("");
|
|
3419
|
+
const [pendingCommand, setPendingCommand] = useState8("");
|
|
3420
|
+
const [showPlanDetails, setShowPlanDetails] = useState8(false);
|
|
3421
|
+
const [uploadedFiles, setUploadedFiles] = useState8([]);
|
|
3422
|
+
const [showSettingsMenu, setShowSettingsMenu] = useState8(false);
|
|
3423
|
+
const [internalPlanMode, setInternalPlanMode] = useState8(planMode);
|
|
3200
3424
|
const fileInputRef = React.useRef(null);
|
|
3201
|
-
|
|
3425
|
+
useEffect7(() => {
|
|
3202
3426
|
if (autoExecute && state === "idle" && command) {
|
|
3203
3427
|
executeCommand();
|
|
3204
3428
|
}
|
|
3205
3429
|
}, [autoExecute]);
|
|
3206
|
-
|
|
3430
|
+
useEffect7(() => {
|
|
3207
3431
|
setInternalPlanMode(planMode);
|
|
3208
3432
|
}, [planMode]);
|
|
3209
|
-
|
|
3433
|
+
useEffect7(() => {
|
|
3210
3434
|
const handleClickOutside = (event) => {
|
|
3211
3435
|
const target = event.target;
|
|
3212
3436
|
if (showSettingsMenu && !target.closest(".settings-menu-container")) {
|
|
@@ -4128,7 +4352,7 @@ ${planToExecute}`;
|
|
|
4128
4352
|
}
|
|
4129
4353
|
|
|
4130
4354
|
// src/components/Prompt/Prompt.tsx
|
|
4131
|
-
import { useState as
|
|
4355
|
+
import { useState as useState9 } from "react";
|
|
4132
4356
|
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4133
4357
|
function Prompt({
|
|
4134
4358
|
agentId,
|
|
@@ -4146,9 +4370,9 @@ function Prompt({
|
|
|
4146
4370
|
showSuggestions = false,
|
|
4147
4371
|
className
|
|
4148
4372
|
}) {
|
|
4149
|
-
const [value, setValue] =
|
|
4150
|
-
const [isLoading, setIsLoading] =
|
|
4151
|
-
const [suggestions] =
|
|
4373
|
+
const [value, setValue] = useState9(initialValue);
|
|
4374
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
4375
|
+
const [suggestions] = useState9(["Plan a trip", "Write a description", "Analyze data"]);
|
|
4152
4376
|
const handleChange = (e) => {
|
|
4153
4377
|
const newValue = e.target.value;
|
|
4154
4378
|
if (!maxLength || newValue.length <= maxLength) {
|
|
@@ -4239,7 +4463,7 @@ function Prompt({
|
|
|
4239
4463
|
}
|
|
4240
4464
|
|
|
4241
4465
|
// src/components/Stream/Stream.tsx
|
|
4242
|
-
import { useState as
|
|
4466
|
+
import { useState as useState10, useEffect as useEffect8 } from "react";
|
|
4243
4467
|
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4244
4468
|
function Stream({
|
|
4245
4469
|
agentId,
|
|
@@ -4256,10 +4480,10 @@ function Stream({
|
|
|
4256
4480
|
typingSpeed = 30,
|
|
4257
4481
|
className
|
|
4258
4482
|
}) {
|
|
4259
|
-
const [text, setText] =
|
|
4260
|
-
const [isStreaming, setIsStreaming] =
|
|
4261
|
-
const [isComplete, setIsComplete] =
|
|
4262
|
-
|
|
4483
|
+
const [text, setText] = useState10("");
|
|
4484
|
+
const [isStreaming, setIsStreaming] = useState10(false);
|
|
4485
|
+
const [isComplete, setIsComplete] = useState10(false);
|
|
4486
|
+
useEffect8(() => {
|
|
4263
4487
|
if (autoStart && !isStreaming && !isComplete) {
|
|
4264
4488
|
startStreaming();
|
|
4265
4489
|
}
|
|
@@ -4336,7 +4560,7 @@ function Stream({
|
|
|
4336
4560
|
}
|
|
4337
4561
|
|
|
4338
4562
|
// src/components/Threads/ThreadList.tsx
|
|
4339
|
-
import { useState as
|
|
4563
|
+
import { useState as useState11 } from "react";
|
|
4340
4564
|
|
|
4341
4565
|
// src/components/Threads/ThreadItem.tsx
|
|
4342
4566
|
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
@@ -4400,7 +4624,7 @@ function ThreadList({
|
|
|
4400
4624
|
showSearch = false,
|
|
4401
4625
|
groupBy = "none"
|
|
4402
4626
|
}) {
|
|
4403
|
-
const [searchQuery, setSearchQuery] =
|
|
4627
|
+
const [searchQuery, setSearchQuery] = useState11("");
|
|
4404
4628
|
const filteredThreads = threads.filter(
|
|
4405
4629
|
(thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || thread.preview?.toLowerCase().includes(searchQuery.toLowerCase())
|
|
4406
4630
|
);
|