@apteva/apteva-kit 0.1.11 → 0.1.14

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
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -417,6 +417,87 @@ function generateMockCommandStream(command, onChunk, onComplete, onError, typing
417
417
  }, typingSpeed);
418
418
  }
419
419
 
420
+ // src/utils/file-utils.ts
421
+ function fileToBase64(file) {
422
+ return new Promise((resolve, reject) => {
423
+ const reader = new FileReader();
424
+ reader.onload = () => {
425
+ const result = reader.result;
426
+ const base64 = result.split(",")[1];
427
+ resolve(base64);
428
+ };
429
+ reader.onerror = () => reject(new Error("Failed to read file"));
430
+ reader.readAsDataURL(file);
431
+ });
432
+ }
433
+ function getContentBlockType(mimeType) {
434
+ if (mimeType.startsWith("image/")) {
435
+ return "image";
436
+ }
437
+ return "document";
438
+ }
439
+ function isSupportedFileType(file) {
440
+ const supportedTypes = [
441
+ // Images
442
+ "image/jpeg",
443
+ "image/png",
444
+ "image/gif",
445
+ "image/webp",
446
+ // Documents
447
+ "application/pdf",
448
+ "text/plain",
449
+ "application/msword",
450
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
451
+ ];
452
+ return supportedTypes.includes(file.type);
453
+ }
454
+ async function fileToContentBlock(file) {
455
+ const base64 = await fileToBase64(file);
456
+ const blockType = getContentBlockType(file.type);
457
+ return {
458
+ type: blockType,
459
+ source: {
460
+ type: "base64",
461
+ media_type: file.type,
462
+ data: base64
463
+ }
464
+ };
465
+ }
466
+ async function filesToContentBlocks(files) {
467
+ const fileArray = Array.from(files);
468
+ const blocks = await Promise.all(
469
+ fileArray.map((file) => fileToContentBlock(file))
470
+ );
471
+ return blocks;
472
+ }
473
+ async function buildMessageWithAttachments(text, files) {
474
+ if (!files || files.length === 0) {
475
+ return text;
476
+ }
477
+ const blocks = [];
478
+ if (text.trim()) {
479
+ blocks.push({ type: "text", text: text.trim() });
480
+ }
481
+ const fileBlocks = await filesToContentBlocks(files);
482
+ blocks.push(...fileBlocks);
483
+ return blocks;
484
+ }
485
+ function formatFileSize(bytes) {
486
+ if (bytes < 1024) return `${bytes} B`;
487
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
488
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
489
+ }
490
+ var MAX_FILE_SIZE = 10 * 1024 * 1024;
491
+ function validateFile(file) {
492
+ if (!isSupportedFileType(file)) {
493
+ return { valid: false, error: `Unsupported file type: ${file.type}` };
494
+ }
495
+ if (file.size > MAX_FILE_SIZE) {
496
+ return { valid: false, error: `File too large: ${formatFileSize(file.size)} (max ${formatFileSize(MAX_FILE_SIZE)})` };
497
+ }
498
+ return { valid: true };
499
+ }
500
+
420
501
  // src/components/Widgets/Widgets.tsx
421
502
 
422
503
 
@@ -514,6 +595,53 @@ function Button({ widget, onAction }) {
514
595
  );
515
596
  }
516
597
 
598
+ // src/components/Widgets/widget-library/ButtonGroup.tsx
599
+
600
+ function ButtonGroup({ widget, onAction }) {
601
+ const { layout = "horizontal", buttons } = widget.props;
602
+ const variantClasses = {
603
+ primary: "bg-blue-500 !text-white hover:bg-blue-600",
604
+ secondary: "bg-gray-200 dark:bg-gray-700 !text-gray-800 dark:!text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-600",
605
+ outline: "border border-gray-300 dark:border-gray-600 !text-gray-700 dark:!text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800"
606
+ };
607
+ const getActionForButton = (buttonId) => {
608
+ return _optionalChain([widget, 'access', _7 => _7.actions, 'optionalAccess', _8 => _8.find, 'call', _9 => _9((action) => _optionalChain([action, 'access', _10 => _10.payload, 'optionalAccess', _11 => _11.buttonId]) === buttonId)]) || _optionalChain([widget, 'access', _12 => _12.actions, 'optionalAccess', _13 => _13[0]]);
609
+ };
610
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
611
+ "div",
612
+ {
613
+ className: cn(
614
+ "flex gap-2",
615
+ layout === "vertical" ? "flex-col" : "flex-row flex-wrap"
616
+ ),
617
+ children: buttons.map((button) => {
618
+ const action = getActionForButton(button.id);
619
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
620
+ "button",
621
+ {
622
+ onClick: () => {
623
+ if (action) {
624
+ _optionalChain([onAction, 'optionalCall', _14 => _14({
625
+ type: action.type,
626
+ payload: { ...action.payload, buttonId: button.id },
627
+ widgetId: widget.id,
628
+ timestamp: /* @__PURE__ */ new Date()
629
+ })]);
630
+ }
631
+ },
632
+ className: cn(
633
+ "px-4 py-2 rounded-lg font-medium transition-colors text-sm",
634
+ variantClasses[button.variant || "secondary"]
635
+ ),
636
+ children: button.label
637
+ },
638
+ button.id
639
+ );
640
+ })
641
+ }
642
+ );
643
+ }
644
+
517
645
  // src/components/Widgets/WidgetRenderer.tsx
518
646
 
519
647
  function WidgetRenderer({ widget, onAction }) {
@@ -524,6 +652,8 @@ function WidgetRenderer({ widget, onAction }) {
524
652
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, List, { widget, onAction });
525
653
  case "button":
526
654
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { widget, onAction });
655
+ case "button_group":
656
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ButtonGroup, { widget, onAction });
527
657
  default:
528
658
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-4 border border-yellow-300 bg-yellow-50 rounded-lg", children: [
529
659
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-yellow-800", children: [
@@ -548,7 +678,7 @@ function Widgets({
548
678
  }) {
549
679
  _react.useEffect.call(void 0, () => {
550
680
  widgets.forEach((widget) => {
551
- _optionalChain([onWidgetMount, 'optionalCall', _7 => _7(widget.id)]);
681
+ _optionalChain([onWidgetMount, 'optionalCall', _15 => _15(widget.id)]);
552
682
  });
553
683
  }, [widgets, onWidgetMount]);
554
684
  const layoutClasses = {
@@ -647,6 +777,33 @@ function parseMarkdown(content) {
647
777
  );
648
778
  continue;
649
779
  }
780
+ const tableMatch = line.match(/^\|(.+)\|$/);
781
+ if (tableMatch && i + 1 < lines.length) {
782
+ const separatorLine = lines[i + 1];
783
+ const separatorMatch = separatorLine.match(/^\|[\s:-]+\|$/);
784
+ if (separatorMatch) {
785
+ const headerCells = line.split("|").filter((cell) => cell.trim() !== "").map((cell) => cell.trim());
786
+ i += 2;
787
+ const bodyRows = [];
788
+ while (i < lines.length) {
789
+ const rowMatch = lines[i].match(/^\|(.+)\|$/);
790
+ if (rowMatch) {
791
+ const cells = lines[i].split("|").filter((cell) => cell.trim() !== "").map((cell) => cell.trim());
792
+ bodyRows.push(cells);
793
+ i++;
794
+ } else {
795
+ break;
796
+ }
797
+ }
798
+ result.push(
799
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-md-table-wrapper", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { className: "apteva-md-table", children: [
800
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { children: headerCells.map((cell, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: "apteva-md-th", children: parseInlineMarkdown(cell, `th${key}${idx}`) }, `th${idx}`)) }) }),
801
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { children: bodyRows.map((row, rowIdx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { children: row.map((cell, cellIdx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: "apteva-md-td", children: parseInlineMarkdown(cell, `td${key}${rowIdx}${cellIdx}`) }, `td${cellIdx}`)) }, `tr${rowIdx}`)) })
802
+ ] }) }, `table-wrapper${key++}`)
803
+ );
804
+ continue;
805
+ }
806
+ }
650
807
  if (line === "") {
651
808
  result.push(/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "br", {}, `br${key++}`));
652
809
  } else {
@@ -668,14 +825,14 @@ function MarkdownContent({ content, className = "" }) {
668
825
  // src/components/Chat/ToolCall.tsx
669
826
 
670
827
  function ToolCall({ name, status }) {
671
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 py-2 px-3 my-2 rounded-lg bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-sm", children: [
672
- status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse" }),
673
- status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-green-500" }),
674
- status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-red-500" }),
675
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-700 dark:text-gray-300 font-mono", children: name }),
676
- status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-500 dark:text-gray-400 ml-auto", children: "Running..." }),
677
- status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-green-600 dark:text-green-400 ml-auto", children: "Completed" }),
678
- status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-red-600 dark:text-red-400 ml-auto", children: "Error" })
828
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "apteva-tool-call", children: [
829
+ status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-tool-call-dot apteva-tool-call-dot-running" }),
830
+ status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-tool-call-dot apteva-tool-call-dot-completed" }),
831
+ status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-tool-call-dot apteva-tool-call-dot-error" }),
832
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-call-name", children: name }),
833
+ status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-call-status", children: "Running..." }),
834
+ status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-call-status apteva-tool-call-status-completed", children: "Completed" }),
835
+ status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-tool-call-status apteva-tool-call-status-error", children: "Error" })
679
836
  ] });
680
837
  }
681
838
 
