@apteva/apteva-kit 0.1.68 → 0.1.70

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.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 useState4, useEffect as useEffect4, useRef as useRef5, useMemo as useMemo2, forwardRef, useImperativeHandle } from "react";
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 useEffect3, useRef as useRef2 } from "react";
10
+ import { useEffect as useEffect5, useRef as useRef4 } from "react";
11
11
 
12
12
  // src/components/Chat/Message.tsx
13
- import { useEffect as useEffect2, useRef, useMemo } from "react";
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
- processText = text.slice(0, lastWidgetStart);
567
- pendingWidgetType = widgetType;
568
- hasPendingWidget = true;
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
- return /* @__PURE__ */ jsx2("div", { className: "border border-neutral-200 dark:border-neutral-700 rounded-xl bg-white dark:bg-neutral-900 overflow-hidden", children: items.map((item, index) => /* @__PURE__ */ jsxs2(
735
- "div",
736
- {
737
- className: `flex items-center p-4 transition-colors ${index !== items.length - 1 ? "border-b border-neutral-200 dark:border-neutral-700" : ""} ${!item.backgroundColor ? "hover:bg-neutral-50 dark:hover:bg-neutral-800" : ""}`,
738
- style: item.backgroundColor ? { backgroundColor: item.backgroundColor } : void 0,
739
- children: [
740
- item.image && /* @__PURE__ */ jsx2("img", { src: item.image, alt: item.title, className: "w-16 h-16 rounded object-cover" }),
741
- /* @__PURE__ */ jsxs2("div", { className: `flex-1 ${item.image ? "ml-4" : ""}`, children: [
742
- /* @__PURE__ */ jsx2("h4", { className: "font-semibold !text-neutral-900 dark:!text-white", children: item.title }),
743
- item.subtitle && /* @__PURE__ */ jsx2("p", { className: "!text-sm !text-neutral-600 dark:!text-neutral-400", children: item.subtitle }),
744
- item.description && /* @__PURE__ */ jsx2("p", { className: "!text-xs !text-neutral-500 dark:!text-neutral-500 mt-1", children: item.description })
745
- ] }),
746
- widget.actions && widget.actions.length > 0 && /* @__PURE__ */ jsx2("div", { className: "flex gap-2", children: widget.actions.map((action, idx) => /* @__PURE__ */ jsx2(
747
- "button",
748
- {
749
- onClick: () => onAction?.({
750
- type: action.type,
751
- payload: item.metadata || item,
752
- widgetId: widget.id,
753
- timestamp: /* @__PURE__ */ new Date()
754
- }),
755
- className: "px-3 py-1.5 !text-sm rounded-lg font-medium transition-colors bg-blue-500 !text-white hover:bg-blue-600",
756
- children: action.label
757
- },
758
- idx
759
- )) })
760
- ]
761
- },
762
- item.id
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) => /* @__PURE__ */ jsx5(
872
- "tr",
873
- {
874
- className: cn(
875
- "border-b border-neutral-200 dark:border-neutral-700 last:border-b-0",
876
- "transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-800",
877
- striped && rowIndex % 2 === 1 && "bg-neutral-50/50 dark:bg-neutral-800/50"
878
- ),
879
- onClick: () => {
880
- if (widget.actions && widget.actions.length > 0) {
881
- onAction?.({
882
- type: widget.actions[0].type,
883
- payload: row,
884
- widgetId: widget.id,
885
- timestamp: /* @__PURE__ */ new Date()
886
- });
887
- }
888
- },
889
- style: { cursor: widget.actions?.length ? "pointer" : "default" },
890
- children: columns.map((column) => /* @__PURE__ */ jsx5(
891
- "td",
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
- column.key
901
- ))
902
- },
903
- row.id || rowIndex
904
- )),
905
- rows.length === 0 && /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5(
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] = useState(() => {
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
- useEffect(() => {
1245
+ useEffect3(() => {
1073
1246
  widgets.forEach((widget) => {
1074
1247
  onWidgetMount?.(widget.id);
1075
1248
  });
@@ -1377,7 +1550,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
1377
1550
  const contentSegments = message.metadata?.content_segments;
1378
1551
  const isStreaming = message.metadata?.isStreaming === true;
1379
1552
  const hasContent = message.content || contentSegments && contentSegments.length > 0;
1380
- const reportedWidgetsRef = useRef(/* @__PURE__ */ new Set());
1553
+ const reportedWidgetsRef = useRef3(/* @__PURE__ */ new Set());
1381
1554
  const parsedWidgets = useMemo(() => {
1382
1555
  if (!enableWidgets || isUser || !message.content) {
1383
1556
  return [];
@@ -1385,7 +1558,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
1385
1558
  const parsed = parseWidgetsFromText(message.content);
1386
1559
  return parsed.segments.filter((seg) => seg.type === "widget" && !!seg.widget).map((seg) => seg.widget);
1387
1560
  }, [enableWidgets, isUser, message.content]);
1388
- useEffect2(() => {
1561
+ useEffect4(() => {
1389
1562
  if (onWidgetRender && message.widgets) {
1390
1563
  for (const widget of message.widgets) {
1391
1564
  if (!reportedWidgetsRef.current.has(widget.id)) {
@@ -1395,7 +1568,7 @@ function Message({ message, onAction, enableWidgets, onWidgetRender }) {
1395
1568
  }
1396
1569
  }
1397
1570
  }, [message.widgets, onWidgetRender]);
1398
- useEffect2(() => {
1571
+ useEffect4(() => {
1399
1572
  if (onWidgetRender && parsedWidgets.length > 0) {
1400
1573
  for (const widget of parsedWidgets) {
1401
1574
  if (!reportedWidgetsRef.current.has(widget.id)) {
@@ -1767,16 +1940,16 @@ function MessageList({
1767
1940
  enableWidgets,
1768
1941
  onWidgetRender
1769
1942
  }) {
1770
- const listRef = useRef2(null);
1771
- const isNearBottomRef = useRef2(true);
1772
- const lastScrollHeightRef = useRef2(0);
1943
+ const listRef = useRef4(null);
1944
+ const isNearBottomRef = useRef4(true);
1945
+ const lastScrollHeightRef = useRef4(0);
1773
1946
  const handleScroll = () => {
1774
1947
  if (listRef.current) {
1775
1948
  const { scrollTop, scrollHeight, clientHeight } = listRef.current;
1776
1949
  isNearBottomRef.current = scrollHeight - scrollTop - clientHeight < 100;
1777
1950
  }
1778
1951
  };
1779
- useEffect3(() => {
1952
+ useEffect5(() => {
1780
1953
  if (listRef.current && isNearBottomRef.current) {
1781
1954
  const currentScrollHeight = listRef.current.scrollHeight;
1782
1955
  if (currentScrollHeight !== lastScrollHeightRef.current) {
@@ -1800,16 +1973,16 @@ function MessageList({
1800
1973
  }
1801
1974
 
1802
1975
  // src/components/Chat/Composer.tsx
1803
- import { useState as useState2, useRef as useRef3 } from "react";
1976
+ import { useState as useState4, useRef as useRef5 } from "react";
1804
1977
  import { Fragment, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
1805
1978
  function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, isLoading = false, onStop, onFileUpload, onSwitchMode }) {
1806
- const [text, setText] = useState2("");
1807
- const [showMenu, setShowMenu] = useState2(false);
1808
- const [pendingFiles, setPendingFiles] = useState2([]);
1809
- const [fileError, setFileError] = useState2(null);
1810
- const textareaRef = useRef3(null);
1811
- const fileInputRef = useRef3(null);
1812
- const menuButtonRef = useRef3(null);
1979
+ const [text, setText] = useState4("");
1980
+ const [showMenu, setShowMenu] = useState4(false);
1981
+ const [pendingFiles, setPendingFiles] = useState4([]);
1982
+ const [fileError, setFileError] = useState4(null);
1983
+ const textareaRef = useRef5(null);
1984
+ const fileInputRef = useRef5(null);
1985
+ const menuButtonRef = useRef5(null);
1813
1986
  const handleKeyDown = (e) => {
1814
1987
  if (e.key === "Enter" && !e.shiftKey) {
1815
1988
  e.preventDefault();
@@ -1975,9 +2148,8 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
1975
2148
  onKeyDown: handleKeyDown,
1976
2149
  placeholder,
1977
2150
  disabled,
1978
- className: "apteva-composer-textarea flex-1 resize-none bg-transparent border-none focus:outline-none !text-neutral-900 dark:!text-neutral-100 placeholder-neutral-400 dark:placeholder-neutral-500 py-1 disabled:opacity-50 disabled:cursor-not-allowed overflow-y-auto",
1979
- rows: 1,
1980
- style: { maxHeight: "120px" }
2151
+ className: "apteva-composer-textarea flex-1 resize-none bg-transparent border-none focus:outline-none !text-neutral-900 dark:!text-neutral-100 placeholder-neutral-400 dark:placeholder-neutral-500 py-1 disabled:opacity-50 disabled:cursor-not-allowed overflow-hidden",
2152
+ rows: 1
1981
2153
  }
1982
2154
  ),
1983
2155
  isLoading && onStop ? /* @__PURE__ */ jsx15(
@@ -2014,7 +2186,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
2014
2186
  }
2015
2187
 
2016
2188
  // src/components/Chat/CommandComposer.tsx
2017
- import { useState as useState3, useRef as useRef4 } from "react";
2189
+ import { useState as useState5, useRef as useRef6 } from "react";
2018
2190
  import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2019
2191
  function CommandComposer({
2020
2192
  onExecute,
@@ -2032,13 +2204,13 @@ function CommandComposer({
2032
2204
  placeholder = "Enter your command...",
2033
2205
  disabled = false
2034
2206
  }) {
2035
- const [input, setInput] = useState3("");
2036
- const [pendingFiles, setPendingFiles] = useState3([]);
2037
- const [fileError, setFileError] = useState3(null);
2038
- const [showMenu, setShowMenu] = useState3(false);
2039
- const inputRef = useRef4(null);
2040
- const fileInputRef = useRef4(null);
2041
- const menuButtonRef = useRef4(null);
2207
+ const [input, setInput] = useState5("");
2208
+ const [pendingFiles, setPendingFiles] = useState5([]);
2209
+ const [fileError, setFileError] = useState5(null);
2210
+ const [showMenu, setShowMenu] = useState5(false);
2211
+ const inputRef = useRef6(null);
2212
+ const fileInputRef = useRef6(null);
2213
+ const menuButtonRef = useRef6(null);
2042
2214
  const handleSubmit = () => {
2043
2215
  const hasText = input.trim();
2044
2216
  const hasFiles = pendingFiles.length > 0;
@@ -2567,25 +2739,25 @@ var Chat = forwardRef(function Chat2({
2567
2739
  onWidgetRender,
2568
2740
  className
2569
2741
  }, ref) {
2570
- const [messages, setMessages] = useState4(initialMessages);
2571
- const [isLoading, setIsLoading] = useState4(false);
2572
- const [currentThreadId, setCurrentThreadId] = useState4(threadId || null);
2573
- const [mode, setMode] = useState4(initialMode);
2574
- const [chatToolName, setChatToolName] = useState4(null);
2575
- const [commandState, setCommandState] = useState4("idle");
2576
- const [commandResult, setCommandResult] = useState4(null);
2577
- const [commandError, setCommandError] = useState4(null);
2578
- const [progress, setProgress] = useState4(0);
2579
- const [commandInput, setCommandInput] = useState4("");
2580
- const [streamedContent, setStreamedContent] = useState4("");
2581
- const [currentToolName, setCurrentToolName] = useState4(null);
2582
- const [currentRequestId, setCurrentRequestId] = useState4(null);
2583
- const [plan, setPlan] = useState4("");
2584
- const [pendingCommand, setPendingCommand] = useState4("");
2585
- const [internalPlanMode, setInternalPlanMode] = useState4(planMode);
2586
- const [showSettingsMenu, setShowSettingsMenu] = useState4(false);
2587
- const fileInputRef = useRef5(null);
2588
- const handleSendMessageRef = useRef5(null);
2742
+ const [messages, setMessages] = useState6(initialMessages);
2743
+ const [isLoading, setIsLoading] = useState6(false);
2744
+ const [currentThreadId, setCurrentThreadId] = useState6(threadId || null);
2745
+ const [mode, setMode] = useState6(initialMode);
2746
+ const [chatToolName, setChatToolName] = useState6(null);
2747
+ const [commandState, setCommandState] = useState6("idle");
2748
+ const [commandResult, setCommandResult] = useState6(null);
2749
+ const [commandError, setCommandError] = useState6(null);
2750
+ const [progress, setProgress] = useState6(0);
2751
+ const [commandInput, setCommandInput] = useState6("");
2752
+ const [streamedContent, setStreamedContent] = useState6("");
2753
+ const [currentToolName, setCurrentToolName] = useState6(null);
2754
+ const [currentRequestId, setCurrentRequestId] = useState6(null);
2755
+ const [plan, setPlan] = useState6("");
2756
+ const [pendingCommand, setPendingCommand] = useState6("");
2757
+ const [internalPlanMode, setInternalPlanMode] = useState6(planMode);
2758
+ const [showSettingsMenu, setShowSettingsMenu] = useState6(false);
2759
+ const fileInputRef = useRef7(null);
2760
+ const handleSendMessageRef = useRef7(null);
2589
2761
  useImperativeHandle(ref, () => ({
2590
2762
  sendMessage: async (text) => {
2591
2763
  if (handleSendMessageRef.current) {
@@ -2606,7 +2778,7 @@ var Chat = forwardRef(function Chat2({
2606
2778
  return context ? `${context}
2607
2779
  ${widgetContext}` : widgetContext;
2608
2780
  }, [context, enableWidgets, availableWidgets, compactWidgetContext]);
2609
- useEffect4(() => {
2781
+ useEffect6(() => {
2610
2782
  if (apiUrl || apiKey) {
2611
2783
  aptevaClient.configure({
2612
2784
  ...apiUrl && { apiUrl },
@@ -2614,15 +2786,15 @@ ${widgetContext}` : widgetContext;
2614
2786
  });
2615
2787
  }
2616
2788
  }, [apiUrl, apiKey]);
2617
- useEffect4(() => {
2789
+ useEffect6(() => {
2618
2790
  if (threadId) {
2619
2791
  onThreadChange?.(threadId);
2620
2792
  }
2621
2793
  }, [threadId, onThreadChange]);
2622
- useEffect4(() => {
2794
+ useEffect6(() => {
2623
2795
  setInternalPlanMode(planMode);
2624
2796
  }, [planMode]);
2625
- useEffect4(() => {
2797
+ useEffect6(() => {
2626
2798
  const handleClickOutside = (event) => {
2627
2799
  const target = event.target;
2628
2800
  if (showSettingsMenu && !target.closest(".settings-menu-container")) {
@@ -3154,11 +3326,11 @@ ${planToExecute}`;
3154
3326
  });
3155
3327
 
3156
3328
  // src/components/Chat/CommandOutput.tsx
3157
- import { useState as useState5 } from "react";
3329
+ import { useState as useState7 } from "react";
3158
3330
  import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
3159
3331
 
3160
3332
  // src/components/Command/Command.tsx
3161
- import React, { useState as useState6, useEffect as useEffect5 } from "react";
3333
+ import React, { useState as useState8, useEffect as useEffect7 } from "react";
3162
3334
  import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
3163
3335
  function Command({
3164
3336
  agentId,
@@ -3186,28 +3358,28 @@ function Command({
3186
3358
  resultRenderer,
3187
3359
  className
3188
3360
  }) {
3189
- const [state, setState] = useState6("idle");
3190
- const [result, setResult] = useState6(null);
3191
- const [error, setError] = useState6(null);
3192
- const [progress, setProgress] = useState6(0);
3193
- const [command, setCommand] = useState6(initialCommand || "");
3194
- const [streamedContent, setStreamedContent] = useState6("");
3195
- const [plan, setPlan] = useState6("");
3196
- const [pendingCommand, setPendingCommand] = useState6("");
3197
- const [showPlanDetails, setShowPlanDetails] = useState6(false);
3198
- const [uploadedFiles, setUploadedFiles] = useState6([]);
3199
- const [showSettingsMenu, setShowSettingsMenu] = useState6(false);
3200
- const [internalPlanMode, setInternalPlanMode] = useState6(planMode);
3361
+ const [state, setState] = useState8("idle");
3362
+ const [result, setResult] = useState8(null);
3363
+ const [error, setError] = useState8(null);
3364
+ const [progress, setProgress] = useState8(0);
3365
+ const [command, setCommand] = useState8(initialCommand || "");
3366
+ const [streamedContent, setStreamedContent] = useState8("");
3367
+ const [plan, setPlan] = useState8("");
3368
+ const [pendingCommand, setPendingCommand] = useState8("");
3369
+ const [showPlanDetails, setShowPlanDetails] = useState8(false);
3370
+ const [uploadedFiles, setUploadedFiles] = useState8([]);
3371
+ const [showSettingsMenu, setShowSettingsMenu] = useState8(false);
3372
+ const [internalPlanMode, setInternalPlanMode] = useState8(planMode);
3201
3373
  const fileInputRef = React.useRef(null);
3202
- useEffect5(() => {
3374
+ useEffect7(() => {
3203
3375
  if (autoExecute && state === "idle" && command) {
3204
3376
  executeCommand();
3205
3377
  }
3206
3378
  }, [autoExecute]);
3207
- useEffect5(() => {
3379
+ useEffect7(() => {
3208
3380
  setInternalPlanMode(planMode);
3209
3381
  }, [planMode]);
3210
- useEffect5(() => {
3382
+ useEffect7(() => {
3211
3383
  const handleClickOutside = (event) => {
3212
3384
  const target = event.target;
3213
3385
  if (showSettingsMenu && !target.closest(".settings-menu-container")) {
@@ -4129,7 +4301,7 @@ ${planToExecute}`;
4129
4301
  }
4130
4302
 
4131
4303
  // src/components/Prompt/Prompt.tsx
4132
- import { useState as useState7 } from "react";
4304
+ import { useState as useState9 } from "react";
4133
4305
  import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
4134
4306
  function Prompt({
4135
4307
  agentId,
@@ -4147,9 +4319,9 @@ function Prompt({
4147
4319
  showSuggestions = false,
4148
4320
  className
4149
4321
  }) {
4150
- const [value, setValue] = useState7(initialValue);
4151
- const [isLoading, setIsLoading] = useState7(false);
4152
- const [suggestions] = useState7(["Plan a trip", "Write a description", "Analyze data"]);
4322
+ const [value, setValue] = useState9(initialValue);
4323
+ const [isLoading, setIsLoading] = useState9(false);
4324
+ const [suggestions] = useState9(["Plan a trip", "Write a description", "Analyze data"]);
4153
4325
  const handleChange = (e) => {
4154
4326
  const newValue = e.target.value;
4155
4327
  if (!maxLength || newValue.length <= maxLength) {
@@ -4240,7 +4412,7 @@ function Prompt({
4240
4412
  }
4241
4413
 
4242
4414
  // src/components/Stream/Stream.tsx
4243
- import { useState as useState8, useEffect as useEffect6 } from "react";
4415
+ import { useState as useState10, useEffect as useEffect8 } from "react";
4244
4416
  import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
4245
4417
  function Stream({
4246
4418
  agentId,
@@ -4257,10 +4429,10 @@ function Stream({
4257
4429
  typingSpeed = 30,
4258
4430
  className
4259
4431
  }) {
4260
- const [text, setText] = useState8("");
4261
- const [isStreaming, setIsStreaming] = useState8(false);
4262
- const [isComplete, setIsComplete] = useState8(false);
4263
- useEffect6(() => {
4432
+ const [text, setText] = useState10("");
4433
+ const [isStreaming, setIsStreaming] = useState10(false);
4434
+ const [isComplete, setIsComplete] = useState10(false);
4435
+ useEffect8(() => {
4264
4436
  if (autoStart && !isStreaming && !isComplete) {
4265
4437
  startStreaming();
4266
4438
  }
@@ -4337,7 +4509,7 @@ function Stream({
4337
4509
  }
4338
4510
 
4339
4511
  // src/components/Threads/ThreadList.tsx
4340
- import { useState as useState9 } from "react";
4512
+ import { useState as useState11 } from "react";
4341
4513
 
4342
4514
  // src/components/Threads/ThreadItem.tsx
4343
4515
  import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -4401,7 +4573,7 @@ function ThreadList({
4401
4573
  showSearch = false,
4402
4574
  groupBy = "none"
4403
4575
  }) {
4404
- const [searchQuery, setSearchQuery] = useState9("");
4576
+ const [searchQuery, setSearchQuery] = useState11("");
4405
4577
  const filteredThreads = threads.filter(
4406
4578
  (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || thread.preview?.toLowerCase().includes(searchQuery.toLowerCase())
4407
4579
  );