@apteva/apteva-kit 0.1.17 → 0.1.18

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.js CHANGED
@@ -498,6 +498,237 @@ function validateFile(file) {
498
498
  return { valid: true };
499
499
  }
500
500
 
501
+ // src/utils/widget-parser.ts
502
+ function findMatchingBracket(text, startIndex) {
503
+ let depth = 0;
504
+ let inString = false;
505
+ let escapeNext = false;
506
+ for (let i = startIndex; i < text.length; i++) {
507
+ const char = text[i];
508
+ if (escapeNext) {
509
+ escapeNext = false;
510
+ continue;
511
+ }
512
+ if (char === "\\" && inString) {
513
+ escapeNext = true;
514
+ continue;
515
+ }
516
+ if (char === '"') {
517
+ inString = !inString;
518
+ continue;
519
+ }
520
+ if (inString) continue;
521
+ if (char === "[" || char === "{") {
522
+ depth++;
523
+ } else if (char === "]" || char === "}") {
524
+ depth--;
525
+ if (depth === 0) {
526
+ return i;
527
+ }
528
+ }
529
+ }
530
+ return -1;
531
+ }
532
+ function parseWidgetsFromText(text) {
533
+ const segments = [];
534
+ let hasWidgets = false;
535
+ let hasPendingWidget = false;
536
+ let currentIndex = 0;
537
+ let pendingWidgetType = null;
538
+ let processText = text;
539
+ const lastWidgetStart = text.lastIndexOf("@ui:");
540
+ if (lastWidgetStart !== -1) {
541
+ const afterStart = text.slice(lastWidgetStart);
542
+ const typeMatch = afterStart.match(/^@ui:(\w+)/);
543
+ if (typeMatch) {
544
+ const widgetType = typeMatch[1];
545
+ const bracketOpenIndex = afterStart.indexOf("[");
546
+ if (bracketOpenIndex === -1) {
547
+ processText = text.slice(0, lastWidgetStart);
548
+ pendingWidgetType = widgetType;
549
+ hasPendingWidget = true;
550
+ } else {
551
+ const fullBracketStart = lastWidgetStart + bracketOpenIndex;
552
+ const bracketEnd = findMatchingBracket(text, fullBracketStart);
553
+ if (bracketEnd === -1) {
554
+ processText = text.slice(0, lastWidgetStart);
555
+ pendingWidgetType = widgetType;
556
+ hasPendingWidget = true;
557
+ }
558
+ }
559
+ }
560
+ }
561
+ if (hasPendingWidget) {
562
+ processText = processText.replace(/[\s:;\-–—\.]+$/g, "");
563
+ }
564
+ const startPattern = /@ui:(\w+)\[/g;
565
+ let match;
566
+ while ((match = startPattern.exec(processText)) !== null) {
567
+ const widgetType = match[1];
568
+ const bracketStart = match.index + match[0].length - 1;
569
+ const bracketEnd = findMatchingBracket(processText, bracketStart);
570
+ if (bracketEnd === -1) {
571
+ continue;
572
+ }
573
+ const jsonContent = processText.slice(bracketStart + 1, bracketEnd);
574
+ if (match.index > currentIndex) {
575
+ const textContent = processText.slice(currentIndex, match.index).trim();
576
+ if (textContent) {
577
+ segments.push({
578
+ type: "text",
579
+ content: textContent
580
+ });
581
+ }
582
+ }
583
+ try {
584
+ const trimmedJson = jsonContent.trim();
585
+ const props = JSON.parse(trimmedJson);
586
+ const widgetId = `widget-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
587
+ segments.push({
588
+ type: "widget",
589
+ widget: {
590
+ type: widgetType,
591
+ id: widgetId,
592
+ props
593
+ }
594
+ });
595
+ hasWidgets = true;
596
+ } catch (e) {
597
+ }
598
+ currentIndex = bracketEnd + 1;
599
+ startPattern.lastIndex = currentIndex;
600
+ }
601
+ if (currentIndex < processText.length) {
602
+ const remainingText = processText.slice(currentIndex).trim();
603
+ if (remainingText) {
604
+ segments.push({
605
+ type: "text",
606
+ content: remainingText
607
+ });
608
+ }
609
+ }
610
+ if (segments.length === 0 && processText.trim()) {
611
+ segments.push({
612
+ type: "text",
613
+ content: processText.trim()
614
+ });
615
+ }
616
+ if (pendingWidgetType) {
617
+ segments.push({
618
+ type: "widget_pending",
619
+ pendingType: pendingWidgetType
620
+ });
621
+ }
622
+ return { segments, hasWidgets, hasPendingWidget };
623
+ }
624
+
625
+ // src/utils/widget-context.ts
626
+ var WIDGET_DEFINITIONS = {
627
+ card: {
628
+ description: "Displays a card with title and optional description, image, footer",
629
+ schema: '{"title": "string", "description?": "string", "image?": "url", "footer?": "string"}',
630
+ example: '@ui:card[{"title": "Summary", "description": "Key findings from the analysis"}]'
631
+ },
632
+ list: {
633
+ description: "Displays a list of items with title, subtitle, and optional description",
634
+ schema: '{"items": [{"id": "string", "title": "string", "subtitle?": "string", "description?": "string", "image?": "url"}]}',
635
+ example: '@ui:list[{"items": [{"id": "1", "title": "First item", "subtitle": "Details"}]}]'
636
+ },
637
+ button_group: {
638
+ description: "Displays action buttons. User clicks are sent back to you with the button id",
639
+ schema: '{"buttons": [{"id": "string", "label": "string", "variant?": "primary|secondary|outline"}], "layout?": "horizontal|vertical"}',
640
+ example: '@ui:button_group[{"buttons": [{"id": "confirm", "label": "Confirm", "variant": "primary"}, {"id": "cancel", "label": "Cancel"}]}]'
641
+ },
642
+ form: {
643
+ description: "Displays an input form. Submitted data is sent back to you",
644
+ schema: '{"title?": "string", "fields": [{"name": "string", "type": "text|number|select|checkbox|textarea|date", "label": "string", "required?": boolean, "placeholder?": "string", "options?": [{"label": "string", "value": "string"}]}]}',
645
+ example: '@ui:form[{"title": "Contact", "fields": [{"name": "email", "type": "text", "label": "Email", "required": true}]}]'
646
+ },
647
+ image: {
648
+ description: "Displays a single image with optional caption",
649
+ schema: '{"src": "url", "alt": "string", "caption?": "string"}',
650
+ example: '@ui:image[{"src": "https://example.com/img.png", "alt": "Description", "caption": "Figure 1"}]'
651
+ },
652
+ gallery: {
653
+ description: "Displays multiple images in a grid or carousel layout",
654
+ schema: '{"images": [{"id": "string", "src": "url", "alt": "string", "caption?": "string"}], "layout?": "grid|carousel"}',
655
+ example: '@ui:gallery[{"images": [{"id": "1", "src": "https://example.com/1.png", "alt": "Image 1"}], "layout": "grid"}]'
656
+ },
657
+ chart: {
658
+ description: "Displays a chart visualization (line, bar, pie, doughnut)",
659
+ schema: '{"chartType": "line|bar|pie|doughnut", "title?": "string", "data": {"labels": ["string"], "datasets": [{"label": "string", "data": [number], "backgroundColor?": "string|string[]"}]}}',
660
+ example: '@ui:chart[{"chartType": "bar", "title": "Sales", "data": {"labels": ["Q1", "Q2"], "datasets": [{"label": "Revenue", "data": [100, 150]}]}}]'
661
+ },
662
+ map: {
663
+ description: "Displays an interactive map with optional markers",
664
+ schema: '{"center": {"lat": number, "lng": number}, "zoom?": number, "markers?": [{"id": "string", "position": {"lat": number, "lng": number}, "title": "string"}]}',
665
+ example: '@ui:map[{"center": {"lat": 40.7128, "lng": -74.0060}, "zoom": 12, "markers": [{"id": "1", "position": {"lat": 40.7128, "lng": -74.0060}, "title": "NYC"}]}]'
666
+ },
667
+ table: {
668
+ description: "Displays structured data in rows and columns",
669
+ schema: '{"columns": [{"key": "string", "label": "string", "align?": "left|center|right"}], "rows": [{"id?": "string", ...}], "caption?": "string", "compact?": boolean, "striped?": boolean}',
670
+ example: '@ui:table[{"columns": [{"key": "name", "label": "Name"}, {"key": "status", "label": "Status"}], "rows": [{"name": "Item 1", "status": "Active"}, {"name": "Item 2", "status": "Pending"}]}]'
671
+ }
672
+ };
673
+ var ALL_WIDGET_TYPES = Object.keys(WIDGET_DEFINITIONS);
674
+ function generateWidgetContext(enabledWidgets) {
675
+ const widgets = enabledWidgets || ALL_WIDGET_TYPES;
676
+ let context = `
677
+ ## Available UI Widgets
678
+
679
+ `;
680
+ context += `You can render rich UI components in your responses using this syntax: @ui:type[{json_props}]
681
+
682
+ `;
683
+ context += `The widget syntax will be automatically converted to interactive UI. Users see the rendered widget, not the raw syntax.
684
+
685
+ `;
686
+ context += `### Available widgets:
687
+
688
+ `;
689
+ for (const type of widgets) {
690
+ const def = WIDGET_DEFINITIONS[type];
691
+ if (!def) continue;
692
+ context += `**${type}** - ${def.description}
693
+ `;
694
+ context += `Schema: \`${def.schema}\`
695
+ `;
696
+ context += `Example: \`${def.example}\`
697
+
698
+ `;
699
+ }
700
+ context += `### Important notes:
701
+ `;
702
+ context += `- JSON must be valid (use double quotes for strings)
703
+ `;
704
+ context += `- Widget actions (button clicks, form submissions) are sent back to you
705
+ `;
706
+ context += `- You can include multiple widgets in a single response
707
+ `;
708
+ context += `- Combine widgets with regular text for context
709
+ `;
710
+ return context;
711
+ }
712
+ function generateCompactWidgetContext(enabledWidgets) {
713
+ const widgets = enabledWidgets || ALL_WIDGET_TYPES;
714
+ let context = `
715
+ UI Widgets: Use @ui:type[{props}] syntax.
716
+ `;
717
+ context += `Available: ${widgets.join(", ")}
718
+ `;
719
+ context += `Examples:
720
+ `;
721
+ const examples = ["card", "list", "button_group"].filter((w) => widgets.includes(w));
722
+ for (const type of examples) {
723
+ const def = WIDGET_DEFINITIONS[type];
724
+ if (def) {
725
+ context += `${def.example}
726
+ `;
727
+ }
728
+ }
729
+ return context;
730
+ }
731
+
501
732
  // src/components/Widgets/Widgets.tsx
502
733
 
503
734
 
@@ -642,6 +873,82 @@ function ButtonGroup({ widget, onAction }) {
642
873
  );
643
874
  }
644
875
 
876
+ // src/components/Widgets/widget-library/Table.tsx
877
+
878
+ function Table({ widget, onAction }) {
879
+ const { columns, rows, caption, compact = false, striped = false } = widget.props;
880
+ const getAlignment = (align) => {
881
+ switch (align) {
882
+ case "center":
883
+ return "text-center";
884
+ case "right":
885
+ return "text-right";
886
+ default:
887
+ return "text-left";
888
+ }
889
+ };
890
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-900 overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-x-auto", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { className: "w-full", children: [
891
+ caption && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "caption", { className: "px-4 py-2 text-sm text-gray-600 dark:text-gray-400 text-left bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: caption }),
892
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: columns.map((column) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
893
+ "th",
894
+ {
895
+ className: cn(
896
+ "font-semibold text-gray-900 dark:text-white",
897
+ compact ? "px-3 py-2 text-xs" : "px-4 py-3 text-sm",
898
+ getAlignment(column.align)
899
+ ),
900
+ style: column.width ? { width: column.width } : void 0,
901
+ children: column.label
902
+ },
903
+ column.key
904
+ )) }) }),
905
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { children: [
906
+ rows.map((row, rowIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
907
+ "tr",
908
+ {
909
+ className: cn(
910
+ "border-b border-gray-200 dark:border-gray-700 last:border-b-0",
911
+ "transition-colors hover:bg-gray-50 dark:hover:bg-gray-800",
912
+ striped && rowIndex % 2 === 1 && "bg-gray-50/50 dark:bg-gray-800/50"
913
+ ),
914
+ onClick: () => {
915
+ if (widget.actions && widget.actions.length > 0) {
916
+ _optionalChain([onAction, 'optionalCall', _15 => _15({
917
+ type: widget.actions[0].type,
918
+ payload: row,
919
+ widgetId: widget.id,
920
+ timestamp: /* @__PURE__ */ new Date()
921
+ })]);
922
+ }
923
+ },
924
+ style: { cursor: _optionalChain([widget, 'access', _16 => _16.actions, 'optionalAccess', _17 => _17.length]) ? "pointer" : "default" },
925
+ children: columns.map((column) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
926
+ "td",
927
+ {
928
+ className: cn(
929
+ "text-gray-700 dark:text-gray-300",
930
+ compact ? "px-3 py-2 text-xs" : "px-4 py-3 text-sm",
931
+ getAlignment(column.align)
932
+ ),
933
+ children: _nullishCoalesce(row[column.key], () => ( "\u2014"))
934
+ },
935
+ column.key
936
+ ))
937
+ },
938
+ row.id || rowIndex
939
+ )),
940
+ rows.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
941
+ "td",
942
+ {
943
+ colSpan: columns.length,
944
+ className: "px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400",
945
+ children: "No data available"
946
+ }
947
+ ) })
948
+ ] })
949
+ ] }) }) });
950
+ }
951
+
645
952
  // src/components/Widgets/WidgetRenderer.tsx