@@ -683,7 +840,7 @@ function ToolCall({ name, status }) {
683
840
 
684
841
  function Message({ message, onAction }) {
685
842
  const isUser = message.role === "user";
686
- const contentSegments = _optionalChain([message, 'access', _8 => _8.metadata, 'optionalAccess', _9 => _9.content_segments]);
843
+ const contentSegments = _optionalChain([message, 'access', _16 => _16.metadata, 'optionalAccess', _17 => _17.content_segments]);
687
844
  const renderContent = () => {
688
845
  if (isUser) {
689
846
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "whitespace-pre-wrap !text-sm leading-relaxed", children: message.content });
@@ -711,7 +868,7 @@ function Message({ message, onAction }) {
711
868
  {
712
869
  className: cn(
713
870
  "max-w-[80%]",
714
- isUser ? "px-4 py-2.5 rounded-xl bg-gray-100 dark:bg-gray-800 !text-gray-900 dark:!text-gray-100 ml-auto" : "!text-gray-900 dark:!text-gray-100"
871
+ isUser ? "px-4 py-2.5 rounded-xl bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 !text-gray-900 dark:!text-gray-100 ml-auto" : "!text-gray-900 dark:!text-gray-100"
715
872
  ),
716
873
  children: [
717
874
  renderContent(),
@@ -722,27 +879,187 @@ function Message({ message, onAction }) {
722
879
  );
723
880
  }
724
881
 
882
+ // src/components/Chat/WelcomeScreen.tsx
883
+
884
+ var DefaultIcon = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-12 h-12 sm:w-16 sm:h-16", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
885
+ "path",
886
+ {
887
+ strokeLinecap: "round",
888
+ strokeLinejoin: "round",
889
+ strokeWidth: 1.5,
890
+ d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
891
+ }
892
+ ) });
893
+ var ArrowIcon = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 7l5 5m0 0l-5 5m5-5H6" }) });
894
+ function WelcomeScreen({
895
+ title,
896
+ subtitle,
897
+ icon,
898
+ prompts,
899
+ variant = "centered",
900
+ onPromptClick
901
+ }) {
902
+ const normalizedPrompts = (prompts || []).map(
903
+ (p) => typeof p === "string" ? { text: p } : p
904
+ );
905
+ const hasPrompts = normalizedPrompts.length > 0;
906
+ const hasHeader = title || subtitle || icon;
907
+ if (!hasHeader && !hasPrompts) {
908
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center h-full !text-gray-500 dark:!text-gray-400", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center space-y-2", children: [
909
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DefaultIcon, {}) }),
910
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm", children: "No messages yet. Start a conversation!" })
911
+ ] }) });
912
+ }
913
+ if (variant === "minimal") {
914
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col h-full px-4 py-4", children: [
915
+ hasHeader && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
916
+ title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-lg font-semibold !text-gray-900 dark:!text-white", children: title }),
917
+ subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm !text-gray-500 dark:!text-gray-400 mt-1", children: subtitle })
918
+ ] }),
919
+ hasPrompts && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 space-y-2", children: normalizedPrompts.map((prompt, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
920
+ "button",
921
+ {
922
+ onClick: () => onPromptClick(prompt.text),
923
+ className: cn(
924
+ "w-full text-left px-4 py-3 rounded-xl",
925
+ "bg-gray-50 dark:bg-gray-800/50",
926
+ "border border-gray-200 dark:border-gray-700",
927
+ "hover:bg-gray-100 dark:hover:bg-gray-800",
928
+ "hover:border-gray-300 dark:hover:border-gray-600",
929
+ "transition-all duration-200",
930
+ "group"
931
+ ),
932
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
933
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-shrink-0 !text-gray-400 dark:!text-gray-500 group-hover:!text-blue-500 dark:group-hover:!text-blue-400 transition-colors", children: prompt.icon || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ArrowIcon, {}) }),
934
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0", children: [
935
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium !text-gray-900 dark:!text-white truncate", children: prompt.text }),
936
+ prompt.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs !text-gray-500 dark:!text-gray-400 mt-0.5 truncate", children: prompt.description })
937
+ ] })
938
+ ] })
939
+ },
940
+ index
941
+ )) })
942
+ ] });
943
+ }
944
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center h-full px-4 py-6 sm:py-8", children: [
945
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center mb-6 sm:mb-8 max-w-md", children: [
946
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-4 !text-gray-400 dark:!text-gray-500 flex justify-center", children: icon || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DefaultIcon, {}) }),
947
+ title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-xl sm:text-2xl font-semibold !text-gray-900 dark:!text-white mb-2", children: title }),
948
+ subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm sm:text-base !text-gray-500 dark:!text-gray-400", children: subtitle })
949
+ ] }),
950
+ hasPrompts && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "w-full max-w-2xl", children: [
951
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sm:hidden space-y-2", children: normalizedPrompts.map((prompt, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
952
+ "button",
953
+ {
954
+ onClick: () => onPromptClick(prompt.text),
955
+ className: cn(
956
+ "w-full text-left px-4 py-3 rounded-xl",
957
+ "bg-white dark:bg-gray-800",
958
+ "border border-gray-200 dark:border-gray-700",
959
+ "hover:bg-gray-50 dark:hover:bg-gray-700",
960
+ "hover:border-blue-300 dark:hover:border-blue-600",
961
+ "active:scale-[0.98]",
962
+ "transition-all duration-200",
963
+ "shadow-sm hover:shadow",
964
+ "group"
965
+ ),
966
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
967
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-shrink-0 w-8 h-8 rounded-lg bg-gray-100 dark:bg-gray-700 flex items-center justify-center !text-gray-500 dark:!text-gray-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/30 group-hover:!text-blue-600 dark:group-hover:!text-blue-400 transition-colors", children: prompt.icon || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ArrowIcon, {}) }),
968
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0", children: [
969
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium !text-gray-900 dark:!text-white", children: prompt.text }),
970
+ prompt.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs !text-gray-500 dark:!text-gray-400 mt-0.5 line-clamp-1", children: prompt.description })
971
+ ] }),
972
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
973
+ "svg",
974
+ {
975
+ className: "w-4 h-4 !text-gray-400 group-hover:!text-blue-500 transition-colors flex-shrink-0",
976
+ fill: "none",
977
+ stroke: "currentColor",
978
+ viewBox: "0 0 24 24",
979
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
980
+ "path",
981
+ {
982
+ strokeLinecap: "round",
983
+ strokeLinejoin: "round",
984
+ strokeWidth: 2,
985
+ d: "M9 5l7 7-7 7"
986
+ }
987
+ )
988
+ }
989
+ )
990
+ ] })
991
+ },
992
+ index
993
+ )) }),
994
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "hidden sm:grid sm:grid-cols-2 gap-3", children: normalizedPrompts.map((prompt, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
995
+ "button",
996
+ {
997
+ onClick: () => onPromptClick(prompt.text),
998
+ className: cn(
999
+ "text-left p-4 rounded-xl",
1000
+ "bg-white dark:bg-gray-800",
1001
+ "border border-gray-200 dark:border-gray-700",
1002
+ "hover:bg-gray-50 dark:hover:bg-gray-700",
1003
+ "hover:border-blue-300 dark:hover:border-blue-600",
1004
+ "hover:shadow-md",
1005
+ "active:scale-[0.98]",
1006
+ "transition-all duration-200",
1007
+ "group"
1008
+ ),
1009
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-3", children: [
1010
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-shrink-0 w-9 h-9 rounded-lg bg-gray-100 dark:bg-gray-700 flex items-center justify-center !text-gray-500 dark:!text-gray-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/30 group-hover:!text-blue-600 dark:group-hover:!text-blue-400 transition-colors", children: prompt.icon || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ArrowIcon, {}) }),
1011
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 min-w-0", children: [
1012
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium !text-gray-900 dark:!text-white leading-snug", children: prompt.text }),
1013
+ prompt.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs !text-gray-500 dark:!text-gray-400 mt-1 line-clamp-2", children: prompt.description })
1014
+ ] })
1015
+ ] })
1016
+ },
1017
+ index
1018
+ )) })
1019
+ ] })
1020
+ ] });
1021
+ }
1022
+
725
1023
  // src/components/Chat/MessageList.tsx
726
1024
 
727
- function MessageList({ messages, onAction }) {
1025
+ function MessageList({
1026
+ messages,
1027
+ onAction,
1028
+ welcomeTitle,
1029
+ welcomeSubtitle,
1030
+ welcomeIcon,
1031
+ suggestedPrompts,
1032
+ welcomeVariant,
1033
+ onPromptClick
1034
+ }) {
728
1035
  const listRef = _react.useRef.call(void 0, null);
729
1036
  _react.useEffect.call(void 0, () => {
730
1037
  if (listRef.current) {
731
1038
  listRef.current.scrollTop = listRef.current.scrollHeight;
732
1039
  }
733
1040
  }, [messages]);
734
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: listRef, className: "flex-1 overflow-y-auto px-4 py-4 space-y-3 apteva-scrollbar-hidden", children: messages.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center h-full !text-gray-500 dark:!text-gray-400", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center space-y-2", children: [
735
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-4xl", children: "\u{1F4AC}" }),
736
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No messages yet. Start a conversation!" })
737
- ] }) }) : messages.map((message) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Message, { message, onAction }, message.id)) });
1041
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: listRef, className: "flex-1 overflow-y-auto px-4 py-4 space-y-3 apteva-scrollbar-hidden", children: messages.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1042
+ WelcomeScreen,
1043
+ {
1044
+ title: welcomeTitle,
1045
+ subtitle: welcomeSubtitle,
1046
+ icon: welcomeIcon,
1047
+ prompts: suggestedPrompts,
1048
+ variant: welcomeVariant,
1049
+ onPromptClick: onPromptClick || (() => {
1050
+ })
1051
+ }
1052
+ ) : messages.map((message) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Message, { message, onAction }, message.id)) });
738
1053
  }
739
1054
 
740
1055
  // src/components/Chat/Composer.tsx
741
1056
 
742
1057
 
743
- function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, onFileUpload }) {
1058
+ function Composer({ onSendMessage, placeholder = "Type a message...", disabled = false, onFileUpload, onSwitchMode }) {
744
1059
  const [text, setText] = _react.useState.call(void 0, "");
745
1060
  const [showMenu, setShowMenu] = _react.useState.call(void 0, false);
1061
+ const [pendingFiles, setPendingFiles] = _react.useState.call(void 0, []);
1062
+ const [fileError, setFileError] = _react.useState.call(void 0, null);
746
1063
  const textareaRef = _react.useRef.call(void 0, null);
747
1064
  const fileInputRef = _react.useRef.call(void 0, null);
748
1065
  const handleKeyDown = (e) => {
@@ -752,9 +1069,14 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
752
1069
  }
753
1070
  };
754
1071
  const handleSend = () => {
755
- if (text.trim() && !disabled) {
756
- onSendMessage(text.trim());
1072
+ const hasText = text.trim();
1073
+ const hasFiles = pendingFiles.length > 0;
1074
+ if ((hasText || hasFiles) && !disabled) {
1075
+ const filesToSend = pendingFiles.map((pf) => pf.file);
1076
+ onSendMessage(text.trim(), filesToSend.length > 0 ? filesToSend : void 0);
757
1077
  setText("");
1078
+ setPendingFiles([]);
1079
+ setFileError(null);
758
1080
  if (textareaRef.current) {
759
1081
  textareaRef.current.style.height = "auto";
760
1082
  }
@@ -767,25 +1089,112 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
767
1089
  };
768
1090
  const handleFileSelect = (e) => {
769
1091
  if (e.target.files && e.target.files.length > 0) {
770
- _optionalChain([onFileUpload, 'optionalCall', _10 => _10(e.target.files)]);
1092
+ const files = Array.from(e.target.files);
1093
+ const validFiles = [];
1094
+ const errors = [];
1095
+ files.forEach((file) => {
1096
+ const validation = validateFile(file);
1097
+ if (validation.valid) {
1098
+ const pending = { file };
1099
+ if (file.type.startsWith("image/")) {
1100
+ pending.preview = URL.createObjectURL(file);
1101
+ }
1102
+ validFiles.push(pending);
1103
+ } else {
1104
+ errors.push(validation.error || "Invalid file");
1105
+ }
1106
+ });
1107
+ if (validFiles.length > 0) {
1108
+ setPendingFiles((prev) => [...prev, ...validFiles]);
1109
+ }
1110
+ if (errors.length > 0) {
1111
+ setFileError(errors.join(", "));
1112
+ setTimeout(() => setFileError(null), 5e3);
1113
+ }
1114
+ _optionalChain([onFileUpload, 'optionalCall', _18 => _18(e.target.files)]);
771
1115
  setShowMenu(false);
1116
+ e.target.value = "";
772
1117
  }
773
1118
  };
774
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "px-4 py-3 bg-white dark:bg-gray-900 relative", children: [
1119
+ const removeFile = (index) => {
1120
+ setPendingFiles((prev) => {
1121
+ const file = prev[index];
1122
+ if (file.preview) {
1123
+ URL.revokeObjectURL(file.preview);
1124
+ }
1125
+ return prev.filter((_, i) => i !== index);
1126
+ });
1127
+ };
1128
+ const getFileIcon = (mimeType) => {
1129
+ if (mimeType.startsWith("image/")) {
1130
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
1131
+ }
1132
+ if (mimeType === "application/pdf") {
1133
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) });
1134
+ }
1135
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) });
1136
+ };
1137
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "px-4 py-3 relative", children: [
1138
+ fileError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute bottom-full left-4 right-4 mb-2 p-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg z-20", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 !text-red-700 dark:!text-red-300 text-sm", children: [
1139
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4 flex-shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", 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" }) }),
1140
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: fileError })
1141
+ ] }) }),
775
1142
  showMenu && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
