@apteva/apteva-kit 0.1.9 → 0.1.10

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
@@ -564,10 +564,132 @@ function Widgets({
564
564
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn(layoutClasses[layout], spacingClasses[spacing], className), children: widgets.map((widget) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WidgetRenderer, { widget, onAction }, widget.id)) });
565
565
  }
566
566
 
567
+ // src/components/Chat/MarkdownContent.tsx
568
+
569
+ function parseInlineMarkdown(text, keyPrefix = "") {
570
+ const result = [];
571
+ const boldRegex = /(\*\*|__)(.+?)\1/g;
572
+ let lastIndex = 0;
573
+ let match;
574
+ let key = 0;
575
+ while ((match = boldRegex.exec(text)) !== null) {
576
+ if (match.index > lastIndex) {
577
+ result.push(text.slice(lastIndex, match.index));
578
+ }
579
+ result.push(/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: match[2] }, `${keyPrefix}b${key++}`));
580
+ lastIndex = match.index + match[0].length;
581
+ }
582
+ if (lastIndex < text.length) {
583
+ result.push(text.slice(lastIndex));
584
+ }
585
+ return result.length > 0 ? result : [text];
586
+ }
587
+ function parseMarkdown(content) {
588
+ const lines = content.split("\n");
589
+ const result = [];
590
+ let key = 0;
591
+ let i = 0;
592
+ while (i < lines.length) {
593
+ const line = lines[i];
594
+ const ulMatch = line.match(/^(\s*)([-*+])\s+(.*)$/);
595
+ if (ulMatch) {
596
+ const listItems = [];
597
+ const indent = ulMatch[1].length;
598
+ while (i < lines.length) {
599
+ const itemMatch = lines[i].match(/^(\s*)([-*+])\s+(.*)$/);
600
+ if (itemMatch && itemMatch[1].length === indent) {
601
+ listItems.push(
602
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: parseInlineMarkdown(itemMatch[3], `${key}`) }, `li${key++}`)
603
+ );
604
+ i++;
605
+ } else {
606
+ break;
607
+ }
608
+ }
609
+ result.push(
610
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "list-disc pl-5 my-1", children: listItems }, `ul${key++}`)
611
+ );
612
+ continue;
613
+ }
614
+ const olMatch = line.match(/^(\s*)(\d+)\.\s+(.*)$/);
615
+ if (olMatch) {
616
+ const listItems = [];
617
+ const indent = olMatch[1].length;
618
+ while (i < lines.length) {
619
+ const itemMatch = lines[i].match(/^(\s*)(\d+)\.\s+(.*)$/);
620
+ if (itemMatch && itemMatch[1].length === indent) {
621
+ listItems.push(
622
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: parseInlineMarkdown(itemMatch[3], `${key}`) }, `li${key++}`)
623
+ );
624
+ i++;
625
+ } else {
626
+ break;
627
+ }
628
+ }
629
+ result.push(
630
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "list-decimal pl-5 my-1", children: listItems }, `ol${key++}`)
631
+ );
632
+ continue;
633
+ }
634
+ if (line === "") {
635
+ result.push(/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "br", {}, `br${key++}`));
636
+ } else {
637
+ result.push(
638
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { children: [
639
+ parseInlineMarkdown(line, `${key}`),
640
+ i < lines.length - 1 ? "\n" : ""
641
+ ] }, `p${key++}`)
642
+ );
643
+ }
644
+ i++;
645
+ }
646
+ return result;
647
+ }
648
+ function MarkdownContent({ content, className = "" }) {
649
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `markdown-content !text-sm leading-relaxed whitespace-pre-wrap ${className}`, children: parseMarkdown(content) });
650
+ }
651
+
652
+ // src/components/Chat/ToolCall.tsx
653
+
654
+ function ToolCall({ name, status }) {
655
+ 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: [
656
+ status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse" }),
657
+ status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-green-500" }),
658
+ status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-2 h-2 rounded-full bg-red-500" }),
659
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-700 dark:text-gray-300 font-mono", children: name }),
660
+ status === "running" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-gray-500 dark:text-gray-400 ml-auto", children: "Running..." }),
661
+ status === "completed" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-green-600 dark:text-green-400 ml-auto", children: "Completed" }),
662
+ status === "error" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-red-600 dark:text-red-400 ml-auto", children: "Error" })
663
+ ] });
664
+ }
665
+
567
666
  // src/components/Chat/Message.tsx
568
667
 