646
953
 
647
954
  function WidgetRenderer({ widget, onAction }) {
@@ -654,6 +961,8 @@ function WidgetRenderer({ widget, onAction }) {
654
961
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { widget, onAction });
655
962
  case "button_group":
656
963
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ButtonGroup, { widget, onAction });
964
+ case "table":
965
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Table, { widget, onAction });
657
966
  default:
658
967
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-4 border border-yellow-300 bg-yellow-50 rounded-lg", children: [
659
968
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-yellow-800", children: [
@@ -678,7 +987,7 @@ function Widgets({
678
987
  }) {
679
988
  _react.useEffect.call(void 0, () => {
680
989
  widgets.forEach((widget) => {
681
- _optionalChain([onWidgetMount, 'optionalCall', _15 => _15(widget.id)]);
990
+ _optionalChain([onWidgetMount, 'optionalCall', _18 => _18(widget.id)]);
682
991
  });
683
992
  }, [widgets, onWidgetMount]);
684
993
  const layoutClasses = {
@@ -694,6 +1003,80 @@ function Widgets({
694
1003
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn(layoutClasses[layout], spacingClasses[spacing], className), children: widgets.map((widget) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WidgetRenderer, { widget, onAction }, widget.id)) });
695
1004
  }
696
1005
 
1006
+ // src/components/Widgets/WidgetSkeleton.tsx
1007
+
1008
+ function WidgetSkeleton({ type, className }) {
1009
+ switch (type) {
1010
+ case "card":
1011
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("animate-pulse rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden", className), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-4 space-y-3", children: [
1012
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-3/4" }),
1013
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-full" }),
1014
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-5/6" })
1015
+ ] }) });
1016
+ case "list":
1017
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("animate-pulse space-y-2", className), children: [1, 2, 3].map((i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 p-3 rounded-lg border border-gray-200 dark:border-gray-700", children: [
1018
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-10 h-10 bg-gray-200 dark:bg-gray-700 rounded-full flex-shrink-0" }),
1019
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 space-y-2", children: [
1020
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-1/2" }),
1021
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-2 bg-gray-200 dark:bg-gray-700 rounded w-3/4" })
1022
+ ] })
1023
+ ] }, i)) });
1024
+ case "button_group":
1025
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("animate-pulse flex gap-2", className), children: [
1026
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-9 bg-gray-200 dark:bg-gray-700 rounded-lg w-20" }),
1027
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-9 bg-gray-200 dark:bg-gray-700 rounded-lg w-20" }),
1028
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-9 bg-gray-200 dark:bg-gray-700 rounded-lg w-20" })
1029
+ ] });
1030
+ case "form":
1031
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("animate-pulse rounded-lg border border-gray-200 dark:border-gray-700 p-4 space-y-4", className), children: [
1032
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/3" }),
1033
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
1034
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" }),
1035
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-10 bg-gray-200 dark:bg-gray-700 rounded" })
1036
+ ] }),
1037
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-9 bg-gray-200 dark:bg-gray-700 rounded w-24" })
1038
+ ] });
1039
+ case "chart":
1040
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("animate-pulse rounded-lg border border-gray-200 dark:border-gray-700 p-4", className), children: [
1041
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/4 mb-4" }),
1042
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-end gap-2 h-32", children: [
1043
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 bg-gray-200 dark:bg-gray-700 rounded-t h-1/2" }),
1044
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 bg-gray-200 dark:bg-gray-700 rounded-t h-3/4" }),
1045
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 bg-gray-200 dark:bg-gray-700 rounded-t h-1/3" }),
1046
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 bg-gray-200 dark:bg-gray-700 rounded-t h-full" }),
1047
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 bg-gray-200 dark:bg-gray-700 rounded-t h-2/3" })
1048
+ ] })
1049
+ ] });
1050
+ case "image":
1051
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("animate-pulse", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "aspect-video bg-gray-200 dark:bg-gray-700 rounded-lg" }) });
1052
+ case "gallery":
1053
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("animate-pulse grid grid-cols-3 gap-2", className), children: [1, 2, 3].map((i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "aspect-square bg-gray-200 dark:bg-gray-700 rounded-lg" }, i)) });
1054
+ case "map":
1055
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("animate-pulse", className), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-48 bg-gray-200 dark:bg-gray-700 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { className: "w-8 h-8 text-gray-300 dark:text-gray-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
1056
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" }),
1057
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M15 11a3 3 0 11-6 0 3 3 0 016 0z" })
1058
+ ] }) }) });
1059
+ case "table":
1060
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("animate-pulse rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden", className), children: [
1061
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: [
1062
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-300 dark:bg-gray-600 rounded w-16" }) }),
1063
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-300 dark:bg-gray-600 rounded w-20" }) }),
1064
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-300 dark:bg-gray-600 rounded w-14" }) })
1065
+ ] }),
1066
+ [1, 2, 3].map((i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex border-b border-gray-200 dark:border-gray-700 last:border-b-0", children: [
1067
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-24" }) }),
1068
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-16" }) }),
1069
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 px-4 py-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-20" }) })
1070
+ ] }, i))
1071
+ ] });
1072
+ default:
1073
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("animate-pulse rounded-lg border border-gray-200 dark:border-gray-700 p-4", className), children: [
1074
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2 mb-2" }),
1075
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-3 bg-gray-200 dark:bg-gray-700 rounded w-full" })
1076
+ ] });
1077
+ }
1078
+ }
1079
+
697
1080
  // src/components/Chat/MarkdownContent.tsx