776
1143
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "fixed inset-0 z-10", onClick: () => setShowMenu(false) }),
777
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute bottom-full left-4 mb-2 bg-gray-800 dark:bg-gray-700 rounded-xl shadow-lg overflow-hidden z-20 min-w-[240px]", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
778
- "button",
779
- {
780
- onClick: () => _optionalChain([fileInputRef, 'access', _11 => _11.current, 'optionalAccess', _12 => _12.click, 'call', _13 => _13()]),
781
- 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",
782
- children: [
783
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10.5 3.5L5.5 8.5C4.67157 9.32843 4.67157 10.6716 5.5 11.5C6.32843 12.3284 7.67157 12.3284 8.5 11.5L14.5 5.5C15.8807 4.11929 15.8807 1.88071 14.5 0.5C13.1193 -0.880711 10.8807 -0.880711 9.5 0.5L3.5 6.5C1.56846 8.43154 1.56846 11.5685 3.5 13.5C5.43154 15.4315 8.56846 15.4315 10.5 13.5L15.5 8.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(2, 3)" }) }),
784
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium", children: "Add photos & files" })
785
- ]
786
- }
787
- ) })
1144
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "absolute bottom-full left-4 mb-2 bg-gray-800 dark:bg-gray-700 rounded-xl shadow-lg overflow-hidden z-20 min-w-[240px]", children: [
1145
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1146
+ "button",
1147
+ {
1148
+ onClick: () => {
1149
+ _optionalChain([fileInputRef, 'access', _19 => _19.current, 'optionalAccess', _20 => _20.click, 'call', _21 => _21()]);
1150
+ setShowMenu(false);
1151
+ },
1152
+ 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",
1153
+ children: [
1154
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10.5 3.5L5.5 8.5C4.67157 9.32843 4.67157 10.6716 5.5 11.5C6.32843 12.3284 7.67157 12.3284 8.5 11.5L14.5 5.5C15.8807 4.11929 15.8807 1.88071 14.5 0.5C13.1193 -0.880711 10.8807 -0.880711 9.5 0.5L3.5 6.5C1.56846 8.43154 1.56846 11.5685 3.5 13.5C5.43154 15.4315 8.56846 15.4315 10.5 13.5L15.5 8.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(2, 3)" }) }),
1155
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium", children: "Add photos & files" })
1156
+ ]
1157
+ }
1158
+ ),
1159
+ onSwitchMode && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1160
+ "button",
1161
+ {
1162
+ onClick: () => {
1163
+ onSwitchMode();
1164
+ setShowMenu(false);
1165
+ },
1166
+ 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 border-t border-gray-700 dark:border-gray-600",
1167
+ children: [
1168
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 10V3L4 14h7v7l9-11h-7z" }) }),
1169
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium", children: "Switch to command mode" })
1170
+ ]
1171
+ }
1172
+ )
1173
+ ] })
788
1174
  ] }),
1175
+ pendingFiles.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-2 flex flex-wrap gap-2", children: pendingFiles.map((pf, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1176
+ "div",
1177
+ {
1178
+ className: "relative group flex items-center gap-2 px-3 py-2 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg",
1179
+ children: [
1180
+ pf.preview ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: pf.preview, alt: pf.file.name, className: "w-8 h-8 object-cover rounded" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-8 h-8 flex items-center justify-center bg-gray-200 dark:bg-gray-700 rounded !text-gray-500 dark:!text-gray-400", children: getFileIcon(pf.file.type) }),
1181
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col min-w-0", children: [
1182
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs font-medium !text-gray-700 dark:!text-gray-300 truncate max-w-[120px]", children: pf.file.name }),
1183
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs !text-gray-500 dark:!text-gray-400", children: formatFileSize(pf.file.size) })
1184
+ ] }),
1185
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1186
+ "button",
1187
+ {
1188
+ onClick: () => removeFile(index),
1189
+ className: "absolute -top-1.5 -right-1.5 w-5 h-5 bg-gray-500 hover:bg-red-500 text-white rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity",
1190
+ title: "Remove file",
1191
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1192
+ }
1193
+ )
1194
+ ]
1195
+ },
1196
+ index
1197
+ )) }),
789
1198
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative border-2 border-gray-300 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-900 transition-all duration-300 flex items-center px-3 py-2 gap-3", children: [
790
1199
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
791
1200
  "button",
@@ -814,7 +1223,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
814
1223
  "button",
815
1224
  {
816
1225
  onClick: handleSend,
817
- disabled: !text.trim() || disabled,
1226
+ disabled: !text.trim() && pendingFiles.length === 0 || disabled,
818
1227
  className: "w-8 h-8 rounded-lg flex items-center justify-center font-bold transition-all flex-shrink-0 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 !text-gray-700 dark:!text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-30 disabled:cursor-not-allowed !text-lg",
819
1228
  title: "Send message",
820
1229
  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 3L8 13M8 3L4 7M8 3L12 7", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
@@ -835,8 +1244,341 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
835
1244
  ] });
836
1245
  }
837
1246
 