569
668
  function Message({ message, onAction }) {
570
669
  const isUser = message.role === "user";
670
+ const contentSegments = _optionalChain([message, 'access', _8 => _8.metadata, 'optionalAccess', _9 => _9.content_segments]);
671
+ const renderContent = () => {
672
+ if (isUser) {
673
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "whitespace-pre-wrap !text-sm leading-relaxed", children: message.content });
674
+ }
675
+ if (contentSegments && contentSegments.length > 0) {
676
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: contentSegments.map((segment, index) => {
677
+ if (segment.type === "text") {
678
+ return segment.content ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: segment.content }, `text-${index}`) : null;
679
+ } else if (segment.type === "tool") {
680
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "my-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
681
+ ToolCall,
682
+ {
683
+ name: segment.name,
684
+ status: segment.result !== void 0 ? "completed" : "running"
685
+ }
686
+ ) }, segment.id);
687
+ }
688
+ return null;
689
+ }) });
690
+ }
691
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MarkdownContent, { content: message.content });
692
+ };
571
693
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
572
694
  "div",
573
695
  {
@@ -576,7 +698,7 @@ function Message({ message, onAction }) {
576
698
  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"
577
699
  ),
578
700
  children: [
579
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "whitespace-pre-wrap !text-sm leading-relaxed", children: message.content }),
701
+ renderContent(),
580
702
  message.widgets && message.widgets.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn(isUser ? "mt-3" : "mt-2"), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Widgets, { widgets: message.widgets, onAction, layout: "stack" }) }),
581
703
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("!text-xs opacity-70", isUser ? "mt-1.5 !text-gray-500 dark:!text-gray-400" : "mt-1 !text-gray-500 dark:!text-gray-400"), suppressHydrationWarning: true, children: message.timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) })
582
704
  ]
@@ -629,7 +751,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
629
751
  };
630
752
  const handleFileSelect = (e) => {
631
753
  if (e.target.files && e.target.files.length > 0) {
632
- _optionalChain([onFileUpload, 'optionalCall', _8 => _8(e.target.files)]);
754
+ _optionalChain([onFileUpload, 'optionalCall', _10 => _10(e.target.files)]);
633
755
  setShowMenu(false);
634
756
  }
635
757
  };
@@ -639,7 +761,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
639
761
  /* @__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,
640
762
  "button",
641
763
  {
642
- onClick: () => _optionalChain([fileInputRef, 'access', _9 => _9.current, 'optionalAccess', _10 => _10.click, 'call', _11 => _11()]),
764
+ onClick: () => _optionalChain([fileInputRef, 'access', _11 => _11.current, 'optionalAccess', _12 => _12.click, 'call', _13 => _13()]),
643
765
  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",
644
766
  children: [
645
767
  /* @__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)" }) }),
@@ -697,66 +819,6 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
697
819
  ] });
698
820
  }
699
821
 
700
- // src/components/Chat/Chat.tsx
701
-
702
- function Chat({
703
- agentId,
704
- threadId,
705
- initialMessages = [],
706
- context,
707
- onThreadChange,
708
- onMessageSent,
709
- onAction,
710
- onFileUpload,
711
- placeholder = "Type a message...",
712
- showHeader = true,
713
- headerTitle = "Chat",
714
- className
715
- }) {
716
- const [messages, setMessages] = _react.useState.call(void 0, initialMessages.length > 0 ? initialMessages : mockMessages);
717
- const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
718
- _react.useEffect.call(void 0, () => {
719
- if (threadId) {
720
- console.log("Loading thread:", threadId);
721
- _optionalChain([onThreadChange, 'optionalCall', _12 => _12(threadId)]);
722
- }
723
- }, [threadId, onThreadChange]);
724
- const handleSendMessage = async (text) => {
725
- const userMessage = {
726
- id: `msg-${Date.now()}`,
727
- role: "user",
728
- content: text,
729
- timestamp: /* @__PURE__ */ new Date()
730
- };
731
- setMessages((prev) => [...prev, userMessage]);
732
- _optionalChain([onMessageSent, 'optionalCall', _13 => _13(userMessage)]);
733
- setIsLoading(true);
734
- try {
735
- const response = await generateMockResponse(1e3);
736
- setMessages((prev) => [...prev, response]);
737
- } catch (error) {
738
- console.error("Error generating response:", error);
739
- } finally {
740
- setIsLoading(false);
741
- }
742
- };
743
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col h-full bg-white dark:bg-gray-900", className), children: [
744
- showHeader && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "px-4 py-3 bg-white dark:bg-gray-900", children: [
745
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "!text-lg font-semibold !text-gray-900 dark:!text-white", children: headerTitle }),
746
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "!text-xs !text-gray-500 dark:!text-gray-400", children: [
747
- "Agent: ",
748
- agentId
749
- ] })
750
- ] }),
751
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageList, { messages, onAction }),
752
- 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..." }),
753
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Composer, { onSendMessage: handleSendMessage, placeholder, disabled: isLoading, onFileUpload })
754
- ] });
755
- }
756
-
757
- // src/components/Command/Command.tsx
758
-
759
-
760
822
  // src/lib/apteva-client.ts