698
1081
 
699
1082
  function parseInlineMarkdown(text, keyPrefix = "") {
@@ -838,9 +1221,30 @@ function ToolCall({ name, status }) {
838
1221
 
839
1222
  // src/components/Chat/Message.tsx
840
1223
 
841
- function Message({ message, onAction }) {
1224
+ function Message({ message, onAction, enableWidgets }) {
842
1225
  const isUser = message.role === "user";
843
- const contentSegments = _optionalChain([message, 'access', _16 => _16.metadata, 'optionalAccess', _17 => _17.content_segments]);
1226
+ const contentSegments = _optionalChain([message, 'access', _19 => _19.metadata, 'optionalAccess', _20 => _20.content_segments]);
1227
+ const renderTextContent = (text) => {
1228
+ if (!enableWidgets || isUser) {
1229
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: text });
1230
+ }
1231
+ const parsed = parseWidgetsFromText(text);
1232
+ if (parsed.segments.length === 0) {
1233
+ return null;
1234
+ }
1235
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: parsed.segments.map((segment, index) => {
1236
+ if (segment.type === "text" && segment.content) {
1237
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: segment.content }, `text-${index}`);
1238
+ }
1239
+ if (segment.type === "widget" && segment.widget) {
1240
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "my-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WidgetRenderer, { widget: segment.widget, onAction }) }, `widget-${index}`);
1241
+ }
1242
+ if (segment.type === "widget_pending" && segment.pendingType) {
1243
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "my-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WidgetSkeleton, { type: segment.pendingType }) }, `pending-${index}`);
1244
+ }
1245
+ return null;
1246
+ }) });
1247
+ };
844
1248
  const renderContent = () => {
845
1249
  if (isUser) {
846
1250
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "whitespace-pre-wrap !text-sm leading-relaxed", children: message.content });
@@ -848,7 +1252,7 @@ function Message({ message, onAction }) {
848
1252
  if (contentSegments && contentSegments.length > 0) {
849
1253
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: contentSegments.map((segment, index) => {
850
1254
  if (segment.type === "text") {
851
- return segment.content ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: segment.content }, `text-${index}`) : null;
1255
+ return segment.content ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: renderTextContent(segment.content) }, `text-${index}`) : null;
852
1256
  } else if (segment.type === "tool") {
853
1257
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "my-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
854
1258
  ToolCall,
@@ -861,7 +1265,7 @@ function Message({ message, onAction }) {
861
1265
  return null;
862
1266
  }) });
863
1267
  }
864
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: message.content });
1268
+ return renderTextContent(message.content);
865
1269
  };
866
1270
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
867
1271
  "div",
@@ -1030,7 +1434,8 @@ function MessageList({
1030
1434
  welcomeIcon,
1031
1435
  suggestedPrompts,
1032
1436
  welcomeVariant,
1033
- onPromptClick
1437
+ onPromptClick,
1438
+ enableWidgets
1034
1439
  }) {
1035
1440
  const listRef = _react.useRef.call(void 0, null);
1036
1441
  _react.useEffect.call(void 0, () => {
@@ -1049,13 +1454,13 @@ function MessageList({
1049
1454
  onPromptClick: onPromptClick || (() => {
1050
1455
  })
1051
1456
  }
1052
- ) : messages.map((message) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Message, { message, onAction }, message.id)) });
1457
+ ) : messages.map((message) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Message, { message, onAction, enableWidgets }, message.id)) });
1053
1458
  }
1054
1459
 
1055
1460
  // src/components/Chat/Composer.tsx
1056
1461
 
1057
1462
 
1058
- function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, onFileUpload, onSwitchMode }) {
1463
+ function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, isLoading = false, onStop, onFileUpload, onSwitchMode }) {
1059
1464
  const [text, setText] = _react.useState.call(void 0, "");
1060
1465
  const [showMenu, setShowMenu] = _react.useState.call(void 0, false);
1061
1466
  const [pendingFiles, setPendingFiles] = _react.useState.call(void 0, []);
@@ -1112,7 +1517,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
1112
1517
  setFileError(errors.join(", "));
1113
1518
  setTimeout(() => setFileError(null), 5e3);
1114
1519
  }
1115
- _optionalChain([onFileUpload, 'optionalCall', _18 => _18(e.target.files)]);
1520
+ _optionalChain([onFileUpload, 'optionalCall', _21 => _21(e.target.files)]);
1116
1521
  setShowMenu(false);
1117
1522
  e.target.value = "";
1118
1523
  }
@@ -1182,15 +1587,15 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
1182
1587
  {
1183
1588
  className: "fixed bg-gray-800 dark:bg-gray-700 rounded-xl shadow-lg overflow-hidden z-[9999] min-w-[200px]",
1184
1589
  style: {
1185
- left: _nullishCoalesce(_optionalChain([menuButtonRef, 'access', _19 => _19.current, 'optionalAccess', _20 => _20.getBoundingClientRect, 'call', _21 => _21(), 'access', _22 => _22.left]), () => ( 0)),
1186
- top: (_nullishCoalesce(_optionalChain([menuButtonRef, 'access', _23 => _23.current, 'optionalAccess', _24 => _24.getBoundingClientRect, 'call', _25 => _25(), 'access', _26 => _26.bottom]), () => ( 0))) + 8
1590
+ left: _nullishCoalesce(_optionalChain([menuButtonRef, 'access', _22 => _22.current, 'optionalAccess', _23 => _23.getBoundingClientRect, 'call', _24 => _24(), 'access', _25 => _25.left]), () => ( 0)),
1591
+ top: (_nullishCoalesce(_optionalChain([menuButtonRef, 'access', _26 => _26.current, 'optionalAccess', _27 => _27.getBoundingClientRect, 'call', _28 => _28(), 'access', _29 => _29.bottom]), () => ( 0))) + 8
1187
1592
  },
1188
1593
  children: [
1189
1594
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1190
1595
  "button",
1191
1596
  {
1192
1597
  onClick: () => {
1193
- _optionalChain([fileInputRef, 'access', _27 => _27.current, 'optionalAccess', _28 => _28.click, 'call', _29 => _29()]);
1598
+ _optionalChain([fileInputRef, 'access', _30 => _30.current, 'optionalAccess', _31 => _31.click, 'call', _32 => _32()]);
1194
1599
  setShowMenu(false);
1195
1600
  },
1196
1601
  className: "w-full flex items-center gap-3 px-4 py-3 hover:bg-gray-700 dark:hover:bg-gray-600 transition-colors !text-white text-left",
@@ -1233,7 +1638,15 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
1233
1638
  style: { maxHeight: "120px" }
1234
1639
  }
1235
1640
  ),
1236
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1641
+ isLoading && onStop ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1642
+ "button",
1643
+ {
1644
+ onClick: onStop,
1645
+ className: "w-8 h-8 rounded-lg flex items-center justify-center font-bold transition-all flex-shrink-0 border border-red-400 dark:border-red-500 bg-red-50 dark:bg-red-900/30 !text-red-600 dark:!text-red-400 hover:bg-red-100 dark:hover:bg-red-900/50",
1646
+ title: "Stop generation",
1647
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "rect", { x: "2", y: "2", width: "10", height: "10", rx: "1", fill: "currentColor" }) })
1648
+ }
1649
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1237
1650
  "button",