1247
+ // src/components/Chat/CommandComposer.tsx
1248
+
1249
+
1250
+ function CommandComposer({
1251
+ onExecute,
1252
+ state,
1253
+ response,
1254
+ error,
1255
+ plan,
1256
+ streamedContent,
1257
+ toolName,
1258
+ onApprove,
1259
+ onReject,
1260
+ onReset,
1261
+ onExpand,
1262
+ placeholder = "Enter your command...",
1263
+ disabled = false
1264
+ }) {
1265
+ const [input, setInput] = _react.useState.call(void 0, "");
1266
+ const [pendingFiles, setPendingFiles] = _react.useState.call(void 0, []);
1267
+ const [fileError, setFileError] = _react.useState.call(void 0, null);
1268
+ const [showMenu, setShowMenu] = _react.useState.call(void 0, false);
1269
+ const inputRef = _react.useRef.call(void 0, null);
1270
+ const fileInputRef = _react.useRef.call(void 0, null);
1271
+ const menuButtonRef = _react.useRef.call(void 0, null);
1272
+ const handleSubmit = () => {
1273
+ const hasText = input.trim();
1274
+ const hasFiles = pendingFiles.length > 0;
1275
+ if ((hasText || hasFiles) && !disabled && state === "idle") {
1276
+ const filesToSend = pendingFiles.map((pf) => pf.file);
1277
+ onExecute(input.trim(), filesToSend.length > 0 ? filesToSend : void 0);
1278
+ setInput("");
1279
+ setPendingFiles([]);
1280
+ }
1281
+ };
1282
+ const handleKeyDown = (e) => {
1283
+ if (e.key === "Enter" && !e.shiftKey) {
1284
+ e.preventDefault();
1285
+ handleSubmit();
1286
+ }
1287
+ };
1288
+ const handleNewCommand = () => {
1289
+ _optionalChain([onReset, 'optionalCall', _22 => _22()]);
1290
+ _optionalChain([inputRef, 'access', _23 => _23.current, 'optionalAccess', _24 => _24.focus, 'call', _25 => _25()]);
1291
+ };
1292
+ const handleInputChange = (value) => {
1293
+ setInput(value);
1294
+ if (inputRef.current) {
1295
+ inputRef.current.style.height = "auto";
1296
+ inputRef.current.style.height = `${Math.min(inputRef.current.scrollHeight, 120)}px`;
1297
+ }
1298
+ };
1299
+ const handleFileSelect = (e) => {
1300
+ if (e.target.files && e.target.files.length > 0) {
1301
+ const files = Array.from(e.target.files);
1302
+ const validFiles = [];
1303
+ const errors = [];
1304
+ files.forEach((file) => {
1305
+ const validation = validateFile(file);
1306
+ if (validation.valid) {
1307
+ const pending = { file };
1308
+ if (file.type.startsWith("image/")) {
1309
+ pending.preview = URL.createObjectURL(file);
1310
+ }
1311
+ validFiles.push(pending);
1312
+ } else {
1313
+ errors.push(validation.error || "Invalid file");
1314
+ }
1315
+ });
1316
+ if (validFiles.length > 0) {
1317
+ setPendingFiles((prev) => [...prev, ...validFiles]);
1318
+ }
1319
+ if (errors.length > 0) {
1320
+ setFileError(errors.join(", "));
1321
+ setTimeout(() => setFileError(null), 5e3);
1322
+ }
1323
+ setShowMenu(false);
1324
+ e.target.value = "";
1325
+ }
1326
+ };
1327
+ const removeFile = (index) => {
1328
+ setPendingFiles((prev) => {
1329
+ const file = prev[index];
1330
+ if (file.preview) {
1331
+ URL.revokeObjectURL(file.preview);
1332
+ }
1333
+ return prev.filter((_, i) => i !== index);
1334
+ });
1335
+ };
1336
+ const getFileIcon = (mimeType) => {
1337
+ if (mimeType.startsWith("image/")) {
1338
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
1339
+ }
1340
+ if (mimeType === "application/pdf") {
1341
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) });
1342
+ }
1343
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) });
1344
+ };
1345
+ const getDisplayContent = () => {
1346
+ if (state === "loading") {
1347
+ if (toolName) {
1348
+ return { text: toolName, isToolCall: true };
1349
+ }
1350
+ if (streamedContent) {
1351
+ return { text: streamedContent, isToolCall: false };
1352
+ }
1353
+ return { text: "Processing...", isToolCall: false };
1354
+ }
1355
+ if (state === "success" && response) {
1356
+ return { text: response, isToolCall: false };
1357
+ }
1358
+ if (state === "error" && error) {
1359
+ return { text: error, isToolCall: false };
1360
+ }
1361
+ if (state === "plan-pending" && plan) {
1362
+ return { text: plan, isToolCall: false };
1363
+ }
1364
+ return { text: "", isToolCall: false };
1365
+ };
1366
+ const isShowingResult = state !== "idle";
1367
+ const { text: displayContent, isToolCall } = getDisplayContent();
1368
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "w-full relative", children: [
1369
+ fileError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute -top-12 left-0 right-0 mx-3 p-2 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg z-30", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 !text-red-700 dark:!text-red-300 text-xs", children: [
1370
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-3 h-3 flex-shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", 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" }) }),
1371
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: fileError })
1372
+ ] }) }),
1373
+ showMenu && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1374
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "fixed inset-0 z-[9998]", onClick: () => setShowMenu(false) }),
1375
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1376
+ "div",
1377
+ {
1378
+ className: "fixed bg-gray-800 dark:bg-gray-700 rounded-xl shadow-lg overflow-hidden z-[9999] min-w-[200px]",
1379
+ style: {
1380
+ bottom: "auto",
1381
+ left: _nullishCoalesce(_optionalChain([menuButtonRef, 'access', _26 => _26.current, 'optionalAccess', _27 => _27.getBoundingClientRect, 'call', _28 => _28(), 'access', _29 => _29.left]), () => ( 0)),
1382
+ top: (_nullishCoalesce(_optionalChain([menuButtonRef, 'access', _30 => _30.current, 'optionalAccess', _31 => _31.getBoundingClientRect, 'call', _32 => _32(), 'access', _33 => _33.top]), () => ( 0))) - 8,
1383
+ transform: "translateY(-100%)"
1384
+ },
1385
+ children: [
1386
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1387
+ "button",
1388
+ {
1389
+ onClick: () => {
1390
+ _optionalChain([fileInputRef, 'access', _34 => _34.current, 'optionalAccess', _35 => _35.click, 'call', _36 => _36()]);
1391
+ setShowMenu(false);
1392
+ },
1393
+ 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",
1394
+ children: [
1395
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10.5 3.5L5.5 8.5C4.67157 9.32843 4.67157 10.6716 5.5 11.5C6.32843 12.3284 7.67157 12.3284 8.5 11.5L14.5 5.5C15.8807 4.11929 15.8807 1.88071 14.5 0.5C13.1193 -0.880711 10.8807 -0.880711 9.5 0.5L3.5 6.5C1.56846 8.43154 1.56846 11.5685 3.5 13.5C5.43154 15.4315 8.56846 15.4315 10.5 13.5L15.5 8.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(2, 3)" }) }),
1396
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium", children: "Add photos & files" })
1397
+ ]
1398
+ }
1399
+ ),
1400
+ onExpand && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1401
+ "button",
1402
+ {
1403
+ onClick: () => {
1404
+ onExpand();
1405
+ setShowMenu(false);
1406
+ },
1407
+ 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 border-t border-gray-700 dark:border-gray-600",
1408
+ children: [
1409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4.5 h-4.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" }) }),
1410
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium", children: "Expand to chat" })
1411
+ ]
1412
+ }
1413
+ )
1414
+ ]
1415
+ }
1416
+ )
1417
+ ] }),
1418
+ pendingFiles.length > 0 && state === "idle" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-2 flex flex-wrap gap-2", children: pendingFiles.map((pf, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1419
+ "div",
1420
+ {
1421
+ className: "relative group flex items-center gap-2 px-2 py-1.5 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg",
1422
+ children: [
1423
+ pf.preview ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: pf.preview, alt: pf.file.name, className: "w-6 h-6 object-cover rounded" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-6 h-6 flex items-center justify-center bg-gray-200 dark:bg-gray-700 rounded !text-gray-500 dark:!text-gray-400", children: getFileIcon(pf.file.type) }),
1424
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs font-medium !text-gray-700 dark:!text-gray-300 truncate max-w-[100px]", children: pf.file.name }),
1425
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1426
+ "button",
1427
+ {
1428
+ onClick: () => removeFile(index),
1429
+ className: "w-4 h-4 bg-gray-500 hover:bg-red-500 text-white rounded-full flex items-center justify-center",
1430
+ title: "Remove file",
1431
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-2.5 h-2.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1432
+ }
1433
+ )
1434
+ ]
1435
+ },
1436
+ index
1437
+ )) }),
1438
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1439
+ "div",
1440
+ {
1441
+ className: cn(
1442
+ "flex items-center gap-2 px-3 py-2 border-2 rounded-2xl bg-white dark:bg-gray-900 transition-all duration-200",
1443
+ state === "idle" && "border-gray-200 dark:border-gray-700",
1444
+ state === "loading" && "border-blue-400 dark:border-blue-500",
1445
+ state === "plan-pending" && "border-amber-400 dark:border-amber-500",
1446
+ state === "success" && "border-green-400 dark:border-green-500",
1447
+ state === "error" && "border-red-400 dark:border-red-500"
1448
+ ),
1449
+ children: [
1450
+ state === "idle" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1451
+ "button",
1452
+ {
1453
+ ref: menuButtonRef,
1454
+ onClick: () => setShowMenu(!showMenu),
1455
+ className: "w-8 h-8 rounded-lg flex items-center justify-center transition-all flex-shrink-0 !text-gray-500 dark:!text-gray-400 hover:!text-gray-700 dark:hover:!text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800",
1456
+ title: "More options",
1457
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 5v10M5 10h10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
1458
+ }
1459
+ ),
1460
+ state === "loading" && !toolName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-4 h-4 border-2 border-blue-200 border-t-blue-500 rounded-full animate-spin flex-shrink-0" }),
1461
+ state === "loading" && toolName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" }),
1462
+ state === "idle" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1463
+ "textarea",
1464
+ {
1465
+ ref: inputRef,
1466
+ value: input,
1467
+ onChange: (e) => handleInputChange(e.target.value),
1468
+ onKeyDown: handleKeyDown,
1469
+ placeholder,
1470
+ disabled,
1471
+ rows: 1,
1472
+ className: cn(
1473
+ "flex-1 resize-none bg-transparent border-none focus:outline-none",
1474
+ "!text-gray-900 dark:!text-gray-100 placeholder-gray-400 dark:placeholder-gray-500",
1475
+ "text-sm leading-relaxed py-1",
1476
+ "disabled:opacity-50"
1477
+ ),
1478
+ style: { minHeight: "24px", maxHeight: "120px" }
1479
+ }
1480
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1481
+ "div",
1482
+ {
1483
+ className: cn(
1484
+ "flex-1 text-sm py-1 truncate flex items-center gap-2",
1485
+ state === "loading" && !isToolCall && "!text-gray-600 dark:!text-gray-400",
1486
+ state === "loading" && isToolCall && "!text-blue-600 dark:!text-blue-400",
1487
+ state === "success" && "!text-gray-900 dark:!text-gray-100",
1488
+ state === "error" && "!text-red-600 dark:!text-red-400",
1489
+ state === "plan-pending" && "!text-amber-700 dark:!text-amber-300"
1490
+ ),
1491
+ children: isToolCall ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1492
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-mono", children: displayContent }),
1493
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-400 dark:text-gray-500", children: "Running..." })
1494
+ ] }) : displayContent
1495
+ }
1496
+ ),
1497
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 flex-shrink-0", children: [
1498
+ state === "plan-pending" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1499
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1500
+ "button",
1501
+ {
1502
+ onClick: onApprove,
1503
+ className: "px-2 py-1 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition-colors text-xs font-medium",
1504
+ children: "Approve"
1505
+ }
1506
+ ),
1507
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1508
+ "button",
1509
+ {
1510
+ onClick: onReject,
1511
+ className: "px-2 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors text-xs font-medium",
1512
+ children: "Modify"
1513
+ }
1514
+ )
1515
+ ] }),
1516
+ (state === "success" || state === "error") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1517
+ "button",
1518
+ {
1519
+ onClick: handleNewCommand,
1520
+ className: "w-8 h-8 rounded-lg flex items-center justify-center !text-gray-400 hover:!text-gray-600 dark:hover:!text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors",
1521
+ title: "New command",
1522
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1523
+ }
1524
+ ),
1525
+ state === "idle" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1526
+ "button",
1527
+ {
1528
+ onClick: handleSubmit,
1529
+ disabled: !input.trim() && pendingFiles.length === 0 || disabled,
1530
+ className: cn(
1531
+ "w-8 h-8 rounded-lg flex items-center justify-center transition-all",
1532
+ "border border-gray-200 dark:border-gray-700",
1533
+ "disabled:opacity-30 disabled:cursor-not-allowed",
1534
+ input.trim() || pendingFiles.length > 0 ? "bg-gray-900 dark:bg-white !text-white dark:!text-gray-900 border-gray-900 dark:border-white" : "bg-white dark:bg-gray-800 !text-gray-400"
1535
+ ),
1536
+ title: "Execute command",
1537
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 12h14M12 5l7 7-7 7" }) })
1538
+ }
1539
+ )
1540
+ ] })
1541
+ ]
1542
+ }
1543
+ ),
1544
+ state === "success" && _optionalChain([response, 'optionalAccess', _37 => _37.includes, 'call', _38 => _38("weather")]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-3 p-3 bg-gradient-to-r from-blue-50 to-cyan-50 dark:from-blue-900/20 dark:to-cyan-900/20 border border-blue-200 dark:border-blue-800 rounded-xl", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3", children: [
1545
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-3xl", children: "\u2600\uFE0F" }),
1546
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
1547
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-sm font-medium text-gray-900 dark:text-white", children: "Paris, France" }),
1548
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Sunny, 22\xB0C" })
1549
+ ] }),
1550
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { className: "px-3 py-1 text-xs bg-blue-500 text-white rounded-lg hover:bg-blue-600", children: "Details" })
1551
+ ] }) }),
1552
+ state === "success" && _optionalChain([response, 'optionalAccess', _39 => _39.includes, 'call', _40 => _40("trip")]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-3 p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm", children: [
1553
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: "https://images.unsplash.com/photo-1502602898657-3e91760cbb34?w=400&h=150&fit=crop", alt: "Paris", className: "w-full h-24 object-cover rounded-lg mb-2" }),
1554
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-sm font-medium text-gray-900 dark:text-white", children: "Paris Weekend Getaway" }),
1555
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-xs text-gray-500 dark:text-gray-400 mb-2", children: "3 days \xB7 $850" }),
1556
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2", children: [
1557
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { className: "flex-1 px-2 py-1 text-xs bg-blue-500 text-white rounded-lg hover:bg-blue-600", children: "Book" }),
1558
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { className: "flex-1 px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600", children: "Details" })
1559
+ ] })
1560
+ ] }),
1561
+ state === "success" && _optionalChain([response, 'optionalAccess', _41 => _41.includes, 'call', _42 => _42("task")]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-3 border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden", children: ["Review PR #123", "Update documentation", "Fix login bug"].map((task, i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `flex items-center gap-2 px-3 py-2 ${i > 0 ? "border-t border-gray-100 dark:border-gray-800" : ""}`, children: [
1562
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `w-2 h-2 rounded-full ${i === 0 ? "bg-green-500" : i === 1 ? "bg-yellow-500" : "bg-red-500"}` }),
1563
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex-1 text-sm text-gray-700 dark:text-gray-300", children: task }),
1564
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { className: "text-xs text-blue-500 hover:text-blue-600", children: "View" })
1565
+ ] }, i)) }),
1566
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1567
+ "input",
1568
+ {
1569
+ ref: fileInputRef,
1570
+ type: "file",
1571
+ multiple: true,
1572
+ onChange: handleFileSelect,
1573
+ className: "hidden",
1574
+ accept: "image/*,application/pdf,.doc,.docx,.txt"
1575
+ }
1576
+ )
1577
+ ] });
1578
+ }
1579
+
838
1580
  // src/lib/apteva-client.ts