761
823
  var DEFAULT_API_URL = "http://localhost:3000/agents";
762
824
  var DEFAULT_API_KEY = "agt_894abd5966bc9f1e9f8f17f2a6f6b5e0";
@@ -868,15 +930,9 @@ var AptevaClient = class {
868
930
  if (chunk.thread_id) {
869
931
  threadId = chunk.thread_id;
870
932
  }
871
- if (chunk.type === "token" && chunk.content) {
872
- onChunk({ type: "token", content: chunk.content });
873
- } else if (chunk.type === "widget" && chunk.widget) {
874
- onChunk({ type: "widget", widget: chunk.widget });
875
- } else if (chunk.type === "complete") {
876
- onChunk({ type: "complete", thread_id: threadId });
877
- }
933
+ onChunk(chunk);
878
934
  } catch (e) {
879
- console.warn("Failed to parse SSE data:", data);
935
+ console.warn("[AptevaClient] Failed to parse SSE data:", data);
880
936
  }
881
937
  }
882
938
  }
@@ -927,8 +983,257 @@ var AptevaClient = class {
927
983
  };
928
984
  var aptevaClient = new AptevaClient();
929
985
 
986
+ // src/components/Chat/Chat.tsx
987
+
988
+ function Chat({
989
+ agentId,
990
+ threadId,
991
+ initialMessages = [],
992
+ context,
993
+ useMock = false,
994
+ onThreadChange,
995
+ onMessageSent,
996
+ onAction,
997
+ onFileUpload,
998
+ placeholder = "Type a message...",
999
+ showHeader = true,
1000
+ headerTitle = "Chat",
1001
+ className
1002
+ }) {
1003
+ const [messages, setMessages] = _react.useState.call(void 0, initialMessages);
1004
+ const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
1005
+ const [currentThreadId, setCurrentThreadId] = _react.useState.call(void 0, threadId || null);
1006
+ _react.useEffect.call(void 0, () => {
1007
+ if (threadId) {
1008
+ console.log("Loading thread:", threadId);
1009
+ _optionalChain([onThreadChange, 'optionalCall', _20 => _20(threadId)]);
1010
+ }
1011
+ }, [threadId, onThreadChange]);
1012
+ const handleSendMessage = async (text) => {
1013
+ const userMessage = {
1014
+ id: `msg-${Date.now()}`,
1015
+ role: "user",
1016
+ content: text,
1017
+ timestamp: /* @__PURE__ */ new Date()
1018
+ };
1019
+ setMessages((prev) => [...prev, userMessage]);
1020
+ _optionalChain([onMessageSent, 'optionalCall', _21 => _21(userMessage)]);
1021
+ setIsLoading(true);
1022
+ try {
1023
+ if (useMock) {
1024
+ const response = await generateMockResponse(1e3);
1025
+ setMessages((prev) => [...prev, response]);
1026
+ } else {
1027
+ let contentSegments = [];
1028
+ let currentTextBuffer = "";
1029
+ let accumulatedWidgets = [];
1030
+ let responseThreadId = currentThreadId;
1031
+ let toolInputBuffer = "";
1032
+ const updateMessage = () => {
1033
+ const segments = [...contentSegments];
1034
+ if (currentTextBuffer) {
1035
+ const lastSegment = segments[segments.length - 1];
1036
+ if (lastSegment && lastSegment.type === "text") {
1037
+ lastSegment.content = currentTextBuffer;
1038
+ } else {
1039
+ segments.push({ type: "text", content: currentTextBuffer });
1040
+ }
1041
+ }
1042
+ setMessages((prev) => {
1043
+ const lastMessage = prev[prev.length - 1];
1044
+ if (lastMessage && lastMessage.role === "assistant") {
1045
+ return [
1046
+ ...prev.slice(0, -1),
1047
+ {
1048
+ ...lastMessage,
1049
+ content: currentTextBuffer,
1050
+ widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1051
+ metadata: {
1052
+ ...lastMessage.metadata,
1053
+ content_segments: segments
1054
+ }
1055
+ }
1056
+ ];
1057
+ } else {
1058
+ return [
1059
+ ...prev,
1060
+ {
1061
+ id: `msg-${Date.now()}-streaming`,
1062
+ role: "assistant",
1063
+ content: currentTextBuffer,
1064
+ widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1065
+ timestamp: /* @__PURE__ */ new Date(),
1066
+ metadata: {
1067
+ content_segments: segments
1068
+ }
1069
+ }
1070
+ ];
1071
+ }
1072
+ });
1073
+ };
1074
+ await aptevaClient.chatStream(
1075
+ {
1076
+ agent_id: agentId,
1077
+ message: text,
1078
+ stream: true,
1079
+ ...currentThreadId && { thread_id: currentThreadId },
1080
+ ...context && { system: context }
1081
+ },
1082
+ (chunk) => {
1083
+ console.log("[Chat] Chunk:", chunk);
1084
+ switch (chunk.type) {
1085
+ case "start":
1086
+ break;
1087
+ case "thread_id":
1088
+ if (chunk.thread_id) {
1089
+ responseThreadId = chunk.thread_id;
1090
+ if (!currentThreadId) {
1091
+ setCurrentThreadId(chunk.thread_id);
1092
+ _optionalChain([onThreadChange, 'optionalCall', _22 => _22(chunk.thread_id)]);
1093
+ }
1094
+ }
1095
+ break;
1096
+ case "content":
1097
+ case "token":
1098
+ if (chunk.content) {
1099
+ currentTextBuffer += chunk.content;
1100
+ updateMessage();
1101
+ }
1102
+ break;
1103
+ case "tool_call":
1104
+ if (chunk.tool_id && chunk.tool_name) {
1105
+ if (currentTextBuffer) {
1106
+ contentSegments.push({ type: "text", content: currentTextBuffer });
1107
+ currentTextBuffer = "";
1108
+ }
1109
+ contentSegments.push({
1110
+ type: "tool",
1111
+ id: chunk.tool_id,
1112
+ name: chunk.tool_name
1113
+ });
1114
+ toolInputBuffer = "";
1115
+ updateMessage();
1116
+ }
1117
+ break;
1118
+ case "tool_input_delta":
1119
+ if (chunk.tool_id && chunk.content) {
1120
+ toolInputBuffer += chunk.content;
1121
+ }
1122
+ break;
1123
+ case "tool_use":
1124
+ toolInputBuffer = "";
1125
+ break;
1126
+ case "tool_result":
1127
+ if (chunk.tool_id) {
1128
+ const toolSegment = contentSegments.find(
1129
+ (s) => s.type === "tool" && s.id === chunk.tool_id
1130
+ );
1131
+ if (toolSegment) {
1132
+ toolSegment.result = chunk.content;
1133
+ }
1134
+ updateMessage();
1135
+ }
1136
+ break;
1137
+ case "widget":
1138
+ if (chunk.widget) {
1139
+ accumulatedWidgets.push(chunk.widget);
1140
+ updateMessage();
1141
+ }
1142
+ break;
1143
+ case "stop":
1144
+ break;
1145
+ case "complete":
1146
+ break;
1147
+ case "error":
1148
+ throw new Error(chunk.message || "Stream error");
1149
+ default:
1150
+ break;
1151
+ }
1152
+ },
1153
+ (threadId2) => {
1154
+ if (currentTextBuffer) {
1155
+ const lastSegment = contentSegments[contentSegments.length - 1];
1156
+ if (lastSegment && lastSegment.type === "text") {
1157
+ lastSegment.content = currentTextBuffer;
1158
+ } else {
1159
+ contentSegments.push({ type: "text", content: currentTextBuffer });
1160
+ }
1161
+ }
1162
+ setMessages((prev) => {
1163
+ const lastMessage = prev[prev.length - 1];
1164
+ if (lastMessage && lastMessage.role === "assistant") {
1165
+ return [
1166
+ ...prev.slice(0, -1),
1167
+ {
1168
+ ...lastMessage,
1169
+ id: `msg-${Date.now()}`,
1170
+ content: currentTextBuffer || "Response received",
1171
+ widgets: accumulatedWidgets.length > 0 ? accumulatedWidgets : void 0,
1172
+ metadata: {
1173
+ thread_id: threadId2,
1174
+ content_segments: contentSegments
1175
+ }
1176
+ }
1177
+ ];
1178
+ }
1179
+ return prev;
1180
+ });
1181
+ if (threadId2 && threadId2 !== currentThreadId) {
1182
+ setCurrentThreadId(threadId2);
1183
+ _optionalChain([onThreadChange, 'optionalCall', _23 => _23(threadId2)]);
1184
+ }
1185
+ setIsLoading(false);
1186
+ },
1187
+ (error) => {
1188
+ const errorMessage = {
1189
+ id: `msg-${Date.now()}-error`,
1190
+ role: "assistant",
1191
+ content: `Error: ${error.message}`,
1192
+ timestamp: /* @__PURE__ */ new Date(),
1193
+ metadata: { error: true }
1194
+ };
1195
+ setMessages((prev) => {
1196
+ const lastMessage = prev[prev.length - 1];
1197
+ if (lastMessage && lastMessage.id.includes("streaming")) {
1198
+ return [...prev.slice(0, -1), errorMessage];
1199
+ }
1200
+ return [...prev, errorMessage];
1201
+ });
1202
+ setIsLoading(false);
1203
+ }
1204
+ );
1205
+ }
1206
+ } catch (error) {
1207
+ console.error("Chat error:", error);
1208
+ const errorMessage = {
1209
+ id: `msg-${Date.now()}-error`,
1210
+ role: "assistant",
1211
+ content: error instanceof Error ? `Error: ${error.message}` : "An error occurred",
1212
+ timestamp: /* @__PURE__ */ new Date(),
1213
+ metadata: { error: true }
1214
+ };
1215
+ setMessages((prev) => [...prev, errorMessage]);
1216
+ } finally {
1217
+ setIsLoading(false);
1218
+ }
1219
+ };
1220
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col h-full bg-white dark:bg-gray-900", className), children: [
1221
+ showHeader && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "px-4 py-3 bg-white dark:bg-gray-900", children: [
1222
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "!text-lg font-semibold !text-gray-900 dark:!text-white", children: headerTitle }),
1223
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "!text-xs !text-gray-500 dark:!text-gray-400", children: [
1224
+ "Agent: ",
1225
+ agentId
1226
+ ] })
1227
+ ] }),
1228
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageList, { messages, onAction }),
1229
+ 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..." }),
1230
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Composer, { onSendMessage: handleSendMessage, placeholder, disabled: isLoading, onFileUpload })
1231
+ ] });
1232
+ }
1233
+
930
1234
  // src/components/Command/Command.tsx