1238
1651
  {
1239
1652
  onClick: handleSend,
@@ -1272,6 +1685,7 @@ function CommandComposer({
1272
1685
  onApprove,
1273
1686
  onReject,
1274
1687
  onReset,
1688
+ onStop,
1275
1689
  onExpand,
1276
1690
  placeholder = "Enter your command...",
1277
1691
  disabled = false
@@ -1300,8 +1714,8 @@ function CommandComposer({
1300
1714
  }
1301
1715
  };
1302
1716
  const handleNewCommand = () => {
1303
- _optionalChain([onReset, 'optionalCall', _30 => _30()]);
1304
- _optionalChain([inputRef, 'access', _31 => _31.current, 'optionalAccess', _32 => _32.focus, 'call', _33 => _33()]);
1717
+ _optionalChain([onReset, 'optionalCall', _33 => _33()]);
1718
+ _optionalChain([inputRef, 'access', _34 => _34.current, 'optionalAccess', _35 => _35.focus, 'call', _36 => _36()]);
1305
1719
  };
1306
1720
  const handleInputChange = (value) => {
1307
1721
  setInput(value);
@@ -1415,15 +1829,15 @@ function CommandComposer({
1415
1829
  {
1416
1830
  className: "fixed bg-gray-800 dark:bg-gray-700 rounded-xl shadow-lg overflow-hidden z-[9999] min-w-[200px]",
1417
1831
  style: {
1418
- left: _nullishCoalesce(_optionalChain([menuButtonRef, 'access', _34 => _34.current, 'optionalAccess', _35 => _35.getBoundingClientRect, 'call', _36 => _36(), 'access', _37 => _37.left]), () => ( 0)),
1419
- top: (_nullishCoalesce(_optionalChain([menuButtonRef, 'access', _38 => _38.current, 'optionalAccess', _39 => _39.getBoundingClientRect, 'call', _40 => _40(), 'access', _41 => _41.bottom]), () => ( 0))) + 8
1832
+ left: _nullishCoalesce(_optionalChain([menuButtonRef, 'access', _37 => _37.current, 'optionalAccess', _38 => _38.getBoundingClientRect, 'call', _39 => _39(), 'access', _40 => _40.left]), () => ( 0)),
1833
+ top: (_nullishCoalesce(_optionalChain([menuButtonRef, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.getBoundingClientRect, 'call', _43 => _43(), 'access', _44 => _44.bottom]), () => ( 0))) + 8
1420
1834
  },
1421
1835
  children: [
1422
1836
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1423
1837
  "button",
1424
1838
  {
1425
1839
  onClick: () => {
1426
- _optionalChain([fileInputRef, 'access', _42 => _42.current, 'optionalAccess', _43 => _43.click, 'call', _44 => _44()]);
1840
+ _optionalChain([fileInputRef, 'access', _45 => _45.current, 'optionalAccess', _46 => _46.click, 'call', _47 => _47()]);
1427
1841
  setShowMenu(false);
1428
1842
  },
1429
1843
  className: "w-full flex items-center gap-3 px-4 py-3 hover:bg-gray-700 dark:hover:bg-gray-600 transition-colors !text-white text-left",
@@ -1528,6 +1942,15 @@ function CommandComposer({
1528
1942
  }
1529
1943
  )
1530
1944
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1945
+ state === "loading" && onStop && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1946
+ "button",
1947
+ {
1948
+ onClick: onStop,
1949
+ className: "w-8 h-8 rounded-lg flex items-center justify-center transition-all border border-red-400 dark:border-red-500 bg-red-50 dark:bg-red-900/30 !text-red-600 dark:!text-red-400 hover:bg-red-100 dark:hover:bg-red-900/50",
1950
+ title: "Stop generation",
1951
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "rect", { x: "2", y: "2", width: "10", height: "10", rx: "1", fill: "currentColor" }) })
1952
+ }
1953
+ ),
1531
1954
  (state === "success" || state === "error") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1532
1955
  "button",
1533
1956
  {
@@ -1655,7 +2078,7 @@ var AptevaClient = class {
1655
2078
  const error = await response.json().catch(() => ({ error: "Request failed" }));
1656
2079
  throw new Error(error.error || `Request failed with status ${response.status}`);
1657
2080
  }
1658
- const reader = _optionalChain([response, 'access', _45 => _45.body, 'optionalAccess', _46 => _46.getReader, 'call', _47 => _47()]);
2081
+ const reader = _optionalChain([response, 'access', _48 => _48.body, 'optionalAccess', _49 => _49.getReader, 'call', _50 => _50()]);
1659
2082
  if (!reader) {
1660
2083
  throw new Error("Response body is not readable");
1661
2084
  }
@@ -1673,7 +2096,7 @@ var AptevaClient = class {
1673
2096
  if (line.startsWith("data: ")) {
1674
2097
  const data = line.slice(6);
1675
2098
  if (data === "[DONE]") {
1676
- _optionalChain([onComplete, 'optionalCall', _48 => _48(threadId)]);
2099
+ _optionalChain([onComplete, 'optionalCall', _51 => _51(threadId)]);
1677
2100
  return;
1678
2101
  }
1679
2102
  try {
@@ -1688,10 +2111,10 @@ var AptevaClient = class {
1688
2111
  }
1689
2112
  }
1690
2113
  }
1691
- _optionalChain([onComplete, 'optionalCall', _49 => _49(threadId)]);
2114
+ _optionalChain([onComplete, 'optionalCall', _52 => _52(threadId)]);
1692
2115
  } catch (error) {
1693
2116
  const err = error instanceof Error ? error : new Error("Unknown error");
1694
- _optionalChain([onError, 'optionalCall', _50 => _50(err)]);
2117
+ _optionalChain([onError, 'optionalCall', _53 => _53(err)]);
1695
2118
  throw err;
1696
2119
  }
1697
2120
  }
@@ -1731,6 +2154,27 @@ var AptevaClient = class {
1731
2154
  const data = await response.json();
1732
2155
  return data.messages;
1733
2156
  }
2157
+ /**
2158
+ * Cancel an in-progress request
2159
+ */
2160
+ async cancelRequest(agentId, requestId) {
2161
+ try {
2162
+ const response = await fetch(`${this.config.apiUrl}/agents/${agentId}/requests/${requestId}/cancel`, {
2163
+ method: "POST",
2164
+ headers: {
2165
+ "Content-Type": "application/json",
2166
+ "X-API-Key": this.config.apiKey
2167
+ }
2168
+ });
2169
+ if (!response.ok) {
2170
+ const error = await response.json().catch(() => ({ error: "Cancel request failed" }));
2171
+ throw new Error(error.error || `Cancel request failed with status ${response.status}`);
2172
+ }
2173
+ } catch (error) {
2174
+ console.error("[AptevaClient] Cancel request error:", error);
2175
+ throw error;
2176
+ }
2177
+ }
1734
2178
  };
1735
2179
  var aptevaClient = new AptevaClient();
1736
2180
 
@@ -1773,6 +2217,11 @@ function Chat({
1773
2217
  placeholder,
1774
2218
  showHeader = true,
1775
2219
  headerTitle = "Chat",
2220
+ // Widget detection
2221
+ enableWidgets = false,
2222
+ availableWidgets,
2223
+ compactWidgetContext = false,
2224
+ onWidgetRender,
1776
2225
  className
1777
2226
  }) {
1778
2227
  const [messages, setMessages] = _react.useState.call(void 0, initialMessages);
@@ -1786,11 +2235,18 @@ function Chat({
1786
2235
  const [commandInput, setCommandInput] = _react.useState.call(void 0, "");
1787
2236
  const [streamedContent, setStreamedContent] = _react.useState.call(void 0, "");
1788
2237
  const [currentToolName, setCurrentToolName] = _react.useState.call(void 0, null);
2238
+ const [currentRequestId, setCurrentRequestId] = _react.useState.call(void 0, null);
1789
2239
  const [plan, setPlan] = _react.useState.call(void 0, "");
1790
2240
  const [pendingCommand, setPendingCommand] = _react.useState.call(void 0, "");
1791
2241
  const [internalPlanMode, setInternalPlanMode] = _react.useState.call(void 0, planMode);
1792
2242
  const [showSettingsMenu, setShowSettingsMenu] = _react.useState.call(void 0, false);
1793
2243
  const fileInputRef = _react.useRef.call(void 0, null);
2244
+ const effectiveContext = _react.useMemo.call(void 0, () => {
2245
+ if (!enableWidgets) return context;
2246
+ const widgetContext = compactWidgetContext ? generateCompactWidgetContext(availableWidgets) : generateWidgetContext(availableWidgets);
2247
+ return context ? `${context}
2248
+ ${widgetContext}` : widgetContext;
2249
+ }, [context, enableWidgets, availableWidgets, compactWidgetContext]);
1794
2250
  _react.useEffect.call(void 0, () => {
1795
2251
  if (apiUrl || apiKey) {
1796
2252
  aptevaClient.configure({
@@ -1801,7 +2257,7 @@ function Chat({
1801
2257
  }, [apiUrl, apiKey]);
1802
2258
  _react.useEffect.call(void 0, () => {
1803
2259
  if (threadId) {
1804
- _optionalChain([onThreadChange, 'optionalCall', _51 => _51(threadId)]);
2260
+ _optionalChain([onThreadChange, 'optionalCall', _54 => _54(threadId)]);
1805
2261
  }
1806
2262
  }, [threadId, onThreadChange]);
1807
2263
  _react.useEffect.call(void 0, () => {
@@ -1819,7 +2275,7 @@ function Chat({
1819
2275
  }, [showSettingsMenu]);
1820
2276
  const handleModeChange = (newMode) => {
1821
2277
  setMode(newMode);
1822
- _optionalChain([onModeChange, 'optionalCall', _52 => _52(newMode)]);
2278
+ _optionalChain([onModeChange, 'optionalCall', _55 => _55(newMode)]);
1823
2279
  if (newMode === "command") {
1824
2280
  setCommandState("idle");
1825
2281
  setCommandResult(null);
@@ -1839,7 +2295,7 @@ function Chat({
1839
2295
  metadata: hasFiles ? { attachments: fileNames } : void 0
1840
2296
  };
1841
2297
  setMessages((prev) => [...prev, userMessage]);
1842
- _optionalChain([onMessageSent, 'optionalCall', _53 => _53(userMessage)]);
2298
+ _optionalChain([onMessageSent, 'optionalCall', _56 => _56(userMessage)]);
1843
2299
  setIsLoading(true);
1844
2300
  try {
1845
2301
  const messagePayload = await buildMessageWithAttachments(text, files);
@@ -1895,7 +2351,7 @@ function Chat({
1895
2351
  message: messagePayload,
1896
2352
  stream: true,
1897
2353
  ...currentThreadId && { thread_id: currentThreadId },
1898
- ...context && { system: context }
2354
+ ...effectiveContext && { system: effectiveContext }
1899
2355
  },
1900
2356
  (chunk) => {
1901
2357
  switch (chunk.type) {
@@ -1904,10 +2360,15 @@ function Chat({
1904
2360
  responseThreadId = chunk.thread_id;
1905
2361
  if (!currentThreadId) {
1906
2362
  setCurrentThreadId(chunk.thread_id);
1907
- _optionalChain([onThreadChange, 'optionalCall', _54 => _54(chunk.thread_id)]);
2363
+ _optionalChain([onThreadChange, 'optionalCall', _57 => _57(chunk.thread_id)]);
1908
2364
  }
1909
2365
  }
1910
2366
  break;
2367
+ case "request_id":
2368
+ if (chunk.request_id) {
2369
+ setCurrentRequestId(chunk.request_id);
2370
+ }
2371
+ break;
1911
2372
  case "content":
1912
2373
  case "token":
1913
2374
  if (chunk.content) {
@@ -1936,7 +2397,7 @@ function Chat({
1936
2397
  const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
1937
2398
  if (toolSegment) {
1938
2399
  toolSegment.result = chunk.content;
1939
- _optionalChain([onToolResult, 'optionalCall', _55 => _55(toolSegment.name, chunk.content)]);
2400
+ _optionalChain([onToolResult, 'optionalCall', _58 => _58(toolSegment.name, chunk.content)]);
1940
2401
  }
1941
2402
  updateMessage();
1942
2403
  }
@@ -1978,9 +2439,10 @@ function Chat({
1978
2439
  });
1979
2440
  if (threadId2 && threadId2 !== currentThreadId) {
1980
2441
  setCurrentThreadId(threadId2);
1981
- _optionalChain([onThreadChange, 'optionalCall', _56 => _56(threadId2)]);
2442
+ _optionalChain([onThreadChange, 'optionalCall', _59 => _59(threadId2)]);
1982
2443
  }
1983
2444
  setIsLoading(false);
2445
+ setCurrentRequestId(null);
1984
2446
  },
1985
2447
  (error) => {
1986
2448
  const errorMessage = {
@@ -1998,7 +2460,8 @@ function Chat({
1998
2460
  return [...prev, errorMessage];
1999
2461
  });
2000
2462
  setIsLoading(false);
2001
- _optionalChain([onError, 'optionalCall', _57 => _57(error)]);
2463
+ setCurrentRequestId(null);
2464
+ _optionalChain([onError, 'optionalCall', _60 => _60(error)]);
2002
2465
  }
2003
2466
  );
2004
2467
  }
@@ -2011,7 +2474,7 @@ function Chat({
2011
2474
  metadata: { error: true }
2012
2475
  };
2013
2476
  setMessages((prev) => [...prev, errorMessage]);
2014
- _optionalChain([onError, 'optionalCall', _58 => _58(error instanceof Error ? error : new Error("Unknown error"))]);
2477
+ _optionalChain([onError, 'optionalCall', _61 => _61(error instanceof Error ? error : new Error("Unknown error"))]);
2015
2478
  } finally {
2016
2479
  setIsLoading(false);
2017
2480
  }
@@ -2040,7 +2503,7 @@ function Chat({
2040
2503
  } else {
2041
2504
  try {
2042
2505
  const planningInstruction = `CRITICAL PLANNING MODE: You are ONLY creating a plan. Write a numbered list of steps describing what WOULD be done. DO NOT execute anything.`;
2043
- const systemMessage = context ? `${context}
2506
+ const systemMessage = effectiveContext ? `${effectiveContext}
2044
2507
 
2045
2508
  ${planningInstruction}` : planningInstruction;
2046
2509
  const response = await aptevaClient.chat({
@@ -2056,7 +2519,7 @@ ${planningInstruction}` : planningInstruction;
2056
2519
  const error = err instanceof Error ? err : new Error("Failed to generate plan");
2057
2520
  setCommandError(error);
2058
2521
  setCommandState("error");
2059
- _optionalChain([onError, 'optionalCall', _59 => _59(error)]);
2522
+ _optionalChain([onError, 'optionalCall', _62 => _62(error)]);
2060
2523
  }
2061
2524
  }
2062
2525
  return;
@@ -2089,12 +2552,12 @@ ${planningInstruction}` : planningInstruction;
2089
2552
  setCommandResult(result);
2090
2553
  setCommandState("success");
2091
2554
  setProgress(100);
2092
- _optionalChain([onComplete, 'optionalCall', _60 => _60(result)]);
2555
+ _optionalChain([onComplete, 'optionalCall', _63 => _63(result)]);
2093
2556
  },
2094
2557
  (error) => {
2095
2558
  setCommandError(error);
2096
2559
  setCommandState("error");
2097
- _optionalChain([onError, 'optionalCall', _61 => _61(error)]);
2560
+ _optionalChain([onError, 'optionalCall', _64 => _64(error)]);
2098
2561
  }
2099
2562
  );
2100
2563
  } else {
@@ -2107,11 +2570,11 @@ ${planningInstruction}` : planningInstruction;
2107
2570
  setCommandResult(result);
2108
2571
  setCommandState("success");
2109
2572
  setProgress(100);
2110
- _optionalChain([onComplete, 'optionalCall', _62 => _62(result)]);
2573
+ _optionalChain([onComplete, 'optionalCall', _65 => _65(result)]);
2111
2574
  }
2112
2575
  } else {
2113
2576
  const commandInstruction = `CRITICAL COMMAND MODE: Maximum 10 words per response. Execute the command immediately. Make reasonable assumptions based on context. Use sensible defaults for missing details. DO NOT ask questions unless something is truly impossible without user input (e.g., missing required password). State what you're doing or the result. Examples: "Analyzing customer data from last quarter..." or "Created 5 new database entries successfully" or "Search complete: found 12 matching results". NO greetings, NO filler words, NO clarification requests. Action/result only.`;
2114
- const systemMessage = context ? `${context}
2577
+ const systemMessage = effectiveContext ? `${effectiveContext}
2115
2578
 
2116
2579
  ${commandInstruction}` : commandInstruction;
2117
2580
  const messagePayload = files && files.length > 0 ? await buildMessageWithAttachments(currentCommand, files) : currentCommand;
@@ -2139,13 +2602,15 @@ ${commandInstruction}` : commandInstruction;
2139
2602
  accumulatedContent = "";
2140
2603
  setStreamedContent("");
2141
2604
  } else if (chunk.type === "tool_result") {
2142
- _optionalChain([onToolResult, 'optionalCall', _63 => _63(lastToolName, chunk.content)]);
2605
+ _optionalChain([onToolResult, 'optionalCall', _66 => _66(lastToolName, chunk.content)]);
2143
2606
  setCurrentToolName(null);
2144
2607
  } else if (chunk.type === "thread_id" && chunk.thread_id) {
2145
2608
  if (!currentThreadId) {
2146
2609
  setCurrentThreadId(chunk.thread_id);
2147
- _optionalChain([onThreadChange, 'optionalCall', _64 => _64(chunk.thread_id)]);
2610
+ _optionalChain([onThreadChange, 'optionalCall', _67 => _67(chunk.thread_id)]);
2148
2611
  }
2612
+ } else if (chunk.type === "request_id" && chunk.request_id) {
2613
+ setCurrentRequestId(chunk.request_id);
2149
2614
  }
2150
2615
  },
2151
2616
  (threadId2) => {
@@ -2157,12 +2622,14 @@ ${commandInstruction}` : commandInstruction;
2157
2622
  setCommandResult(result);
2158
2623
  setCommandState("success");
2159
2624
  setProgress(100);
2160
- _optionalChain([onComplete, 'optionalCall', _65 => _65(result)]);
2625
+ setCurrentRequestId(null);
2626
+ _optionalChain([onComplete, 'optionalCall', _68 => _68(result)]);
2161
2627
  },
2162
2628
  (error) => {
2163
2629
  setCommandError(error);
2164
2630
  setCommandState("error");
2165
- _optionalChain([onError, 'optionalCall', _66 => _66(error)]);
2631
+ setCurrentRequestId(null);
2632
+ _optionalChain([onError, 'optionalCall', _69 => _69(error)]);
2166
2633
  }
2167
2634
  );
2168
2635
  } else {
@@ -2182,14 +2649,14 @@ ${commandInstruction}` : commandInstruction;
2182
2649
  setCommandResult(result);
2183
2650
  setCommandState("success");
2184
2651
  setProgress(100);
2185
- _optionalChain([onComplete, 'optionalCall', _67 => _67(result)]);
2652
+ _optionalChain([onComplete, 'optionalCall', _70 => _70(result)]);
2186
2653
  }
2187
2654
  }
2188
2655
  } catch (err) {
2189
2656
  const error = err instanceof Error ? err : new Error("Unknown error");
2190
2657
  setCommandError(error);
2191
2658
  setCommandState("error");
2192
- _optionalChain([onError, 'optionalCall', _68 => _68(error)]);
2659
+ _optionalChain([onError, 'optionalCall', _71 => _71(error)]);
2193
2660
  }
2194
2661
  };
2195
2662
  const resetCommand = () => {
@@ -2218,6 +2685,23 @@ ${planToExecute}`;
2218
2685
  setPendingCommand("");
2219
2686
  setCommandState("idle");
2220
2687
  };
2688
+ const handleStop = async () => {
2689
+ if (currentRequestId && agentId) {
2690
+ try {
2691
+ await aptevaClient.cancelRequest(agentId, currentRequestId);
2692
+ } catch (error) {
2693
+ console.error("Failed to cancel request:", error);
2694
+ }
2695
+ }
2696
+ setIsLoading(false);
2697
+ if (commandState === "loading") {
2698
+ setCommandState("idle");
2699
+ setStreamedContent("");
2700
+ setCurrentToolName(null);
2701
+ setProgress(0);
2702
+ }
2703
+ setCurrentRequestId(null);
2704
+ };
2221
2705
  const isCompact = commandVariant === "compact";
2222
2706
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col h-full", className), children: [
2223
2707
  showHeader && mode === "chat" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-3 flex items-center justify-between", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "!text-lg font-semibold !text-gray-900 dark:!text-white", children: headerTitle }) }),
@@ -2232,7 +2716,8 @@ ${planToExecute}`;
2232
2716
  welcomeIcon,
2233
2717
  suggestedPrompts,
2234
2718
  welcomeVariant,
2235
- onPromptClick: (prompt) => handleSendMessage(prompt)
2719
+ onPromptClick: (prompt) => handleSendMessage(prompt),
2720
+ enableWidgets
2236
2721
  }
2237
2722
  ),
2238
2723
  isLoading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-2 !text-sm !text-gray-500 dark:!text-gray-400 italic", children: "AI is thinking..." }),
@@ -2242,6 +2727,8 @@ ${planToExecute}`;
2242
2727
  onSendMessage: handleSendMessage,
2243
2728
  placeholder: placeholder || defaultPlaceholder,
2244
2729
  disabled: isLoading,
2730
+ isLoading,
2731
+ onStop: handleStop,
2245
2732
  onFileUpload,
2246
2733
  onSwitchMode: showModeToggle ? () => handleModeChange("command") : void 0
2247
2734
  }
@@ -2255,14 +2742,15 @@ ${planToExecute}`;
2255
2742
  executeCommand(text, files);
2256
2743
  },
2257
2744
  state: commandState,
2258
- response: _optionalChain([commandResult, 'optionalAccess', _69 => _69.data, 'optionalAccess', _70 => _70.summary]) || _optionalChain([commandResult, 'optionalAccess', _71 => _71.message]),
2259
- error: _optionalChain([commandError, 'optionalAccess', _72 => _72.message]),
2745
+ response: _optionalChain([commandResult, 'optionalAccess', _72 => _72.data, 'optionalAccess', _73 => _73.summary]) || _optionalChain([commandResult, 'optionalAccess', _74 => _74.message]),
2746
+ error: _optionalChain([commandError, 'optionalAccess', _75 => _75.message]),
2260
2747
  plan,
2261
2748
  streamedContent,
2262
2749
  toolName: currentToolName,
2263
2750
  onApprove: approvePlan,
2264
2751
  onReject: rejectPlan,
2265
2752
  onReset: resetCommand,
2753
+ onStop: handleStop,
2266
2754
  onExpand: showModeToggle ? () => handleModeChange("chat") : void 0,
2267
2755
  placeholder: placeholder || "Enter your command..."
2268
2756
  }
@@ -2423,13 +2911,13 @@ ${planningInstruction}` : planningInstruction;
2423
2911
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
2424
2912
  setError(error2);
2425
2913
  setState("error");
2426
- _optionalChain([onError, 'optionalCall', _73 => _73(error2)]);
2914
+ _optionalChain([onError, 'optionalCall', _76 => _76(error2)]);
2427
2915
  });
2428
2916
  } catch (err) {
2429
2917
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
2430
2918
  setError(error2);
2431
2919
  setState("error");
2432
- _optionalChain([onError, 'optionalCall', _74 => _74(error2)]);
2920
+ _optionalChain([onError, 'optionalCall', _77 => _77(error2)]);
2433
2921
  }
2434
2922
  }
2435
2923
  return;
@@ -2440,7 +2928,7 @@ ${planningInstruction}` : planningInstruction;
2440
2928
  setStreamedContent("");
2441
2929
  setCommand("");
2442
2930
  setUploadedFiles([]);
2443
- _optionalChain([onStart, 'optionalCall', _75 => _75()]);
2931
+ _optionalChain([onStart, 'optionalCall', _78 => _78()]);
2444
2932
  try {
2445
2933
  if (useMock) {
2446
2934
  if (enableStreaming) {
@@ -2451,16 +2939,16 @@ ${planningInstruction}` : planningInstruction;
2451
2939
  if (chunk.type === "token" && chunk.content) {
2452
2940
  accumulatedContent += chunk.content;
2453
2941
  setStreamedContent(accumulatedContent);
2454
- _optionalChain([onChunk, 'optionalCall', _76 => _76(chunk.content)]);
2942
+ _optionalChain([onChunk, 'optionalCall', _79 => _79(chunk.content)]);
2455
2943
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
2456
2944
  setProgress(estimatedProgress);
2457
- _optionalChain([onProgress, 'optionalCall', _77 => _77(estimatedProgress)]);
2945
+ _optionalChain([onProgress, 'optionalCall', _80 => _80(estimatedProgress)]);
2458
2946
  } else if (chunk.type === "widget" && chunk.widget) {
2459
2947
  const widget = chunk.widget;
2460
2948
  setResult((prev) => ({
2461
2949
  success: true,
2462
- data: _optionalChain([prev, 'optionalAccess', _78 => _78.data]) || {},
2463
- widgets: [..._optionalChain([prev, 'optionalAccess', _79 => _79.widgets]) || [], widget],
2950
+ data: _optionalChain([prev, 'optionalAccess', _81 => _81.data]) || {},
2951
+ widgets: [..._optionalChain([prev, 'optionalAccess', _82 => _82.widgets]) || [], widget],
2464
2952
  message: accumulatedContent || "Command executed successfully"
2465
2953
  }));
2466
2954
  }
@@ -2480,19 +2968,19 @@ ${planningInstruction}` : planningInstruction;
2480
2968
  setResult(result2);
2481
2969
  setState("success");
2482
2970
  setProgress(100);
2483
- _optionalChain([onComplete, 'optionalCall', _80 => _80(result2)]);
2971
+ _optionalChain([onComplete, 'optionalCall', _83 => _83(result2)]);
2484
2972
  },
2485
2973
  (error2) => {
2486
2974
  setError(error2);
2487
2975
  setState("error");
2488
- _optionalChain([onError, 'optionalCall', _81 => _81(error2)]);
2976
+ _optionalChain([onError, 'optionalCall', _84 => _84(error2)]);
2489
2977
  }
2490
2978
  );
2491
2979
  } else {
2492
2980
  const progressInterval = setInterval(() => {
2493
2981
  setProgress((prev) => {
2494
2982
  const next = Math.min(prev + 10, 90);
2495
- _optionalChain([onProgress, 'optionalCall', _82 => _82(next)]);
2983
+ _optionalChain([onProgress, 'optionalCall', _85 => _85(next)]);
2496
2984
  return next;
2497
2985
  });
2498
2986
  }, 200);
@@ -2516,7 +3004,7 @@ ${planningInstruction}` : planningInstruction;
2516
3004
  setResult(result2);
2517
3005
  setState("success");
2518
3006
  setProgress(100);
2519
- _optionalChain([onComplete, 'optionalCall', _83 => _83(result2)]);
3007
+ _optionalChain([onComplete, 'optionalCall', _86 => _86(result2)]);
2520
3008
  }
2521
3009
  } else {
2522
3010
  if (enableStreaming) {
@@ -2562,16 +3050,16 @@ ${commandInstruction}` : commandInstruction;
2562
3050
  if (chunk.type === "token" && chunk.content) {
2563
3051
  accumulatedContent += chunk.content;
2564
3052
  setStreamedContent(accumulatedContent);
2565
- _optionalChain([onChunk, 'optionalCall', _84 => _84(chunk.content)]);
3053
+ _optionalChain([onChunk, 'optionalCall', _87 => _87(chunk.content)]);
2566
3054
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
2567
3055
  setProgress(estimatedProgress);
2568
- _optionalChain([onProgress, 'optionalCall', _85 => _85(estimatedProgress)]);
3056
+ _optionalChain([onProgress, 'optionalCall', _88 => _88(estimatedProgress)]);
2569
3057
  } else if (chunk.type === "widget" && chunk.widget) {
2570
3058
  const widget = chunk.widget;
2571
3059
  setResult((prev) => ({
2572
3060
  success: true,
2573
- data: _optionalChain([prev, 'optionalAccess', _86 => _86.data]) || {},
2574
- widgets: [..._optionalChain([prev, 'optionalAccess', _87 => _87.widgets]) || [], widget],
3061
+ data: _optionalChain([prev, 'optionalAccess', _89 => _89.data]) || {},
3062
+ widgets: [..._optionalChain([prev, 'optionalAccess', _90 => _90.widgets]) || [], widget],
2575
3063
  message: accumulatedContent || "Command executed successfully"
2576
3064
  }));
2577
3065
  }
@@ -2591,20 +3079,20 @@ ${commandInstruction}` : commandInstruction;
2591
3079
  setResult(result2);
2592
3080
  setState("success");
2593
3081
  setProgress(100);
2594
- _optionalChain([onComplete, 'optionalCall', _88 => _88(result2)]);
3082
+ _optionalChain([onComplete, 'optionalCall', _91 => _91(result2)]);
2595
3083
  },
2596
3084
  (error2) => {
2597
3085
  const err = error2 instanceof Error ? error2 : new Error("Unknown error");
2598
3086
  setError(err);
2599
3087
  setState("error");
2600
- _optionalChain([onError, 'optionalCall', _89 => _89(err)]);
3088
+ _optionalChain([onError, 'optionalCall', _92 => _92(err)]);
2601
3089
  }
2602
3090
  );
2603
3091
  } else {
2604
3092
  const progressInterval = setInterval(() => {
2605
3093
  setProgress((prev) => {
2606
3094
  const next = Math.min(prev + 10, 90);
2607
- _optionalChain([onProgress, 'optionalCall', _90 => _90(next)]);
3095
+ _optionalChain([onProgress, 'optionalCall', _93 => _93(next)]);
2608
3096
  return next;
2609
3097
  });
2610
3098
  }, 200);
@@ -2660,14 +3148,14 @@ ${commandInstruction}` : commandInstruction;
2660
3148
  setResult(result2);
2661
3149
  setState("success");
2662
3150
  setProgress(100);
2663
- _optionalChain([onComplete, 'optionalCall', _91 => _91(result2)]);
3151
+ _optionalChain([onComplete, 'optionalCall', _94 => _94(result2)]);
2664
3152
  }
2665
3153
  }
2666
3154
  } catch (err) {
2667
3155
  const error2 = err instanceof Error ? err : new Error("Unknown error");
2668
3156
  setError(error2);
2669
3157
  setState("error");
2670
- _optionalChain([onError, 'optionalCall', _92 => _92(error2)]);
3158
+ _optionalChain([onError, 'optionalCall', _95 => _95(error2)]);
2671
3159
  }
2672
3160
  };
2673
3161
  const resetCommand = () => {
@@ -2700,14 +3188,14 @@ ${planToExecute}`;
2700
3188
  };
2701
3189
  const handleFileSelect = async (e) => {
2702
3190
  if (e.target.files && e.target.files.length > 0) {
2703
- _optionalChain([onFileUpload, 'optionalCall', _93 => _93(e.target.files)]);
3191
+ _optionalChain([onFileUpload, 'optionalCall', _96 => _96(e.target.files)]);
2704
3192
  const files = [];
2705
3193
  for (let i = 0; i < e.target.files.length; i++) {
2706
3194
  const file = e.target.files[i];
2707
3195
  const reader = new FileReader();
2708
3196
  await new Promise((resolve) => {
2709
3197
  reader.onload = (event) => {
2710
- if (_optionalChain([event, 'access', _94 => _94.target, 'optionalAccess', _95 => _95.result])) {
3198
+ if (_optionalChain([event, 'access', _97 => _97.target, 'optionalAccess', _98 => _98.result])) {
2711
3199
  const fullDataUrl = event.target.result;
2712
3200
  const base64Data = fullDataUrl.split(",")[1];
2713
3201
  if (file.type.startsWith("image/")) {
@@ -2801,7 +3289,7 @@ ${planToExecute}`;
2801
3289
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2802
3290
  "button",
2803
3291
  {
2804
- onClick: () => _optionalChain([fileInputRef, 'access', _96 => _96.current, 'optionalAccess', _97 => _97.click, 'call', _98 => _98()]),
3292
+ onClick: () => _optionalChain([fileInputRef, 'access', _99 => _99.current, 'optionalAccess', _100 => _100.click, 'call', _101 => _101()]),
2805
3293
  className: "w-8 h-8 rounded-lg flex items-center justify-center transition-all flex-shrink-0 !text-gray-500 dark:!text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800",
2806
3294
  title: "Attach file",
2807
3295
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8.4 2.8L4.4 6.8C3.736 7.464 3.736 8.536 4.4 9.2C5.064 9.864 6.136 9.864 6.8 9.2L11.6 4.4C12.704 3.296 12.704 1.504 11.6 0.4C10.496 -0.704 8.704 -0.704 7.6 0.4L2.8 5.2C1.256 6.744 1.256 9.256 2.8 10.8C4.344 12.344 6.856 12.344 8.4 10.8L12.4 6.8", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(1.6, 2.4)" }) })
@@ -3020,7 +3508,7 @@ ${planToExecute}`;
3020
3508
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-5 h-5 text-red-600 mt-0.5 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
3021
3509
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3022
3510
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-semibold text-red-800 dark:text-red-400", children: "Error" }),
3023
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _99 => _99.message]) })
3511
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _102 => _102.message]) })
3024
3512
  ] })
3025
3513
  ] }) }),
3026
3514
  allowInput && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -3048,7 +3536,7 @@ ${planToExecute}`;
3048
3536
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-green-700 dark:text-green-300 text-sm", children: "Command executed successfully" })
3049
3537
  ] })
3050
3538
  ] }),
3051
- _optionalChain([result, 'access', _100 => _100.data, 'optionalAccess', _101 => _101.summary]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-gray-700 dark:text-gray-300 text-sm leading-relaxed whitespace-pre-line", children: result.data.summary }),
3539
+ _optionalChain([result, 'access', _103 => _103.data, 'optionalAccess', _104 => _104.summary]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-gray-700 dark:text-gray-300 text-sm leading-relaxed whitespace-pre-line", children: result.data.summary }),
3052
3540
  result.widgets && result.widgets.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-3", children: result.widgets.map((widget) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3053
3541
  WidgetRenderer,
3054
3542
  {
@@ -3099,7 +3587,7 @@ ${planToExecute}`;
3099
3587
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3100
3588
  "button",
3101
3589
  {
3102
- onClick: () => _optionalChain([fileInputRef, 'access', _102 => _102.current, 'optionalAccess', _103 => _103.click, 'call', _104 => _104()]),
3590
+ onClick: () => _optionalChain([fileInputRef, 'access', _105 => _105.current, 'optionalAccess', _106 => _106.click, 'call', _107 => _107()]),
3103
3591
  className: "w-8 h-8 rounded-lg flex items-center justify-center transition-all flex-shrink-0 !text-gray-500 dark:!text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800",
3104
3592
  title: "Attach file",
3105
3593
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8.4 2.8L4.4 6.8C3.736 7.464 3.736 8.536 4.4 9.2C5.064 9.864 6.136 9.864 6.8 9.2L11.6 4.4C12.704 3.296 12.704 1.504 11.6 0.4C10.496 -0.704 8.704 -0.704 7.6 0.4L2.8 5.2C1.256 6.744 1.256 9.256 2.8 10.8C4.344 12.344 6.856 12.344 8.4 10.8L12.4 6.8", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(1.6, 2.4)" }) })
@@ -3285,25 +3773,25 @@ function Prompt({
3285
3773
  const newValue = e.target.value;
3286
3774
  if (!maxLength || newValue.length <= maxLength) {
3287
3775
  setValue(newValue);
3288
- _optionalChain([onChange, 'optionalCall', _105 => _105(newValue)]);
3776
+ _optionalChain([onChange, 'optionalCall', _108 => _108(newValue)]);
3289
3777
  }
3290
3778
  };
3291
3779
  const handleSubmit = async () => {
3292
3780
  if (value.length < minLength) return;
3293
- _optionalChain([onSubmit, 'optionalCall', _106 => _106(value)]);
3781
+ _optionalChain([onSubmit, 'optionalCall', _109 => _109(value)]);
3294
3782
  setIsLoading(true);
3295
3783
  try {
3296
3784
  if (useMock) {
3297
3785
  await new Promise((resolve) => setTimeout(resolve, 1500));
3298
3786
  const mockResult = `Enhanced version: ${value} [AI-generated content]`;
3299
- _optionalChain([onResult, 'optionalCall', _107 => _107(mockResult)]);
3787
+ _optionalChain([onResult, 'optionalCall', _110 => _110(mockResult)]);
3300
3788
  setValue("");
3301
3789
  } else {
3302
3790
  const response = await aptevaClient.chat({
3303
3791
  agent_id: agentId,
3304
3792
  message: value
3305
3793
  });
3306
- _optionalChain([onResult, 'optionalCall', _108 => _108(response.message)]);
3794
+ _optionalChain([onResult, 'optionalCall', _111 => _111(response.message)]);
3307
3795
  setValue("");
3308
3796
  }
3309
3797
  } catch (error) {
@@ -3398,7 +3886,7 @@ function Stream({
3398
3886
  }, [autoStart]);
3399
3887
  const startStreaming = async () => {
3400
3888
  setIsStreaming(true);
3401
- _optionalChain([onStart, 'optionalCall', _109 => _109()]);
3889
+ _optionalChain([onStart, 'optionalCall', _112 => _112()]);
3402
3890
  try {
3403
3891
  if (useMock) {
3404
3892
  const mockText = "This is a simulated streaming response from the AI agent. In a real implementation, this would stream data from your backend API. The text appears word by word to simulate the streaming effect. You can customize the typing speed and styling based on your needs.";
@@ -3406,13 +3894,13 @@ function Stream({
3406
3894
  mockText,
3407
3895
  (chunk) => {
3408
3896
  setText((prev) => prev + chunk);
3409
- _optionalChain([onChunk, 'optionalCall', _110 => _110(chunk)]);
3897
+ _optionalChain([onChunk, 'optionalCall', _113 => _113(chunk)]);
3410
3898
  },
3411
3899
  typingSpeed
3412
3900
  );
3413
3901
  setIsComplete(true);
3414
3902
  setIsStreaming(false);
3415
- _optionalChain([onComplete, 'optionalCall', _111 => _111(text + mockText)]);
3903
+ _optionalChain([onComplete, 'optionalCall', _114 => _114(text + mockText)]);
3416
3904
  } else {
3417
3905
  let accumulatedText = "";
3418
3906
  await aptevaClient.chatStream(
@@ -3425,24 +3913,24 @@ function Stream({
3425
3913
  if (chunk.type === "token" && chunk.content) {
3426
3914
  accumulatedText += chunk.content;
3427
3915
  setText(accumulatedText);
3428
- _optionalChain([onChunk, 'optionalCall', _112 => _112(chunk.content)]);
3916
+ _optionalChain([onChunk, 'optionalCall', _115 => _115(chunk.content)]);
3429
3917
  }
3430
3918
  },
3431
3919
  () => {
3432
3920
  setIsComplete(true);
3433
3921
  setIsStreaming(false);
3434
- _optionalChain([onComplete, 'optionalCall', _113 => _113(accumulatedText)]);
3922
+ _optionalChain([onComplete, 'optionalCall', _116 => _116(accumulatedText)]);
3435
3923
  },
3436
3924
  (error) => {
3437
3925
  const err = error instanceof Error ? error : new Error("Streaming error");
3438
- _optionalChain([onError, 'optionalCall', _114 => _114(err)]);
3926
+ _optionalChain([onError, 'optionalCall', _117 => _117(err)]);
3439
3927
  setIsStreaming(false);
3440
3928
  }
3441
3929
  );
3442
3930
  }
3443
3931
  } catch (error) {
3444
3932
  const err = error instanceof Error ? error : new Error("Streaming error");
3445
- _optionalChain([onError, 'optionalCall', _115 => _115(err)]);
3933
+ _optionalChain([onError, 'optionalCall', _118 => _118(err)]);
3446
3934
  setIsStreaming(false);
3447
3935
  }
3448
3936
  };
@@ -3534,7 +4022,7 @@ function ThreadList({
3534
4022
  }) {
3535
4023
  const [searchQuery, setSearchQuery] = _react.useState.call(void 0, "");
3536
4024
  const filteredThreads = threads.filter(
3537
- (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _116 => _116.preview, 'optionalAccess', _117 => _117.toLowerCase, 'call', _118 => _118(), 'access', _119 => _119.includes, 'call', _120 => _120(searchQuery.toLowerCase())])
4025
+ (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _119 => _119.preview, 'optionalAccess', _120 => _120.toLowerCase, 'call', _121 => _121(), 'access', _122 => _122.includes, 'call', _123 => _123(searchQuery.toLowerCase())])
3538
4026
  );
3539
4027
  const groupedThreads = groupBy === "date" ? groupThreadsByDate(filteredThreads) : { All: filteredThreads };
3540
4028
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col h-full", children: [
@@ -3556,8 +4044,8 @@ function ThreadList({
3556
4044
  {
3557
4045
  thread,
3558
4046
  isActive: thread.id === currentThreadId,
3559
- onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _121 => _121(thread.id)]),
3560
- onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _122 => _122(thread.id)])
4047
+ onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _124 => _124(thread.id)]),
4048
+ onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _125 => _125(thread.id)])
3561
4049
  },
3562
4050
  thread.id
3563
4051
  ))
@@ -3619,7 +4107,7 @@ function Threads({
3619
4107
  threads.slice(0, 5).map((thread) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3620
4108
  "button",
3621
4109
  {
3622
- onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _123 => _123(thread.id)]),
4110
+ onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _126 => _126(thread.id)]),
3623
4111
  className: cn(
3624
4112
  "px-4 py-2 whitespace-nowrap font-medium transition-colors",
3625
4113
  thread.id === currentThreadId ? "border-b-2 border-apteva-500 text-apteva-500" : "text-gray-600 hover:text-gray-900"