839
- var DEFAULT_API_URL = "http://localhost:3000/agents";
1581
+ var DEFAULT_API_URL = "http://91.99.200.48:3000/agents";
840
1582
  var DEFAULT_API_KEY = "agt_894abd5966bc9f1e9f8f17f2a6f6b5e0";
841
1583
  var AptevaClient = class {
842
1584
  constructor() {
@@ -920,7 +1662,7 @@ var AptevaClient = class {
920
1662
  const error = await response.json().catch(() => ({ error: "Request failed" }));
921
1663
  throw new Error(error.error || `Request failed with status ${response.status}`);
922
1664
  }
923
- const reader = _optionalChain([response, 'access', _14 => _14.body, 'optionalAccess', _15 => _15.getReader, 'call', _16 => _16()]);
1665
+ const reader = _optionalChain([response, 'access', _43 => _43.body, 'optionalAccess', _44 => _44.getReader, 'call', _45 => _45()]);
924
1666
  if (!reader) {
925
1667
  throw new Error("Response body is not readable");
926
1668
  }
@@ -938,7 +1680,7 @@ var AptevaClient = class {
938
1680
  if (line.startsWith("data: ")) {
939
1681
  const data = line.slice(6);
940
1682
  if (data === "[DONE]") {
941
- _optionalChain([onComplete, 'optionalCall', _17 => _17(threadId)]);
1683
+ _optionalChain([onComplete, 'optionalCall', _46 => _46(threadId)]);
942
1684
  return;
943
1685
  }
944
1686
  try {
@@ -953,10 +1695,10 @@ var AptevaClient = class {
953
1695
  }
954
1696
  }
955
1697
  }
956
- _optionalChain([onComplete, 'optionalCall', _18 => _18(threadId)]);
1698
+ _optionalChain([onComplete, 'optionalCall', _47 => _47(threadId)]);
957
1699
  } catch (error) {
958
1700
  const err = error instanceof Error ? error : new Error("Unknown error");
959
- _optionalChain([onError, 'optionalCall', _19 => _19(err)]);
1701
+ _optionalChain([onError, 'optionalCall', _48 => _48(err)]);
960
1702
  throw err;
961
1703
  }
962
1704
  }
@@ -1009,11 +1751,32 @@ function Chat({
1009
1751
  apiUrl,
1010
1752
  apiKey,
1011
1753
  useMock = false,
1754
+ // Mode switching
1755
+ initialMode = "chat",
1756
+ showModeToggle = false,
1757
+ onModeChange,
1758
+ // Command mode options
1759
+ commandVariant = "default",
1760
+ planMode = false,
1761
+ onPlanModeChange,
1762
+ enableStreaming = true,
1763
+ showProgress = true,
1764
+ loadingText = "Processing...",
1765
+ // Welcome screen
1766
+ welcomeTitle,
1767
+ welcomeSubtitle,
1768
+ welcomeIcon,
1769
+ suggestedPrompts,
1770
+ welcomeVariant,
1771
+ // Events
1012
1772
  onThreadChange,
1013
1773
  onMessageSent,
1014
1774
  onAction,
1015
1775
  onFileUpload,
1016
- placeholder = "Type a message...",
1776
+ onComplete,
1777
+ onError,
1778
+ // UI
1779
+ placeholder,
1017
1780
  showHeader = true,
1018
1781
  headerTitle = "Chat",
1019
1782
  className
@@ -1021,6 +1784,19 @@ function Chat({
1021
1784
  const [messages, setMessages] = _react.useState.call(void 0, initialMessages);
1022
1785
  const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
1023
1786
  const [currentThreadId, setCurrentThreadId] = _react.useState.call(void 0, threadId || null);
1787
+ const [mode, setMode] = _react.useState.call(void 0, initialMode);
1788
+ const [commandState, setCommandState] = _react.useState.call(void 0, "idle");
1789
+ const [commandResult, setCommandResult] = _react.useState.call(void 0, null);
1790
+ const [commandError, setCommandError] = _react.useState.call(void 0, null);
1791
+ const [progress, setProgress] = _react.useState.call(void 0, 0);
1792
+ const [commandInput, setCommandInput] = _react.useState.call(void 0, "");
1793
+ const [streamedContent, setStreamedContent] = _react.useState.call(void 0, "");
1794
+ const [currentToolName, setCurrentToolName] = _react.useState.call(void 0, null);
1795
+ const [plan, setPlan] = _react.useState.call(void 0, "");
1796
+ const [pendingCommand, setPendingCommand] = _react.useState.call(void 0, "");
1797
+ const [internalPlanMode, setInternalPlanMode] = _react.useState.call(void 0, planMode);
1798
+ const [showSettingsMenu, setShowSettingsMenu] = _react.useState.call(void 0, false);
1799
+ const fileInputRef = _react.useRef.call(void 0, null);
1024
1800
  _react.useEffect.call(void 0, () => {
1025
1801
  if (apiUrl || apiKey) {
1026
1802
  aptevaClient.configure({
@@ -1031,21 +1807,48 @@ function Chat({
1031
1807
  }, [apiUrl, apiKey]);
1032
1808
  _react.useEffect.call(void 0, () => {
1033
1809
  if (threadId) {
1034
- console.log("Loading thread:", threadId);
1035
- _optionalChain([onThreadChange, 'optionalCall', _20 => _20(threadId)]);
1810
+ _optionalChain([onThreadChange, 'optionalCall', _49 => _49(threadId)]);
1036
1811
  }
1037
1812
  }, [threadId, onThreadChange]);
1038
- const handleSendMessage = async (text) => {
1813
+ _react.useEffect.call(void 0, () => {
1814
+ setInternalPlanMode(planMode);
1815
+ }, [planMode]);
1816
+ _react.useEffect.call(void 0, () => {
1817
+ const handleClickOutside = (event) => {
1818
+ const target = event.target;
1819
+ if (showSettingsMenu && !target.closest(".settings-menu-container")) {
1820
+ setShowSettingsMenu(false);
1821
+ }
1822
+ };
1823
+ document.addEventListener("mousedown", handleClickOutside);
1824
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1825
+ }, [showSettingsMenu]);
1826
+ const handleModeChange = (newMode) => {
1827
+ setMode(newMode);
1828
+ _optionalChain([onModeChange, 'optionalCall', _50 => _50(newMode)]);
1829
+ if (newMode === "command") {
1830
+ setCommandState("idle");
1831
+ setCommandResult(null);
1832
+ setCommandError(null);
1833
+ }
1834
+ };
1835
+ const defaultPlaceholder = mode === "chat" ? "Type a message..." : "Enter your command...";
1836
+ const handleSendMessage = async (text, files) => {
1837
+ const hasFiles = files && files.length > 0;
1838
+ const fileNames = hasFiles ? files.map((f) => f.name) : [];
1839
+ const displayContent = hasFiles ? `${text}${text ? "\n" : ""}[Attached: ${fileNames.join(", ")}]` : text;
1039
1840
  const userMessage = {
1040
1841
  id: `msg-${Date.now()}`,
1041
1842
  role: "user",
1042
- content: text,
1043
- timestamp: /* @__PURE__ */ new Date()
1843
+ content: displayContent,
1844
+ timestamp: /* @__PURE__ */ new Date(),
1845
+ metadata: hasFiles ? { attachments: fileNames } : void 0
1044
1846
  };
1045
1847
  setMessages((prev) => [...prev, userMessage]);
1046
- _optionalChain([onMessageSent, 'optionalCall', _21 => _21(userMessage)]);
1848
+ _optionalChain([onMessageSent, 'optionalCall', _51 => _51(userMessage)]);
1047
1849
  setIsLoading(true);
1048
1850
  try {
1851
+ const messagePayload = await buildMessageWithAttachments(text, files);
1049
1852
  if (useMock) {
1050
1853
  const response = await generateMockResponse(1e3);
1051
1854
  setMessages((prev) => [...prev, response]);
@@ -1074,10 +1877,7 @@ function Chat({
1074
1877
  ...lastMessage,
1075
1878
  content: currentTextBuffer,
1076
1879
  widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1077
- metadata: {
1078
- ...lastMessage.metadata,
1079
- content_segments: segments
1080
- }
1880
+ metadata: { ...lastMessage.metadata, content_segments: segments }
1081
1881
  }
1082
1882
  ];
1083
1883
  } else {
@@ -1089,9 +1889,7 @@ function Chat({
1089
1889
  content: currentTextBuffer,
1090
1890
  widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1091
1891
  timestamp: /* @__PURE__ */ new Date(),
1092
- metadata: {
1093
- content_segments: segments
1094
- }
1892
+ metadata: { content_segments: segments }
1095
1893
  }
1096
1894
  ];
1097
1895
  }
@@ -1100,21 +1898,19 @@ function Chat({
1100
1898
  await aptevaClient.chatStream(
1101
1899
  {
1102
1900
  agent_id: agentId,
1103
- message: text,
1901
+ message: messagePayload,
1104
1902
  stream: true,
1105
1903
  ...currentThreadId && { thread_id: currentThreadId },
1106
1904
  ...context && { system: context }
1107
1905
  },
1108
1906
  (chunk) => {
1109
1907
  switch (chunk.type) {
1110
- case "start":
1111
- break;
1112
1908
  case "thread_id":
1113
1909
  if (chunk.thread_id) {
1114
1910
  responseThreadId = chunk.thread_id;
1115
1911
  if (!currentThreadId) {
1116
1912
  setCurrentThreadId(chunk.thread_id);
1117
- _optionalChain([onThreadChange, 'optionalCall', _22 => _22(chunk.thread_id)]);
1913
+ _optionalChain([onThreadChange, 'optionalCall', _52 => _52(chunk.thread_id)]);
1118
1914
  }
1119
1915
  }
1120
1916
  break;
@@ -1131,11 +1927,7 @@ function Chat({
1131
1927
  contentSegments.push({ type: "text", content: currentTextBuffer });
1132
1928
  currentTextBuffer = "";
1133
1929
  }
1134
- contentSegments.push({
1135
- type: "tool",
1136
- id: chunk.tool_id,
1137
- name: chunk.tool_name
1138
- });
1930
+ contentSegments.push({ type: "tool", id: chunk.tool_id, name: chunk.tool_name });
1139
1931
  toolInputBuffer = "";
1140
1932
  updateMessage();
1141
1933
  }
@@ -1145,14 +1937,9 @@ function Chat({
1145
1937
  toolInputBuffer += chunk.content;
1146
1938
  }
1147
1939
  break;
1148
- case "tool_use":
1149
- toolInputBuffer = "";
1150
- break;
1151
1940
  case "tool_result":
1152
1941
  if (chunk.tool_id) {
1153
- const toolSegment = contentSegments.find(
1154
- (s) => s.type === "tool" && s.id === chunk.tool_id
1155
- );
1942
+ const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
1156
1943
  if (toolSegment) {
1157
1944
  toolSegment.result = chunk.content;
1158
1945
  }
@@ -1165,14 +1952,8 @@ function Chat({
1165
1952
  updateMessage();
1166
1953
  }
1167
1954
  break;
1168
- case "stop":
1169
- break;
1170
- case "complete":
1171
- break;
1172
1955
  case "error":
1173
1956
  throw new Error(chunk.message || "Stream error");
1174
- default:
1175
- break;
1176
1957
  }
1177
1958
  },
1178
1959
  (threadId2) => {
@@ -1194,10 +1975,7 @@ function Chat({
1194
1975
  id: `msg-${Date.now()}`,
1195
1976
  content: currentTextBuffer || "Response received",
1196
1977
  widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1197
- metadata: {
1198
- thread_id: threadId2,
1199
- content_segments: contentSegments
1200
- }
1978
+ metadata: { thread_id: threadId2, content_segments: contentSegments }
1201
1979
  }
1202
1980
  ];
1203
1981
  }
@@ -1205,7 +1983,7 @@ function Chat({
1205
1983
  });
1206
1984
  if (threadId2 && threadId2 !== currentThreadId) {
1207
1985
  setCurrentThreadId(threadId2);
1208
- _optionalChain([onThreadChange, 'optionalCall', _23 => _23(threadId2)]);
1986
+ _optionalChain([onThreadChange, 'optionalCall', _53 => _53(threadId2)]);
1209
1987
  }
1210
1988
  setIsLoading(false);
1211
1989
  },
@@ -1225,11 +2003,11 @@ function Chat({
1225
2003
  return [...prev, errorMessage];
1226
2004
  });
1227
2005
  setIsLoading(false);
2006
+ _optionalChain([onError, 'optionalCall', _54 => _54(error)]);
1228
2007
  }
1229
2008
  );
1230
2009
  }
1231
2010
  } catch (error) {
1232
- console.error("Chat error:", error);
1233
2011
  const errorMessage = {
1234
2012
  id: `msg-${Date.now()}-error`,
1235
2013
  role: "assistant",
@@ -1238,18 +2016,277 @@ function Chat({
1238
2016
  metadata: { error: true }
1239
2017
  };
1240
2018
  setMessages((prev) => [...prev, errorMessage]);
2019
+ _optionalChain([onError, 'optionalCall', _55 => _55(error instanceof Error ? error : new Error("Unknown error"))]);
1241
2020
  } finally {
1242
2021
  setIsLoading(false);
1243
2022
  }
1244
2023
  };
1245
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col h-full bg-white dark:bg-gray-900", className), children: [
1246
- showHeader && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-4 py-3 bg-white dark:bg-gray-900", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "!text-lg font-semibold !text-gray-900 dark:!text-white", children: headerTitle }) }),
1247
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageList, { messages, onAction }),
1248
- 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..." }),
1249
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Composer, { onSendMessage: handleSendMessage, placeholder, disabled: isLoading, onFileUpload })
2024
+ const executeCommand = async (commandOverride, files) => {
2025
+ const currentCommand = commandOverride || commandInput;
2026
+ if (!currentCommand.trim() && (!files || files.length === 0)) {
2027
+ setCommandError(new Error("Please enter a command"));
2028
+ setCommandState("error");
2029
+ return;
2030
+ }
2031
+ if (internalPlanMode && commandState !== "plan-pending") {
2032
+ setCommandState("loading");
2033
+ setCommandError(null);
2034
+ setCommandInput("");
2035
+ if (useMock) {
2036
+ setTimeout(() => {
2037
+ const mockPlan = `1. Analyze the request: "${currentCommand}"
2038
+ 2. Process the data
2039
+ 3. Generate response
2040
+ 4. Return results`;
2041
+ setPlan(mockPlan);
2042
+ setPendingCommand(currentCommand);
2043
+ setCommandState("plan-pending");
2044
+ }, 800);
2045
+ } else {
2046
+ try {
2047
+ 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.`;
2048
+ const systemMessage = context ? `${context}
2049
+
2050
+ ${planningInstruction}` : planningInstruction;
2051
+ const response = await aptevaClient.chat({
2052
+ agent_id: agentId,
2053
+ message: currentCommand,
2054
+ stream: false,
2055
+ system: systemMessage
2056
+ });
2057
+ setPlan(response.message);
2058
+ setPendingCommand(currentCommand);
2059
+ setCommandState("plan-pending");
2060
+ } catch (err) {
2061
+ const error = err instanceof Error ? err : new Error("Failed to generate plan");
2062
+ setCommandError(error);
2063
+ setCommandState("error");
2064
+ _optionalChain([onError, 'optionalCall', _56 => _56(error)]);
2065
+ }
2066
+ }
2067
+ return;
2068
+ }
2069
+ setCommandState("loading");
2070
+ setCommandError(null);
2071
+ setProgress(0);
2072
+ setStreamedContent("");
2073
+ setCommandInput("");
2074
+ try {
2075
+ if (useMock) {
2076
+ if (enableStreaming) {
2077
+ let accumulatedContent = "";
2078
+ generateMockCommandStream(
2079
+ currentCommand,
2080
+ (chunk) => {
2081
+ if (chunk.type === "token" && chunk.content) {
2082
+ accumulatedContent += chunk.content;
2083
+ setStreamedContent(accumulatedContent);
2084
+ const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
2085
+ setProgress(estimatedProgress);
2086
+ }
2087
+ },
2088
+ (threadId2) => {
2089
+ const result = {
2090
+ success: true,
2091
+ data: { summary: accumulatedContent, thread_id: threadId2 },
2092
+ message: accumulatedContent || "Command executed successfully"
2093
+ };
2094
+ setCommandResult(result);
2095
+ setCommandState("success");
2096
+ setProgress(100);
2097
+ _optionalChain([onComplete, 'optionalCall', _57 => _57(result)]);
2098
+ },
2099
+ (error) => {
2100
+ setCommandError(error);
2101
+ setCommandState("error");
2102
+ _optionalChain([onError, 'optionalCall', _58 => _58(error)]);
2103
+ }
2104
+ );
2105
+ } else {
2106
+ await new Promise((resolve) => setTimeout(resolve, 1500));
2107
+ const result = {
2108
+ success: true,
2109
+ data: { summary: `Executed: ${currentCommand}` },
2110
+ message: `Command executed successfully`
2111
+ };
2112
+ setCommandResult(result);
2113
+ setCommandState("success");
2114
+ setProgress(100);
2115
+ _optionalChain([onComplete, 'optionalCall', _59 => _59(result)]);
2116
+ }
2117
+ } else {
2118
+ 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.`;
2119
+ const systemMessage = context ? `${context}
2120
+
2121
+ ${commandInstruction}` : commandInstruction;
2122
+ const messagePayload = files && files.length > 0 ? await buildMessageWithAttachments(currentCommand, files) : currentCommand;
2123
+ if (enableStreaming) {
2124
+ let accumulatedContent = "";
2125
+ await aptevaClient.chatStream(
2126
+ {
2127
+ agent_id: agentId,
2128
+ message: messagePayload,
2129
+ stream: true,
2130
+ ...currentThreadId && { thread_id: currentThreadId },
2131
+ system: systemMessage
2132
+ },
2133
+ (chunk) => {
2134
+ if ((chunk.type === "token" || chunk.type === "content") && chunk.content) {
2135
+ accumulatedContent += chunk.content;
2136
+ setStreamedContent(accumulatedContent);
2137
+ setCurrentToolName(null);
2138
+ const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
2139
+ setProgress(estimatedProgress);
2140
+ } else if (chunk.type === "tool_call" && chunk.tool_name) {
2141
+ setCurrentToolName(chunk.tool_name);
2142
+ accumulatedContent = "";
2143
+ setStreamedContent("");
2144
+ } else if (chunk.type === "tool_result") {
2145
+ setCurrentToolName(null);
2146
+ } else if (chunk.type === "thread_id" && chunk.thread_id) {
2147
+ if (!currentThreadId) {
2148
+ setCurrentThreadId(chunk.thread_id);
2149
+ _optionalChain([onThreadChange, 'optionalCall', _60 => _60(chunk.thread_id)]);
2150
+ }
2151
+ }
2152
+ },
2153
+ (threadId2) => {
2154
+ const result = {
2155
+ success: true,
2156
+ data: { summary: accumulatedContent, thread_id: threadId2 },
2157
+ message: accumulatedContent || "Command executed successfully"
2158
+ };
2159
+ setCommandResult(result);
2160
+ setCommandState("success");
2161
+ setProgress(100);
2162
+ _optionalChain([onComplete, 'optionalCall', _61 => _61(result)]);
2163
+ },
2164
+ (error) => {
2165
+ setCommandError(error);
2166
+ setCommandState("error");
2167
+ _optionalChain([onError, 'optionalCall', _62 => _62(error)]);
2168
+ }
2169
+ );
2170
+ } else {
2171
+ const response = await aptevaClient.chat({
2172
+ agent_id: agentId,
2173
+ message: messagePayload,
2174
+ stream: false,
2175
+ ...currentThreadId && { thread_id: currentThreadId },
2176
+ system: systemMessage
2177
+ });
2178
+ const result = {
2179
+ success: true,
2180
+ data: { summary: response.message, thread_id: response.thread_id },
2181
+ widgets: response.widgets,
2182
+ message: response.message
2183
+ };
2184
+ setCommandResult(result);
2185
+ setCommandState("success");
2186
+ setProgress(100);
2187
+ _optionalChain([onComplete, 'optionalCall', _63 => _63(result)]);
2188
+ }
2189
+ }
2190
+ } catch (err) {
2191
+ const error = err instanceof Error ? err : new Error("Unknown error");
2192
+ setCommandError(error);
2193
+ setCommandState("error");
2194
+ _optionalChain([onError, 'optionalCall', _64 => _64(error)]);
2195
+ }
2196
+ };
2197
+ const resetCommand = () => {
2198
+ setCommandState("idle");
2199
+ setCommandResult(null);
2200
+ setCommandError(null);
2201
+ setProgress(0);
2202
+ setCommandInput("");
2203
+ setPlan("");
2204
+ setPendingCommand("");
2205
+ setStreamedContent("");
2206
+ setCurrentToolName(null);
2207
+ };
2208
+ const approvePlan = () => {
2209
+ const planToExecute = plan;
2210
+ setPlan("");
2211
+ setPendingCommand("");
2212
+ const executionMessage = `Execute this plan now:
2213
+
2214
+ ${planToExecute}`;
2215
+ executeCommand(executionMessage);
2216
+ };
2217
+ const rejectPlan = () => {
2218
+ setCommandInput(pendingCommand);
2219
+ setPlan("");
2220
+ setPendingCommand("");
2221
+ setCommandState("idle");
2222
+ };
2223
+ const isCompact = commandVariant === "compact";
2224
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col h-full", className), children: [
2225
+ 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 }) }),
2226
+ mode === "chat" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2227
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2228
+ MessageList,
2229
+ {
2230
+ messages,
2231
+ onAction,
2232
+ welcomeTitle,
2233
+ welcomeSubtitle,
2234
+ welcomeIcon,
2235
+ suggestedPrompts,
2236
+ welcomeVariant,
2237
+ onPromptClick: (prompt) => handleSendMessage(prompt)
2238
+ }
2239
+ ),
2240
+ 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..." }),
2241
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2242
+ Composer,
2243
+ {
2244
+ onSendMessage: handleSendMessage,
2245
+ placeholder: placeholder || defaultPlaceholder,
2246
+ disabled: isLoading,
2247
+ onFileUpload,
2248
+ onSwitchMode: showModeToggle ? () => handleModeChange("command") : void 0
2249
+ }
2250
+ )
2251
+ ] }),
2252
+ mode === "command" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 flex flex-col items-center justify-center p-4", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2253
+ CommandComposer,
2254
+ {
2255
+ onExecute: (text, files) => {
2256
+ setCommandInput(text);
2257
+ executeCommand(text, files);
2258
+ },
2259
+ state: commandState,
2260
+ response: _optionalChain([commandResult, 'optionalAccess', _65 => _65.data, 'optionalAccess', _66 => _66.summary]) || _optionalChain([commandResult, 'optionalAccess', _67 => _67.message]),
2261
+ error: _optionalChain([commandError, 'optionalAccess', _68 => _68.message]),
2262
+ plan,
2263
+ streamedContent,
2264
+ toolName: currentToolName,
2265
+ onApprove: approvePlan,
2266
+ onReject: rejectPlan,
2267
+ onReset: resetCommand,
2268
+ onExpand: showModeToggle ? () => handleModeChange("chat") : void 0,
2269
+ placeholder: placeholder || "Enter your command..."
2270
+ }
2271
+ ) }) }),
2272
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "style", { dangerouslySetInnerHTML: {
2273
+ __html: `
2274
+ @keyframes pulse-border {
2275
+ 0%, 100% { border-color: rgb(59, 130, 246); }
2276
+ 50% { border-color: rgb(147, 197, 253); }
2277
+ }
2278
+ .animate-pulse-border {
2279
+ animation: pulse-border 2s ease-in-out infinite;
2280
+ }
2281
+ `
2282
+ } })
1250
2283
  ] });