931
1235
 
1236
+
932
1237
  function Command({
933
1238
  agentId,
934
1239
  command: initialCommand,
@@ -1061,13 +1366,13 @@ ${planningInstruction}` : planningInstruction;
1061
1366
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1062
1367
  setError(error2);
1063
1368
  setState("error");
1064
- _optionalChain([onError, 'optionalCall', _20 => _20(error2)]);
1369
+ _optionalChain([onError, 'optionalCall', _24 => _24(error2)]);
1065
1370
  });
1066
1371
  } catch (err) {
1067
1372
  const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1068
1373
  setError(error2);
1069
1374
  setState("error");
1070
- _optionalChain([onError, 'optionalCall', _21 => _21(error2)]);
1375
+ _optionalChain([onError, 'optionalCall', _25 => _25(error2)]);
1071
1376
  }
1072
1377
  }
1073
1378
  return;
@@ -1078,7 +1383,7 @@ ${planningInstruction}` : planningInstruction;
1078
1383
  setStreamedContent("");
1079
1384
  setCommand("");
1080
1385
  setUploadedFiles([]);
1081
- _optionalChain([onStart, 'optionalCall', _22 => _22()]);
1386
+ _optionalChain([onStart, 'optionalCall', _26 => _26()]);
1082
1387
  try {
1083
1388
  if (useMock) {
1084
1389
  if (enableStreaming) {
@@ -1089,16 +1394,16 @@ ${planningInstruction}` : planningInstruction;
1089
1394
  if (chunk.type === "token" && chunk.content) {
1090
1395
  accumulatedContent += chunk.content;
1091
1396
  setStreamedContent(accumulatedContent);
1092
- _optionalChain([onChunk, 'optionalCall', _23 => _23(chunk.content)]);
1397
+ _optionalChain([onChunk, 'optionalCall', _27 => _27(chunk.content)]);
1093
1398
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1094
1399
  setProgress(estimatedProgress);
1095
- _optionalChain([onProgress, 'optionalCall', _24 => _24(estimatedProgress)]);
1400
+ _optionalChain([onProgress, 'optionalCall', _28 => _28(estimatedProgress)]);
1096
1401
  } else if (chunk.type === "widget" && chunk.widget) {
1097
1402
  const widget = chunk.widget;
1098
1403
  setResult((prev) => ({
1099
1404
  success: true,
1100
- data: _optionalChain([prev, 'optionalAccess', _25 => _25.data]) || {},
1101
- widgets: [..._optionalChain([prev, 'optionalAccess', _26 => _26.widgets]) || [], widget],
1405
+ data: _optionalChain([prev, 'optionalAccess', _29 => _29.data]) || {},
1406
+ widgets: [..._optionalChain([prev, 'optionalAccess', _30 => _30.widgets]) || [], widget],
1102
1407
  message: accumulatedContent || "Command executed successfully"
1103
1408
  }));
1104
1409
  }
@@ -1118,19 +1423,19 @@ ${planningInstruction}` : planningInstruction;
1118
1423
  setResult(result2);
1119
1424
  setState("success");
1120
1425
  setProgress(100);
1121
- _optionalChain([onComplete, 'optionalCall', _27 => _27(result2)]);
1426
+ _optionalChain([onComplete, 'optionalCall', _31 => _31(result2)]);
1122
1427
  },
1123
1428
  (error2) => {
1124
1429
  setError(error2);
1125
1430
  setState("error");
1126
- _optionalChain([onError, 'optionalCall', _28 => _28(error2)]);
1431
+ _optionalChain([onError, 'optionalCall', _32 => _32(error2)]);
1127
1432
  }
1128
1433
  );
1129
1434
  } else {
1130
1435
  const progressInterval = setInterval(() => {
1131
1436
  setProgress((prev) => {
1132
1437
  const next = Math.min(prev + 10, 90);
1133
- _optionalChain([onProgress, 'optionalCall', _29 => _29(next)]);
1438
+ _optionalChain([onProgress, 'optionalCall', _33 => _33(next)]);
1134
1439
  return next;
1135
1440
  });
1136
1441
  }, 200);
@@ -1154,7 +1459,7 @@ ${planningInstruction}` : planningInstruction;
1154
1459
  setResult(result2);
1155
1460
  setState("success");
1156
1461
  setProgress(100);
1157
- _optionalChain([onComplete, 'optionalCall', _30 => _30(result2)]);
1462
+ _optionalChain([onComplete, 'optionalCall', _34 => _34(result2)]);
1158
1463
  }
1159
1464
  } else {
1160
1465
  if (enableStreaming) {
@@ -1200,16 +1505,16 @@ ${commandInstruction}` : commandInstruction;
1200
1505
  if (chunk.type === "token" && chunk.content) {
1201
1506
  accumulatedContent += chunk.content;
1202
1507
  setStreamedContent(accumulatedContent);
1203
- _optionalChain([onChunk, 'optionalCall', _31 => _31(chunk.content)]);
1508
+ _optionalChain([onChunk, 'optionalCall', _35 => _35(chunk.content)]);
1204
1509
  const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1205
1510
  setProgress(estimatedProgress);
1206
- _optionalChain([onProgress, 'optionalCall', _32 => _32(estimatedProgress)]);
1511
+ _optionalChain([onProgress, 'optionalCall', _36 => _36(estimatedProgress)]);
1207
1512
  } else if (chunk.type === "widget" && chunk.widget) {
1208
1513
  const widget = chunk.widget;
1209
1514
  setResult((prev) => ({
1210
1515
  success: true,
1211
- data: _optionalChain([prev, 'optionalAccess', _33 => _33.data]) || {},
1212
- widgets: [..._optionalChain([prev, 'optionalAccess', _34 => _34.widgets]) || [], widget],
1516
+ data: _optionalChain([prev, 'optionalAccess', _37 => _37.data]) || {},
1517
+ widgets: [..._optionalChain([prev, 'optionalAccess', _38 => _38.widgets]) || [], widget],
1213
1518
  message: accumulatedContent || "Command executed successfully"
1214
1519
  }));
1215
1520
  }
@@ -1229,20 +1534,20 @@ ${commandInstruction}` : commandInstruction;
1229
1534
  setResult(result2);
1230
1535
  setState("success");
1231
1536
  setProgress(100);
1232
- _optionalChain([onComplete, 'optionalCall', _35 => _35(result2)]);
1537
+ _optionalChain([onComplete, 'optionalCall', _39 => _39(result2)]);
1233
1538
  },
1234
1539
  (error2) => {
1235
1540
  const err = error2 instanceof Error ? error2 : new Error("Unknown error");
1236
1541
  setError(err);
1237
1542
  setState("error");
1238
- _optionalChain([onError, 'optionalCall', _36 => _36(err)]);
1543
+ _optionalChain([onError, 'optionalCall', _40 => _40(err)]);
1239
1544
  }
1240
1545
  );
1241
1546
  } else {
1242
1547
  const progressInterval = setInterval(() => {
1243
1548
  setProgress((prev) => {
1244
1549
  const next = Math.min(prev + 10, 90);
1245
- _optionalChain([onProgress, 'optionalCall', _37 => _37(next)]);
1550
+ _optionalChain([onProgress, 'optionalCall', _41 => _41(next)]);
1246
1551
  return next;
1247
1552
  });
1248
1553
  }, 200);
@@ -1298,14 +1603,14 @@ ${commandInstruction}` : commandInstruction;
1298
1603
  setResult(result2);
1299
1604
  setState("success");
1300
1605
  setProgress(100);
1301
- _optionalChain([onComplete, 'optionalCall', _38 => _38(result2)]);
1606
+ _optionalChain([onComplete, 'optionalCall', _42 => _42(result2)]);
1302
1607
  }
1303
1608
  }
1304
1609
  } catch (err) {
1305
1610
  const error2 = err instanceof Error ? err : new Error("Unknown error");
1306
1611
  setError(error2);
1307
1612
  setState("error");
1308
- _optionalChain([onError, 'optionalCall', _39 => _39(error2)]);
1613
+ _optionalChain([onError, 'optionalCall', _43 => _43(error2)]);
1309
1614
  }