1251
2284
  }
1252
2285
 
2286
+ // src/components/Chat/CommandOutput.tsx
2287
+
2288
+
2289
+
1253
2290
  // src/components/Command/Command.tsx
1254
2291
 
1255
2292
 
@@ -1385,13 +2422,13 @@ ${planningInstruction}` : planningInstruction;
1385
2422
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1386
2423
  setError(error2);
1387
2424
  setState("error");
1388
- _optionalChain([onError, 'optionalCall', _24 => _24(error2)]);
2425
+ _optionalChain([onError, 'optionalCall', _69 => _69(error2)]);
1389
2426
  });
1390
2427
  } catch (err) {
1391
2428
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1392
2429
  setError(error2);
1393
2430
  setState("error");
1394
- _optionalChain([onError, 'optionalCall', _25 => _25(error2)]);
2431
+ _optionalChain([onError, 'optionalCall', _70 => _70(error2)]);
1395
2432
  }
1396
2433
  }
1397
2434
  return;
@@ -1402,7 +2439,7 @@ ${planningInstruction}` : planningInstruction;
1402
2439
  setStreamedContent("");
1403
2440
  setCommand("");
1404
2441
  setUploadedFiles([]);
1405
- _optionalChain([onStart, 'optionalCall', _26 => _26()]);
2442
+ _optionalChain([onStart, 'optionalCall', _71 => _71()]);
1406
2443
  try {
1407
2444
  if (useMock) {
1408
2445
  if (enableStreaming) {
@@ -1413,16 +2450,16 @@ ${planningInstruction}` : planningInstruction;
1413
2450
  if (chunk.type === "token" && chunk.content) {
1414
2451
  accumulatedContent += chunk.content;
1415
2452
  setStreamedContent(accumulatedContent);
1416
- _optionalChain([onChunk, 'optionalCall', _27 => _27(chunk.content)]);
2453
+ _optionalChain([onChunk, 'optionalCall', _72 => _72(chunk.content)]);
1417
2454
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1418
2455
  setProgress(estimatedProgress);
1419
- _optionalChain([onProgress, 'optionalCall', _28 => _28(estimatedProgress)]);
2456
+ _optionalChain([onProgress, 'optionalCall', _73 => _73(estimatedProgress)]);
1420
2457
  } else if (chunk.type === "widget" && chunk.widget) {
1421
2458
  const widget = chunk.widget;
1422
2459
  setResult((prev) => ({
1423
2460
  success: true,
1424
- data: _optionalChain([prev, 'optionalAccess', _29 => _29.data]) || {},
1425
- widgets: [..._optionalChain([prev, 'optionalAccess', _30 => _30.widgets]) || [], widget],
2461
+ data: _optionalChain([prev, 'optionalAccess', _74 => _74.data]) || {},
2462
+ widgets: [..._optionalChain([prev, 'optionalAccess', _75 => _75.widgets]) || [], widget],
1426
2463
  message: accumulatedContent || "Command executed successfully"
1427
2464
  }));
1428
2465
  }
@@ -1442,19 +2479,19 @@ ${planningInstruction}` : planningInstruction;
1442
2479
  setResult(result2);
1443
2480
  setState("success");
1444
2481
  setProgress(100);
1445
- _optionalChain([onComplete, 'optionalCall', _31 => _31(result2)]);
2482
+ _optionalChain([onComplete, 'optionalCall', _76 => _76(result2)]);
1446
2483
  },
1447
2484
  (error2) => {
1448
2485
  setError(error2);
1449
2486
  setState("error");
1450
- _optionalChain([onError, 'optionalCall', _32 => _32(error2)]);
2487
+ _optionalChain([onError, 'optionalCall', _77 => _77(error2)]);
1451
2488
  }
1452
2489
  );
1453
2490
  } else {
1454
2491
  const progressInterval = setInterval(() => {
1455
2492
  setProgress((prev) => {
1456
2493
  const next = Math.min(prev + 10, 90);
1457
- _optionalChain([onProgress, 'optionalCall', _33 => _33(next)]);
2494
+ _optionalChain([onProgress, 'optionalCall', _78 => _78(next)]);
1458
2495
  return next;
1459
2496
  });
1460
2497
  }, 200);
@@ -1478,7 +2515,7 @@ ${planningInstruction}` : planningInstruction;
1478
2515
  setResult(result2);
1479
2516
  setState("success");
1480
2517
  setProgress(100);
1481
- _optionalChain([onComplete, 'optionalCall', _34 => _34(result2)]);
2518
+ _optionalChain([onComplete, 'optionalCall', _79 => _79(result2)]);
1482
2519
  }
1483
2520
  } else {
1484
2521
  if (enableStreaming) {
@@ -1524,16 +2561,16 @@ ${commandInstruction}` : commandInstruction;
1524
2561
  if (chunk.type === "token" && chunk.content) {
1525
2562
  accumulatedContent += chunk.content;
1526
2563
  setStreamedContent(accumulatedContent);
1527
- _optionalChain([onChunk, 'optionalCall', _35 => _35(chunk.content)]);
2564
+ _optionalChain([onChunk, 'optionalCall', _80 => _80(chunk.content)]);
1528
2565
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1529
2566
  setProgress(estimatedProgress);
1530
- _optionalChain([onProgress, 'optionalCall', _36 => _36(estimatedProgress)]);
2567
+ _optionalChain([onProgress, 'optionalCall', _81 => _81(estimatedProgress)]);
1531
2568
  } else if (chunk.type === "widget" && chunk.widget) {
1532
2569
  const widget = chunk.widget;
1533
2570
  setResult((prev) => ({
1534
2571
  success: true,
1535
- data: _optionalChain([prev, 'optionalAccess', _37 => _37.data]) || {},
1536
- widgets: [..._optionalChain([prev, 'optionalAccess', _38 => _38.widgets]) || [], widget],
2572
+ data: _optionalChain([prev, 'optionalAccess', _82 => _82.data]) || {},
2573
+ widgets: [..._optionalChain([prev, 'optionalAccess', _83 => _83.widgets]) || [], widget],
1537
2574
  message: accumulatedContent || "Command executed successfully"
1538
2575
  }));
1539
2576
  }
@@ -1553,20 +2590,20 @@ ${commandInstruction}` : commandInstruction;
1553
2590
  setResult(result2);
1554
2591
  setState("success");
1555
2592
  setProgress(100);
1556
- _optionalChain([onComplete, 'optionalCall', _39 => _39(result2)]);
2593
+ _optionalChain([onComplete, 'optionalCall', _84 => _84(result2)]);
1557
2594
  },
1558
2595
  (error2) => {
1559
2596
  const err = error2 instanceof Error ? error2 : new Error("Unknown error");
1560
2597
  setError(err);
1561
2598
  setState("error");
1562
- _optionalChain([onError, 'optionalCall', _40 => _40(err)]);
2599
+ _optionalChain([onError, 'optionalCall', _85 => _85(err)]);
1563
2600
  }
1564
2601
  );
1565
2602
  } else {
1566
2603
  const progressInterval = setInterval(() => {
1567
2604
  setProgress((prev) => {
1568
2605
  const next = Math.min(prev + 10, 90);
1569
- _optionalChain([onProgress, 'optionalCall', _41 => _41(next)]);
2606
+ _optionalChain([onProgress, 'optionalCall', _86 => _86(next)]);
1570
2607
  return next;
1571
2608
  });
1572
2609
  }, 200);
@@ -1622,14 +2659,14 @@ ${commandInstruction}` : commandInstruction;
1622
2659
  setResult(result2);
1623
2660
  setState("success");
1624
2661
  setProgress(100);
1625
- _optionalChain([onComplete, 'optionalCall', _42 => _42(result2)]);
2662
+ _optionalChain([onComplete, 'optionalCall', _87 => _87(result2)]);
1626
2663
  }
1627
2664
  }
1628
2665
  } catch (err) {
1629
2666
  const error2 = err instanceof Error ? err : new Error("Unknown error");
1630
2667
  setError(error2);
1631
2668
  setState("error");
1632
- _optionalChain([onError, 'optionalCall', _43 => _43(error2)]);
2669
+ _optionalChain([onError, 'optionalCall', _88 => _88(error2)]);
1633
2670
  }
1634
2671
  };
1635
2672
  const resetCommand = () => {
@@ -1662,14 +2699,14 @@ ${planToExecute}`;
1662
2699
  };
1663
2700
  const handleFileSelect = async (e) => {
1664
2701
  if (e.target.files && e.target.files.length > 0) {
1665
- _optionalChain([onFileUpload, 'optionalCall', _44 => _44(e.target.files)]);
2702
+ _optionalChain([onFileUpload, 'optionalCall', _89 => _89(e.target.files)]);
1666
2703
  const files = [];
1667
2704
  for (let i = 0; i < e.target.files.length; i++) {
1668
2705
  const file = e.target.files[i];
1669
2706
  const reader = new FileReader();
1670
2707
  await new Promise((resolve) => {
1671
2708
  reader.onload = (event) => {
1672
- if (_optionalChain([event, 'access', _45 => _45.target, 'optionalAccess', _46 => _46.result])) {
2709
+ if (_optionalChain([event, 'access', _90 => _90.target, 'optionalAccess', _91 => _91.result])) {
1673
2710
  const fullDataUrl = event.target.result;
1674
2711
  const base64Data = fullDataUrl.split(",")[1];
1675
2712
  if (file.type.startsWith("image/")) {
@@ -1763,7 +2800,7 @@ ${planToExecute}`;
1763
2800
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1764
2801
  "button",
1765
2802
  {
1766
- onClick: () => _optionalChain([fileInputRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.click, 'call', _49 => _49()]),
2803
+ onClick: () => _optionalChain([fileInputRef, 'access', _92 => _92.current, 'optionalAccess', _93 => _93.click, 'call', _94 => _94()]),
1767
2804
  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",
1768
2805
  title: "Attach file",
1769
2806
  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)" }) })
@@ -1982,7 +3019,7 @@ ${planToExecute}`;
1982
3019
  /* @__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" }) }),
1983
3020
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1984
3021
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-semibold text-red-800 dark:text-red-400", children: "Error" }),
1985
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _50 => _50.message]) })
3022
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _95 => _95.message]) })
1986
3023
  ] })
1987
3024
  ] }) }),
1988
3025
  allowInput && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -2010,7 +3047,7 @@ ${planToExecute}`;
2010
3047
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-green-700 dark:text-green-300 text-sm", children: "Command executed successfully" })
2011
3048
  ] })