1310
1615
  };
1311
1616
  const resetCommand = () => {
@@ -1338,14 +1643,14 @@ ${planToExecute}`;
1338
1643
  };
1339
1644
  const handleFileSelect = async (e) => {
1340
1645
  if (e.target.files && e.target.files.length > 0) {
1341
- _optionalChain([onFileUpload, 'optionalCall', _40 => _40(e.target.files)]);
1646
+ _optionalChain([onFileUpload, 'optionalCall', _44 => _44(e.target.files)]);
1342
1647
  const files = [];
1343
1648
  for (let i = 0; i < e.target.files.length; i++) {
1344
1649
  const file = e.target.files[i];
1345
1650
  const reader = new FileReader();
1346
1651
  await new Promise((resolve) => {
1347
1652
  reader.onload = (event) => {
1348
- if (_optionalChain([event, 'access', _41 => _41.target, 'optionalAccess', _42 => _42.result])) {
1653
+ if (_optionalChain([event, 'access', _45 => _45.target, 'optionalAccess', _46 => _46.result])) {
1349
1654
  const fullDataUrl = event.target.result;
1350
1655
  const base64Data = fullDataUrl.split(",")[1];
1351
1656
  if (file.type.startsWith("image/")) {
@@ -1439,7 +1744,7 @@ ${planToExecute}`;
1439
1744
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1440
1745
  "button",
1441
1746
  {
1442
- onClick: () => _optionalChain([fileInputRef, 'access', _43 => _43.current, 'optionalAccess', _44 => _44.click, 'call', _45 => _45()]),
1747
+ onClick: () => _optionalChain([fileInputRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.click, 'call', _49 => _49()]),
1443
1748
  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",
1444
1749
  title: "Attach file",
1445
1750
  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)" }) })
@@ -1658,7 +1963,7 @@ ${planToExecute}`;
1658
1963
  /* @__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" }) }),
1659
1964
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1660
1965
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-semibold text-red-800 dark:text-red-400", children: "Error" }),
1661
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _46 => _46.message]) })
1966
+ /* @__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]) })
1662
1967
  ] })
1663
1968
  ] }) }),
1664
1969
  allowInput && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -1686,7 +1991,7 @@ ${planToExecute}`;
1686
1991
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-green-700 dark:text-green-300 text-sm", children: "Command executed successfully" })
1687
1992
  ] })