2012
3049
  ] }),
2013
- _optionalChain([result, 'access', _51 => _51.data, 'optionalAccess', _52 => _52.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 }),
3050
+ _optionalChain([result, 'access', _96 => _96.data, 'optionalAccess', _97 => _97.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 }),
2014
3051
  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,
2015
3052
  WidgetRenderer,
2016
3053
  {
@@ -2061,7 +3098,7 @@ ${planToExecute}`;
2061
3098
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2062
3099
  "button",
2063
3100
  {
2064
- onClick: () => _optionalChain([fileInputRef, 'access', _53 => _53.current, 'optionalAccess', _54 => _54.click, 'call', _55 => _55()]),
3101
+ onClick: () => _optionalChain([fileInputRef, 'access', _98 => _98.current, 'optionalAccess', _99 => _99.click, 'call', _100 => _100()]),
2065
3102
  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",
2066
3103
  title: "Attach file",
2067
3104
  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)" }) })
@@ -2247,25 +3284,25 @@ function Prompt({
2247
3284
  const newValue = e.target.value;
2248
3285
  if (!maxLength || newValue.length <= maxLength) {
2249
3286
  setValue(newValue);
2250
- _optionalChain([onChange, 'optionalCall', _56 => _56(newValue)]);
3287
+ _optionalChain([onChange, 'optionalCall', _101 => _101(newValue)]);
2251
3288
  }
2252
3289
  };
2253
3290
  const handleSubmit = async () => {
2254
3291
  if (value.length < minLength) return;
2255
- _optionalChain([onSubmit, 'optionalCall', _57 => _57(value)]);
3292
+ _optionalChain([onSubmit, 'optionalCall', _102 => _102(value)]);
2256
3293
  setIsLoading(true);
2257
3294
  try {
2258
3295
  if (useMock) {
2259
3296
  await new Promise((resolve) => setTimeout(resolve, 1500));
2260
3297
  const mockResult = `Enhanced version: ${value} [AI-generated content]`;
2261
- _optionalChain([onResult, 'optionalCall', _58 => _58(mockResult)]);
3298
+ _optionalChain([onResult, 'optionalCall', _103 => _103(mockResult)]);
2262
3299
  setValue("");
2263
3300
  } else {
2264
3301
  const response = await aptevaClient.chat({
2265
3302
  agent_id: agentId,
2266
3303
  message: value
2267
3304
  });
2268
- _optionalChain([onResult, 'optionalCall', _59 => _59(response.message)]);
3305
+ _optionalChain([onResult, 'optionalCall', _104 => _104(response.message)]);
2269
3306
  setValue("");
2270
3307
  }
2271
3308
  } catch (error) {
@@ -2360,7 +3397,7 @@ function Stream({
2360
3397
  }, [autoStart]);
2361
3398
  const startStreaming = async () => {
2362
3399
  setIsStreaming(true);
2363
- _optionalChain([onStart, 'optionalCall', _60 => _60()]);
3400
+ _optionalChain([onStart, 'optionalCall', _105 => _105()]);
2364
3401
  try {
2365
3402
  if (useMock) {
2366
3403
  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.";
@@ -2368,13 +3405,13 @@ function Stream({
2368
3405
  mockText,
2369
3406
  (chunk) => {
2370
3407
  setText((prev) => prev + chunk);
2371
- _optionalChain([onChunk, 'optionalCall', _61 => _61(chunk)]);
3408
+ _optionalChain([onChunk, 'optionalCall', _106 => _106(chunk)]);
2372
3409
  },
2373
3410
  typingSpeed
2374
3411
  );
2375
3412
  setIsComplete(true);
2376
3413
  setIsStreaming(false);
2377
- _optionalChain([onComplete, 'optionalCall', _62 => _62(text + mockText)]);
3414
+ _optionalChain([onComplete, 'optionalCall', _107 => _107(text + mockText)]);
2378
3415
  } else {
2379
3416
  let accumulatedText = "";
2380
3417
  await aptevaClient.chatStream(
@@ -2387,24 +3424,24 @@ function Stream({
2387
3424
  if (chunk.type === "token" && chunk.content) {
2388
3425
  accumulatedText += chunk.content;
2389
3426
  setText(accumulatedText);
2390
- _optionalChain([onChunk, 'optionalCall', _63 => _63(chunk.content)]);
3427
+ _optionalChain([onChunk, 'optionalCall', _108 => _108(chunk.content)]);
2391
3428
  }
2392
3429
  },
2393
3430
  () => {
2394
3431
  setIsComplete(true);
2395
3432
  setIsStreaming(false);
2396
- _optionalChain([onComplete, 'optionalCall', _64 => _64(accumulatedText)]);
3433
+ _optionalChain([onComplete, 'optionalCall', _109 => _109(accumulatedText)]);
2397
3434
  },
2398
3435
  (error) => {
2399
3436
  const err = error instanceof Error ? error : new Error("Streaming error");
2400
- _optionalChain([onError, 'optionalCall', _65 => _65(err)]);
3437
+ _optionalChain([onError, 'optionalCall', _110 => _110(err)]);
2401
3438
  setIsStreaming(false);
2402
3439
  }
2403
3440
  );
2404
3441
  }
2405
3442
  } catch (error) {
2406
3443
  const err = error instanceof Error ? error : new Error("Streaming error");
2407
- _optionalChain([onError, 'optionalCall', _66 => _66(err)]);
3444
+ _optionalChain([onError, 'optionalCall', _111 => _111(err)]);
2408
3445
  setIsStreaming(false);
2409
3446
  }
2410
3447
  };
@@ -2496,7 +3533,7 @@ function ThreadList({
2496
3533
  }) {
2497
3534
  const [searchQuery, setSearchQuery] = _react.useState.call(void 0, "");
2498
3535
  const filteredThreads = threads.filter(
2499
- (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _67 => _67.preview, 'optionalAccess', _68 => _68.toLowerCase, 'call', _69 => _69(), 'access', _70 => _70.includes, 'call', _71 => _71(searchQuery.toLowerCase())])
3536
+ (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _112 => _112.preview, 'optionalAccess', _113 => _113.toLowerCase, 'call', _114 => _114(), 'access', _115 => _115.includes, 'call', _116 => _116(searchQuery.toLowerCase())])
2500
3537
  );
2501
3538
  const groupedThreads = groupBy === "date" ? groupThreadsByDate(filteredThreads) : { All: filteredThreads };
2502
3539
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col h-full", children: [
@@ -2518,14 +3555,14 @@ function ThreadList({
2518
3555
  {
2519
3556
  thread,
2520
3557
  isActive: thread.id === currentThreadId,
2521
- onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _72 => _72(thread.id)]),
2522
- onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _73 => _73(thread.id)])
3558
+ onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _117 => _117(thread.id)]),
3559
+ onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _118 => _118(thread.id)])
2523
3560
  },
2524
3561
  thread.id
2525
3562
  ))
2526
3563
  ] }, group)),
2527
3564
  filteredThreads.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-8 text-center text-gray-500", children: [
2528
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-4xl mb-2", children: "\u{1F4AC}" }),
3565
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-10 h-10 mx-auto mb-2 opacity-50", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" }) }),
2529
3566
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No conversations found" })
2530
3567
  ] })
2531
3568
  ] })
@@ -2581,7 +3618,7 @@ function Threads({
2581
3618
  threads.slice(0, 5).map((thread) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2582
3619
  "button",
2583
3620
  {
2584
- onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _74 => _74(thread.id)]),
3621
+ onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _119 => _119(thread.id)]),
2585
3622
  className: cn(
2586
3623
  "px-4 py-2 whitespace-nowrap font-medium transition-colors",
2587
3624
  thread.id === currentThreadId ? "border-b-2 border-apteva-500 text-apteva-500" : "text-gray-600 hover:text-gray-900"