1688
1993
  ] }),
1689
- _optionalChain([result, 'access', _47 => _47.data, 'optionalAccess', _48 => _48.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 }),
1994
+ _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 }),
1690
1995
  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,
1691
1996
  WidgetRenderer,
1692
1997
  {
@@ -1737,7 +2042,7 @@ ${planToExecute}`;
1737
2042
  enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1738
2043
  "button",
1739
2044
  {
1740
- onClick: () => _optionalChain([fileInputRef, 'access', _49 => _49.current, 'optionalAccess', _50 => _50.click, 'call', _51 => _51()]),
2045
+ onClick: () => _optionalChain([fileInputRef, 'access', _53 => _53.current, 'optionalAccess', _54 => _54.click, 'call', _55 => _55()]),
1741
2046
  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",
1742
2047
  title: "Attach file",
1743
2048
  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)" }) })
@@ -1923,25 +2228,25 @@ function Prompt({
1923
2228
  const newValue = e.target.value;
1924
2229
  if (!maxLength || newValue.length <= maxLength) {
1925
2230
  setValue(newValue);
1926
- _optionalChain([onChange, 'optionalCall', _52 => _52(newValue)]);
2231
+ _optionalChain([onChange, 'optionalCall', _56 => _56(newValue)]);
1927
2232
  }
1928
2233
  };
1929
2234
  const handleSubmit = async () => {
1930
2235
  if (value.length < minLength) return;
1931
- _optionalChain([onSubmit, 'optionalCall', _53 => _53(value)]);
2236
+ _optionalChain([onSubmit, 'optionalCall', _57 => _57(value)]);
1932
2237
  setIsLoading(true);
1933
2238
  try {
1934
2239
  if (useMock) {
1935
2240
  await new Promise((resolve) => setTimeout(resolve, 1500));
1936
2241
  const mockResult = `Enhanced version: ${value} [AI-generated content]`;
1937
- _optionalChain([onResult, 'optionalCall', _54 => _54(mockResult)]);
2242
+ _optionalChain([onResult, 'optionalCall', _58 => _58(mockResult)]);
1938
2243
  setValue("");
1939
2244
  } else {
1940
2245
  const response = await aptevaClient.chat({
1941
2246
  agent_id: agentId,
1942
2247
  message: value
1943
2248
  });
1944
- _optionalChain([onResult, 'optionalCall', _55 => _55(response.message)]);
2249
+ _optionalChain([onResult, 'optionalCall', _59 => _59(response.message)]);
1945
2250
  setValue("");
1946
2251
  }
1947
2252
  } catch (error) {
@@ -2036,7 +2341,7 @@ function Stream({
2036
2341
  }, [autoStart]);
2037
2342
  const startStreaming = async () => {
2038
2343
  setIsStreaming(true);
2039
- _optionalChain([onStart, 'optionalCall', _56 => _56()]);
2344
+ _optionalChain([onStart, 'optionalCall', _60 => _60()]);
2040
2345
  try {
2041
2346
  if (useMock) {
2042
2347
  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.";
@@ -2044,13 +2349,13 @@ function Stream({
2044
2349
  mockText,
2045
2350
  (chunk) => {
2046
2351
  setText((prev) => prev + chunk);
2047
- _optionalChain([onChunk, 'optionalCall', _57 => _57(chunk)]);
2352
+ _optionalChain([onChunk, 'optionalCall', _61 => _61(chunk)]);
2048
2353
  },
2049
2354
  typingSpeed
2050
2355
  );
2051
2356
  setIsComplete(true);
2052
2357
  setIsStreaming(false);
2053
- _optionalChain([onComplete, 'optionalCall', _58 => _58(text + mockText)]);
2358
+ _optionalChain([onComplete, 'optionalCall', _62 => _62(text + mockText)]);
2054
2359
  } else {
2055
2360
  let accumulatedText = "";
2056
2361
  await aptevaClient.chatStream(
@@ -2063,24 +2368,24 @@ function Stream({
2063
2368
  if (chunk.type === "token" && chunk.content) {
2064
2369
  accumulatedText += chunk.content;
2065
2370
  setText(accumulatedText);
2066
- _optionalChain([onChunk, 'optionalCall', _59 => _59(chunk.content)]);
2371
+ _optionalChain([onChunk, 'optionalCall', _63 => _63(chunk.content)]);
2067
2372
  }
2068
2373
  },
2069
2374
  () => {
2070
2375
  setIsComplete(true);
2071
2376
  setIsStreaming(false);
2072
- _optionalChain([onComplete, 'optionalCall', _60 => _60(accumulatedText)]);
2377
+ _optionalChain([onComplete, 'optionalCall', _64 => _64(accumulatedText)]);
2073
2378
  },
2074
2379
  (error) => {
2075
2380
  const err = error instanceof Error ? error : new Error("Streaming error");
2076
- _optionalChain([onError, 'optionalCall', _61 => _61(err)]);
2381
+ _optionalChain([onError, 'optionalCall', _65 => _65(err)]);
2077
2382
  setIsStreaming(false);
2078
2383
  }
2079
2384
  );
2080
2385
  }
2081
2386
  } catch (error) {
2082
2387
  const err = error instanceof Error ? error : new Error("Streaming error");
2083
- _optionalChain([onError, 'optionalCall', _62 => _62(err)]);
2388
+ _optionalChain([onError, 'optionalCall', _66 => _66(err)]);
2084
2389
  setIsStreaming(false);
2085
2390
  }
2086
2391
  };
@@ -2172,7 +2477,7 @@ function ThreadList({
2172
2477
  }) {
2173
2478
  const [searchQuery, setSearchQuery] = _react.useState.call(void 0, "");
2174
2479
  const filteredThreads = threads.filter(
2175
- (thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _63 => _63.preview, 'optionalAccess', _64 => _64.toLowerCase, 'call', _65 => _65(), 'access', _66 => _66.includes, 'call', _67 => _67(searchQuery.toLowerCase())])
2480
+ (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())])
2176
2481
  );
2177
2482
  const groupedThreads = groupBy === "date" ? groupThreadsByDate(filteredThreads) : { All: filteredThreads };
2178
2483
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col h-full", children: [
@@ -2194,8 +2499,8 @@ function ThreadList({
2194
2499
  {
2195
2500
  thread,
2196
2501
  isActive: thread.id === currentThreadId,
2197
- onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _68 => _68(thread.id)]),
2198
- onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _69 => _69(thread.id)])
2502
+ onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _72 => _72(thread.id)]),
2503
+ onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _73 => _73(thread.id)])
2199
2504
  },
2200
2505
  thread.id
2201
2506
  ))
@@ -2257,7 +2562,7 @@ function Threads({
2257
2562
  threads.slice(0, 5).map((thread) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2258
2563
  "button",
2259
2564
  {
2260
- onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _70 => _70(thread.id)]),
2565
+ onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _74 => _74(thread.id)]),
2261
2566
  className: cn(
2262
2567
  "px-4 py-2 whitespace-nowrap font-medium transition-colors",
2263
2568
  thread.id === currentThreadId ? "border-b-2 border-apteva-500 text-apteva-500" : "text-gray-600 hover:text-gray-900"