@apteva/apteva-kit 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,7 @@
1
1
  "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
5
 
3
6
  // src/components/Chat/Chat.tsx
4
7
  import { useState as useState2, useEffect as useEffect3 } from "react";
@@ -182,6 +185,237 @@ function generateMockStreamingResponse(text, onChunk, typingSpeed = 30) {
182
185
  }, typingSpeed);
183
186
  });
184
187
  }
188
+ function generateMockPlan(command) {
189
+ const lowerCommand = command.toLowerCase();
190
+ if (lowerCommand.includes("analyze") || lowerCommand.includes("analysis")) {
191
+ return `**Plan:**
192
+
193
+ 1. Fetch data from the analytics database
194
+ 2. Apply filters and aggregations
195
+ 3. Calculate key metrics and trends
196
+ 4. Generate visualization data
197
+ 5. Compile insights and recommendations`;
198
+ }
199
+ if (lowerCommand.includes("sales") || lowerCommand.includes("revenue")) {
200
+ return `**Plan:**
201
+
202
+ 1. Query sales records for the specified period
203
+ 2. Calculate total revenue and growth rates
204
+ 3. Break down performance by product category
205
+ 4. Analyze regional distribution
206
+ 5. Present findings in charts and summary`;
207
+ }
208
+ if (lowerCommand.includes("report") || lowerCommand.includes("summary")) {
209
+ return `**Plan:**
210
+
211
+ 1. Gather data from all relevant sources
212
+ 2. Aggregate metrics across categories
213
+ 3. Identify key trends and anomalies
214
+ 4. Generate executive summary
215
+ 5. Create detailed breakdowns with visualizations`;
216
+ }
217
+ if (lowerCommand.includes("customer") || lowerCommand.includes("user")) {
218
+ return `**Plan:**
219
+
220
+ 1. Pull customer data from CRM
221
+ 2. Calculate engagement metrics
222
+ 3. Segment users by behavior patterns
223
+ 4. Analyze satisfaction scores
224
+ 5. Generate customer insights report`;
225
+ }
226
+ if (lowerCommand.includes("task") || lowerCommand.includes("todo") || lowerCommand.includes("work") || lowerCommand.includes("completed")) {
227
+ return `**Plan:**
228
+
229
+ 1. Retrieve task records from the database
230
+ 2. Filter by status and date range
231
+ 3. Organize by priority and category
232
+ 4. Calculate completion metrics
233
+ 5. Display in interactive list format`;
234
+ }
235
+ return `**Plan:**
236
+
237
+ 1. Parse and understand the command requirements
238
+ 2. Gather necessary data from available sources
239
+ 3. Process and analyze the information
240
+ 4. Format results for optimal presentation
241
+ 5. Return response with any relevant visualizations`;
242
+ }
243
+ function generateMockCommandResponse(command) {
244
+ const lowerCommand = command.toLowerCase();
245
+ if (lowerCommand.includes("analyze") || lowerCommand.includes("analysis")) {
246
+ return `Analysis complete for "${command}". Found 247 records with an average value of $1,234. The data shows a 23% increase compared to last quarter. Key insights: Revenue is up, customer satisfaction improved by 15%, and operational costs decreased by 8%.`;
247
+ }
248
+ if (lowerCommand.includes("sales") || lowerCommand.includes("revenue")) {
249
+ return `Sales data processed: Q4 2024 revenue reached $2.4M, representing 18% growth year-over-year. Top performing products: Enterprise Plan (+45%), Pro Plan (+32%), Basic Plan (+12%). Regional breakdown: North America (52%), Europe (31%), APAC (17%).`;
250
+ }
251
+ if (lowerCommand.includes("report") || lowerCommand.includes("summary")) {
252
+ return `Report generated successfully. Executive Summary: Overall performance exceeded targets by 12%. Marketing ROI improved to 3.2x, customer acquisition cost reduced by 18%, and lifetime value increased by 24%. Detailed breakdown available in attached widgets.`;
253
+ }
254
+ if (lowerCommand.includes("data") || lowerCommand.includes("metrics")) {
255
+ return `Data metrics retrieved: 1,847 active users, 12,394 sessions this month, 94.2% uptime, average response time 127ms. Performance is within acceptable parameters. No critical issues detected.`;
256
+ }
257
+ if (lowerCommand.includes("customer") || lowerCommand.includes("user")) {
258
+ return `Customer analysis complete: 523 new customers this month, 89% retention rate, average satisfaction score 4.6/5. Top feedback themes: excellent support (87%), easy to use (72%), good value (68%). 3 support tickets pending review.`;
259
+ }
260
+ return `This is a mock response showing how your agent would process and respond to commands. The actual response would be generated by your AI agent based on real data and context.`;
261
+ }
262
+ function generateMockCommandWithWidgets(command) {
263
+ const message = generateMockCommandResponse(command);
264
+ const lowerCommand = command.toLowerCase();
265
+ let widgets = [];
266
+ let action;
267
+ if (lowerCommand.includes("sales") || lowerCommand.includes("revenue") || lowerCommand.includes("analyze")) {
268
+ widgets.push({
269
+ type: "card",
270
+ id: `widget-${Date.now()}-1`,
271
+ props: {
272
+ title: "Q4 2024 Performance",
273
+ description: "Revenue: $2.4M (+18% YoY)",
274
+ footer: "Updated: " + (/* @__PURE__ */ new Date()).toLocaleDateString()
275
+ },
276
+ actions: [
277
+ {
278
+ type: "view_details",
279
+ label: "View Details",
280
+ handler: "client",
281
+ payload: { reportId: "q4-2024" }
282
+ }
283
+ ]
284
+ });
285
+ }
286
+ if (lowerCommand.includes("customer") || lowerCommand.includes("user")) {
287
+ widgets.push({
288
+ type: "list",
289
+ id: `widget-${Date.now()}-2`,
290
+ props: {
291
+ items: [
292
+ {
293
+ id: "metric-1",
294
+ title: "Active Users",
295
+ subtitle: "1,847 users",
296
+ description: "+12% from last month"
297
+ },
298
+ {
299
+ id: "metric-2",
300
+ title: "Retention Rate",
301
+ subtitle: "89%",
302
+ description: "Above industry average"
303
+ },
304
+ {
305
+ id: "metric-3",
306
+ title: "Satisfaction Score",
307
+ subtitle: "4.6/5",
308
+ description: "Based on 234 reviews"
309
+ }
310
+ ]
311
+ }
312
+ });
313
+ }
314
+ if (lowerCommand.includes("task") || lowerCommand.includes("todo") || lowerCommand.includes("work") || lowerCommand.includes("completed")) {
315
+ widgets.push({
316
+ type: "list",
317
+ id: `widget-${Date.now()}-tasks`,
318
+ props: {
319
+ items: [
320
+ {
321
+ id: "task-1",
322
+ title: "Implement user authentication",
323
+ subtitle: "Created just now",
324
+ description: "Added OAuth 2.0 support with Google and GitHub providers",
325
+ backgroundColor: "rgba(59, 130, 246, 0.15)",
326
+ metadata: {
327
+ status: "created",
328
+ priority: "high",
329
+ tags: ["backend", "security"]
330
+ }
331
+ },
332
+ {
333
+ id: "task-2",
334
+ title: "Update API documentation",
335
+ subtitle: "Modified 2 minutes ago",
336
+ description: "Changed endpoint descriptions and added new examples",
337
+ backgroundColor: "rgba(234, 179, 8, 0.15)",
338
+ metadata: {
339
+ status: "modified",
340
+ priority: "medium",
341
+ tags: ["docs"]
342
+ }
343
+ },
344
+ {
345
+ id: "task-3",
346
+ title: "Fix login redirect bug",
347
+ subtitle: "Completed 5 minutes ago",
348
+ description: "Users now properly redirected after successful login",
349
+ backgroundColor: "rgba(34, 197, 94, 0.15)",
350
+ metadata: {
351
+ status: "completed",
352
+ priority: "urgent",
353
+ tags: ["bugfix", "auth"]
354
+ }
355
+ }
356
+ ]
357
+ },
358
+ actions: [
359
+ {
360
+ type: "view_task",
361
+ label: "View",
362
+ handler: "client",
363
+ payload: {}
364
+ },
365
+ {
366
+ type: "undo",
367
+ label: "Undo",
368
+ handler: "server",
369
+ payload: {}
370
+ }
371
+ ]
372
+ });
373
+ action = {
374
+ type: "update_database",
375
+ payload: {
376
+ table: "tasks",
377
+ operation: "mark_as_viewed",
378
+ taskIds: ["task-1", "task-2", "task-3"],
379
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
380
+ }
381
+ };
382
+ }
383
+ if (lowerCommand.includes("analyze") || lowerCommand.includes("analysis")) {
384
+ action = {
385
+ type: "send_notification",
386
+ payload: {
387
+ recipient: "team@company.com",
388
+ subject: "Analysis Complete",
389
+ message: "Your requested analysis has been completed and is ready for review."
390
+ }
391
+ };
392
+ }
393
+ return { message, widgets, action };
394
+ }
395
+ function generateMockCommandStream(command, onChunk, onComplete, onError, typingSpeed = 30) {
396
+ const { message, widgets } = generateMockCommandWithWidgets(command);
397
+ const words = message.split(" ");
398
+ let currentIndex = 0;
399
+ const interval = setInterval(() => {
400
+ try {
401
+ if (currentIndex < words.length) {
402
+ onChunk({ type: "token", content: words[currentIndex] + " " });
403
+ currentIndex++;
404
+ } else {
405
+ clearInterval(interval);
406
+ widgets.forEach((widget) => {
407
+ onChunk({ type: "widget", widget });
408
+ });
409
+ const threadId = `mock_thread_${Date.now()}`;
410
+ onChunk({ type: "complete" });
411
+ onComplete(threadId);
412
+ }
413
+ } catch (error) {
414
+ clearInterval(interval);
415
+ onError(error instanceof Error ? error : new Error("Mock streaming error"));
416
+ }
417
+ }, typingSpeed);
418
+ }
185
419
 
186
420
  // src/components/Widgets/Widgets.tsx
187
421
  import { useEffect } from "react";
@@ -223,7 +457,8 @@ function List({ widget, onAction }) {
223
457
  return /* @__PURE__ */ jsx2("div", { className: "border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-900 overflow-hidden", children: items.map((item, index) => /* @__PURE__ */ jsxs2(
224
458
  "div",
225
459
  {
226
- className: `flex items-center p-4 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors ${index !== items.length - 1 ? "border-b border-gray-200 dark:border-gray-700" : ""}`,
460
+ className: `flex items-center p-4 transition-colors ${index !== items.length - 1 ? "border-b border-gray-200 dark:border-gray-700" : ""} ${!item.backgroundColor ? "hover:bg-gray-50 dark:hover:bg-gray-800" : ""}`,
461
+ style: item.backgroundColor ? { backgroundColor: item.backgroundColor } : void 0,
227
462
  children: [
228
463
  item.image && /* @__PURE__ */ jsx2("img", { src: item.image, alt: item.title, className: "w-16 h-16 rounded object-cover" }),
229
464
  /* @__PURE__ */ jsxs2("div", { className: `flex-1 ${item.image ? "ml-4" : ""}`, children: [
@@ -468,6 +703,7 @@ function Chat({
468
703
  agentId,
469
704
  threadId,
470
705
  initialMessages = [],
706
+ context,
471
707
  onThreadChange,
472
708
  onMessageSent,
473
709
  onAction,
@@ -520,6 +756,178 @@ function Chat({
520
756
 
521
757
  // src/components/Command/Command.tsx
522
758
  import React, { useState as useState3, useEffect as useEffect4 } from "react";
759
+
760
+ // src/lib/apteva-client.ts
761
+ var DEFAULT_API_URL = "http://localhost:3000/agents";
762
+ var DEFAULT_API_KEY = "agt_894abd5966bc9f1e9f8f17f2a6f6b5e0";
763
+ var AptevaClient = class {
764
+ constructor() {
765
+ __publicField(this, "config");
766
+ this.config = {
767
+ apiUrl: DEFAULT_API_URL,
768
+ apiKey: DEFAULT_API_KEY
769
+ };
770
+ }
771
+ /**
772
+ * Update client configuration (optional - users can override defaults)
773
+ */
774
+ configure(config) {
775
+ if (config.apiUrl) this.config.apiUrl = config.apiUrl;
776
+ if (config.apiKey) this.config.apiKey = config.apiKey;
777
+ }
778
+ /**
779
+ * Get current configuration
780
+ */
781
+ getConfig() {
782
+ return { ...this.config };
783
+ }
784
+ /**
785
+ * Send a chat message to an agent
786
+ */
787
+ async chat(request) {
788
+ try {
789
+ console.log("[AptevaClient] Chat request:", {
790
+ agent_id: request.agent_id,
791
+ message: typeof request.message === "string" ? request.message.substring(0, 100) + "..." : "[multi-part message]",
792
+ system: request.system,
793
+ stream: request.stream
794
+ });
795
+ const response = await fetch(`${this.config.apiUrl}/chat`, {
796
+ method: "POST",
797
+ headers: {
798
+ "Content-Type": "application/json",
799
+ "X-API-Key": this.config.apiKey
800
+ },
801
+ body: JSON.stringify(request)
802
+ });
803
+ if (!response.ok) {
804
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
805
+ throw new Error(error.error || `Request failed with status ${response.status}`);
806
+ }
807
+ const data = await response.json();
808
+ return {
809
+ message: data.response || data.message || "",
810
+ thread_id: data.thread_id,
811
+ widgets: data.widgets
812
+ };
813
+ } catch (error) {
814
+ console.error("Chat API error:", error);
815
+ throw error;
816
+ }
817
+ }
818
+ /**
819
+ * Send a chat message with streaming response
820
+ */
821
+ async chatStream(request, onChunk, onComplete, onError) {
822
+ try {
823
+ console.log("[AptevaClient] Chat stream request:", {
824
+ agent_id: request.agent_id,
825
+ message: typeof request.message === "string" ? request.message.substring(0, 100) + "..." : "[multi-part message]",
826
+ system: request.system,
827
+ stream: request.stream
828
+ });
829
+ const response = await fetch(`${this.config.apiUrl}/chat`, {
830
+ method: "POST",
831
+ headers: {
832
+ "Content-Type": "application/json",
833
+ "X-API-Key": this.config.apiKey,
834
+ "Accept": "text/event-stream"
835
+ },
836
+ body: JSON.stringify({
837
+ ...request,
838
+ stream: true
839
+ })
840
+ });
841
+ if (!response.ok) {
842
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
843
+ throw new Error(error.error || `Request failed with status ${response.status}`);
844
+ }
845
+ const reader = response.body?.getReader();
846
+ if (!reader) {
847
+ throw new Error("Response body is not readable");
848
+ }
849
+ const decoder = new TextDecoder();
850
+ let buffer = "";
851
+ let threadId = "";
852
+ while (true) {
853
+ const { done, value } = await reader.read();
854
+ if (done) break;
855
+ buffer += decoder.decode(value, { stream: true });
856
+ const lines = buffer.split("\n");
857
+ buffer = lines.pop() || "";
858
+ for (const line of lines) {
859
+ if (!line.trim() || line.startsWith(":")) continue;
860
+ if (line.startsWith("data: ")) {
861
+ const data = line.slice(6);
862
+ if (data === "[DONE]") {
863
+ onComplete?.(threadId);
864
+ return;
865
+ }
866
+ try {
867
+ const chunk = JSON.parse(data);
868
+ if (chunk.thread_id) {
869
+ threadId = chunk.thread_id;
870
+ }
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
+ }
878
+ } catch (e) {
879
+ console.warn("Failed to parse SSE data:", data);
880
+ }
881
+ }
882
+ }
883
+ }
884
+ onComplete?.(threadId);
885
+ } catch (error) {
886
+ const err = error instanceof Error ? error : new Error("Unknown error");
887
+ onError?.(err);
888
+ throw err;
889
+ }
890
+ }
891
+ /**
892
+ * Create a new thread
893
+ */
894
+ async createThread(agentId, metadata) {
895
+ const response = await fetch(`${this.config.apiUrl}/agents/${agentId}/threads`, {
896
+ method: "POST",
897
+ headers: {
898
+ "Content-Type": "application/json",
899
+ "X-API-Key": this.config.apiKey
900
+ },
901
+ body: JSON.stringify({ metadata })
902
+ });
903
+ if (!response.ok) {
904
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
905
+ throw new Error(error.error || `Request failed with status ${response.status}`);
906
+ }
907
+ const data = await response.json();
908
+ return data.thread_id;
909
+ }
910
+ /**
911
+ * Get thread messages
912
+ */
913
+ async getThreadMessages(threadId) {
914
+ const response = await fetch(`${this.config.apiUrl}/threads/${threadId}/messages`, {
915
+ method: "GET",
916
+ headers: {
917
+ "X-API-Key": this.config.apiKey
918
+ }
919
+ });
920
+ if (!response.ok) {
921
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
922
+ throw new Error(error.error || `Request failed with status ${response.status}`);
923
+ }
924
+ const data = await response.json();
925
+ return data.messages;
926
+ }
927
+ };
928
+ var aptevaClient = new AptevaClient();
929
+
930
+ // src/components/Command/Command.tsx
523
931
  import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
524
932
  function Command({
525
933
  agentId,
@@ -530,12 +938,17 @@ function Command({
530
938
  placeholder = "Enter your command...",
531
939
  submitButtonText = "Execute",
532
940
  variant = "default",
941
+ useMock = false,
942
+ planMode = false,
943
+ onPlanModeChange,
944
+ enableFileUpload = true,
533
945
  onStart,
534
946
  onProgress,
535
947
  onChunk,
536
948
  onComplete,
537
949
  onError,
538
950
  onFileUpload,
951
+ onAction,
539
952
  loadingText = "Processing...",
540
953
  showProgress = true,
541
954
  enableStreaming = false,
@@ -548,82 +961,345 @@ function Command({
548
961
  const [progress, setProgress] = useState3(0);
549
962
  const [command, setCommand] = useState3(initialCommand || "");
550
963
  const [streamedContent, setStreamedContent] = useState3("");
964
+ const [plan, setPlan] = useState3("");
965
+ const [pendingCommand, setPendingCommand] = useState3("");
966
+ const [showPlanDetails, setShowPlanDetails] = useState3(false);
967
+ const [uploadedFiles, setUploadedFiles] = useState3([]);
968
+ const [showSettingsMenu, setShowSettingsMenu] = useState3(false);
969
+ const [internalPlanMode, setInternalPlanMode] = useState3(planMode);
551
970
  const fileInputRef = React.useRef(null);
552
971
  useEffect4(() => {
553
972
  if (autoExecute && state === "idle" && command) {
554
973
  executeCommand();
555
974
  }
556
975
  }, [autoExecute]);
557
- const executeCommand = async () => {
558
- if (!command.trim()) {
976
+ useEffect4(() => {
977
+ setInternalPlanMode(planMode);
978
+ }, [planMode]);
979
+ useEffect4(() => {
980
+ const handleClickOutside = (event) => {
981
+ const target = event.target;
982
+ if (showSettingsMenu && !target.closest(".settings-menu-container")) {
983
+ setShowSettingsMenu(false);
984
+ }
985
+ };
986
+ document.addEventListener("mousedown", handleClickOutside);
987
+ return () => document.removeEventListener("mousedown", handleClickOutside);
988
+ }, [showSettingsMenu]);
989
+ const executeCommand = async (commandOverride) => {
990
+ const currentCommand = commandOverride || command;
991
+ if (!currentCommand.trim()) {
559
992
  setError(new Error("Please enter a command"));
560
993
  setState("error");
561
994
  return;
562
995
  }
563
- const currentCommand = command;
996
+ if (internalPlanMode && state !== "plan-pending") {
997
+ setState("loading");
998
+ setError(null);
999
+ setCommand("");
1000
+ if (useMock) {
1001
+ setTimeout(() => {
1002
+ const mockPlan = generateMockPlan(currentCommand);
1003
+ setPlan(mockPlan);
1004
+ setPendingCommand(currentCommand);
1005
+ setState("plan-pending");
1006
+ }, 800);
1007
+ } else {
1008
+ try {
1009
+ let messageContent;
1010
+ if (uploadedFiles.length > 0) {
1011
+ messageContent = [
1012
+ {
1013
+ type: "text",
1014
+ text: currentCommand
1015
+ },
1016
+ ...uploadedFiles.map((file) => ({
1017
+ type: file.type,
1018
+ source: {
1019
+ type: "base64",
1020
+ media_type: file.mediaType,
1021
+ data: file.data
1022
+ }
1023
+ }))
1024
+ ];
1025
+ } else {
1026
+ messageContent = currentCommand;
1027
+ }
1028
+ let systemMessage = context || "";
1029
+ const planningInstruction = `CRITICAL PLANNING MODE - READ CAREFULLY:
1030
+
1031
+ You are ONLY creating a plan. You are NOT executing anything.
1032
+
1033
+ YOUR TASK: Write a numbered list of steps describing what WOULD be done.
1034
+ DO NOT: Execute any actions, make API calls, access databases, modify data, or perform any operations.
1035
+ DO NOT: Ask questions or clarifications. Make reasonable assumptions.
1036
+ DO: Describe the steps as "Step 1: Would search database...", "Step 2: Would analyze results...", etc.
1037
+ DO: Use default values or best practices if details are missing.
1038
+
1039
+ FORMAT REQUIRED:
1040
+ 1. [First action that would be taken]
1041
+ 2. [Second action that would be taken]
1042
+ 3. [Third action that would be taken]
1043
+ ...
1044
+
1045
+ IMPORTANT: This is COMMAND MODE - figure things out yourself. Make intelligent assumptions based on context. ONLY ask questions if something is absolutely impossible to proceed without (e.g., missing required credentials). Otherwise, use sensible defaults and proceed with the plan.
1046
+
1047
+ REMEMBER: This is ONLY a plan. The user will approve it, THEN it will be executed. Right now you are just describing what would happen - NOT doing it.`;
1048
+ systemMessage = systemMessage ? `${systemMessage}
1049
+
1050
+ ${planningInstruction}` : planningInstruction;
1051
+ aptevaClient.chat({
1052
+ agent_id: agentId,
1053
+ message: messageContent,
1054
+ stream: false,
1055
+ system: systemMessage
1056
+ }).then((response) => {
1057
+ setPlan(response.message);
1058
+ setPendingCommand(currentCommand);
1059
+ setState("plan-pending");
1060
+ }).catch((err) => {
1061
+ const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1062
+ setError(error2);
1063
+ setState("error");
1064
+ onError?.(error2);
1065
+ });
1066
+ } catch (err) {
1067
+ const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
1068
+ setError(error2);
1069
+ setState("error");
1070
+ onError?.(error2);
1071
+ }
1072
+ }
1073
+ return;
1074
+ }
564
1075
  setState("loading");
565
1076
  setError(null);
566
1077
  setProgress(0);
567
1078
  setStreamedContent("");
568
1079
  setCommand("");
1080
+ setUploadedFiles([]);
569
1081
  onStart?.();
570
1082
  try {
571
- if (enableStreaming) {
572
- const mockStreamChunks = [
573
- "Initializing...",
574
- "Connecting to agent...",
575
- "Processing your request...",
576
- "Analyzing data sources...",
577
- "Gathering information...",
578
- "Generating response...",
579
- "Finalizing results..."
580
- ];
581
- for (let i = 0; i < mockStreamChunks.length; i++) {
582
- await new Promise((resolve) => setTimeout(resolve, 600 + Math.random() * 400));
583
- const chunk = mockStreamChunks[i];
584
- setStreamedContent(chunk);
585
- onChunk?.(chunk);
586
- setProgress(Math.round((i + 1) / mockStreamChunks.length * 100));
587
- onProgress?.(Math.round((i + 1) / mockStreamChunks.length * 100));
1083
+ if (useMock) {
1084
+ if (enableStreaming) {
1085
+ let accumulatedContent = "";
1086
+ generateMockCommandStream(
1087
+ currentCommand,
1088
+ (chunk) => {
1089
+ if (chunk.type === "token" && chunk.content) {
1090
+ accumulatedContent += chunk.content;
1091
+ setStreamedContent(accumulatedContent);
1092
+ onChunk?.(chunk.content);
1093
+ const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1094
+ setProgress(estimatedProgress);
1095
+ onProgress?.(estimatedProgress);
1096
+ } else if (chunk.type === "widget" && chunk.widget) {
1097
+ const widget = chunk.widget;
1098
+ setResult((prev) => ({
1099
+ success: true,
1100
+ data: prev?.data || {},
1101
+ widgets: [...prev?.widgets || [], widget],
1102
+ message: accumulatedContent || "Command executed successfully"
1103
+ }));
1104
+ }
1105
+ },
1106
+ (threadId) => {
1107
+ const result2 = {
1108
+ success: true,
1109
+ data: {
1110
+ summary: accumulatedContent,
1111
+ thread_id: threadId,
1112
+ agentId,
1113
+ context,
1114
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1115
+ },
1116
+ message: accumulatedContent || "Command executed successfully"
1117
+ };
1118
+ setResult(result2);
1119
+ setState("success");
1120
+ setProgress(100);
1121
+ onComplete?.(result2);
1122
+ },
1123
+ (error2) => {
1124
+ setError(error2);
1125
+ setState("error");
1126
+ onError?.(error2);
1127
+ }
1128
+ );
1129
+ } else {
1130
+ const progressInterval = setInterval(() => {
1131
+ setProgress((prev) => {
1132
+ const next = Math.min(prev + 10, 90);
1133
+ onProgress?.(next);
1134
+ return next;
1135
+ });
1136
+ }, 200);
1137
+ await new Promise((resolve) => setTimeout(resolve, 1500));
1138
+ clearInterval(progressInterval);
1139
+ const mockResponse = generateMockCommandWithWidgets(currentCommand);
1140
+ const result2 = {
1141
+ success: true,
1142
+ data: {
1143
+ summary: mockResponse.message,
1144
+ thread_id: `mock_thread_${Date.now()}`,
1145
+ agentId,
1146
+ context,
1147
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1148
+ action: mockResponse.action
1149
+ // Include agent action intent
1150
+ },
1151
+ widgets: mockResponse.widgets,
1152
+ message: mockResponse.message
1153
+ };
1154
+ setResult(result2);
1155
+ setState("success");
1156
+ setProgress(100);
1157
+ onComplete?.(result2);
588
1158
  }
589
- const mockResult = {
590
- success: true,
591
- data: {
592
- summary: `Successfully processed: "${currentCommand}"`,
593
- agentId,
594
- context,
595
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
596
- },
597
- message: "Command executed successfully"
598
- };
599
- setResult(mockResult);
600
- setState("success");
601
- setProgress(100);
602
- onComplete?.(mockResult);
603
1159
  } else {
604
- const progressInterval = setInterval(() => {
605
- setProgress((prev) => {
606
- const next = Math.min(prev + 10, 90);
607
- onProgress?.(next);
608
- return next;
1160
+ if (enableStreaming) {
1161
+ let accumulatedContent = "";
1162
+ let messageContent;
1163
+ if (uploadedFiles.length > 0) {
1164
+ messageContent = [
1165
+ {
1166
+ type: "text",
1167
+ text: currentCommand
1168
+ },
1169
+ ...uploadedFiles.map((file) => ({
1170
+ type: file.type,
1171
+ // 'image' or 'document'
1172
+ source: {
1173
+ type: "base64",
1174
+ media_type: file.mediaType,
1175
+ data: file.data
1176
+ }
1177
+ }))
1178
+ ];
1179
+ } else {
1180
+ messageContent = currentCommand;
1181
+ }
1182
+ let systemMessage = context || "";
1183
+ let commandInstruction;
1184
+ if (isCompact) {
1185
+ commandInstruction = 'CRITICAL COMMAND MODE: Maximum 10 words per response. Execute immediately, make intelligent assumptions, use defaults when needed. NO questions unless absolutely critical (missing required credentials). State action or result ONLY. Examples: "Searching database for matching records..." or "Found 3 user records in database" or "Task completed successfully". NO greetings, NO explanations, NO clarification requests. Just execute and report.';
1186
+ } else {
1187
+ 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.`;
1188
+ }
1189
+ systemMessage = systemMessage ? `${systemMessage}
1190
+
1191
+ ${commandInstruction}` : commandInstruction;
1192
+ await aptevaClient.chatStream(
1193
+ {
1194
+ agent_id: agentId,
1195
+ message: messageContent,
1196
+ stream: true,
1197
+ ...systemMessage && { system: systemMessage }
1198
+ },
1199
+ (chunk) => {
1200
+ if (chunk.type === "token" && chunk.content) {
1201
+ accumulatedContent += chunk.content;
1202
+ setStreamedContent(accumulatedContent);
1203
+ onChunk?.(chunk.content);
1204
+ const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
1205
+ setProgress(estimatedProgress);
1206
+ onProgress?.(estimatedProgress);
1207
+ } else if (chunk.type === "widget" && chunk.widget) {
1208
+ const widget = chunk.widget;
1209
+ setResult((prev) => ({
1210
+ success: true,
1211
+ data: prev?.data || {},
1212
+ widgets: [...prev?.widgets || [], widget],
1213
+ message: accumulatedContent || "Command executed successfully"
1214
+ }));
1215
+ }
1216
+ },
1217
+ (threadId) => {
1218
+ const result2 = {
1219
+ success: true,
1220
+ data: {
1221
+ summary: accumulatedContent,
1222
+ thread_id: threadId,
1223
+ agentId,
1224
+ context,
1225
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1226
+ },
1227
+ message: accumulatedContent || "Command executed successfully"
1228
+ };
1229
+ setResult(result2);
1230
+ setState("success");
1231
+ setProgress(100);
1232
+ onComplete?.(result2);
1233
+ },
1234
+ (error2) => {
1235
+ const err = error2 instanceof Error ? error2 : new Error("Unknown error");
1236
+ setError(err);
1237
+ setState("error");
1238
+ onError?.(err);
1239
+ }
1240
+ );
1241
+ } else {
1242
+ const progressInterval = setInterval(() => {
1243
+ setProgress((prev) => {
1244
+ const next = Math.min(prev + 10, 90);
1245
+ onProgress?.(next);
1246
+ return next;
1247
+ });
1248
+ }, 200);
1249
+ let messageContent;
1250
+ if (uploadedFiles.length > 0) {
1251
+ messageContent = [
1252
+ {
1253
+ type: "text",
1254
+ text: currentCommand
1255
+ },
1256
+ ...uploadedFiles.map((file) => ({
1257
+ type: file.type,
1258
+ // 'image' or 'document'
1259
+ source: {
1260
+ type: "base64",
1261
+ media_type: file.mediaType,
1262
+ data: file.data
1263
+ }
1264
+ }))
1265
+ ];
1266
+ } else {
1267
+ messageContent = currentCommand;
1268
+ }
1269
+ let systemMessage = context || "";
1270
+ let commandInstruction;
1271
+ if (isCompact) {
1272
+ commandInstruction = 'CRITICAL COMMAND MODE: Maximum 10 words per response. Execute immediately, make intelligent assumptions, use defaults when needed. NO questions unless absolutely critical (missing required credentials). State action or result ONLY. Examples: "Searching database for matching records..." or "Found 3 user records in database" or "Task completed successfully". NO greetings, NO explanations, NO clarification requests. Just execute and report.';
1273
+ } else {
1274
+ 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.`;
1275
+ }
1276
+ systemMessage = systemMessage ? `${systemMessage}
1277
+
1278
+ ${commandInstruction}` : commandInstruction;
1279
+ const response = await aptevaClient.chat({
1280
+ agent_id: agentId,
1281
+ message: messageContent,
1282
+ stream: false,
1283
+ ...systemMessage && { system: systemMessage }
609
1284
  });
610
- }, 200);
611
- await new Promise((resolve) => setTimeout(resolve, 2e3));
612
- clearInterval(progressInterval);
613
- const mockResult = {
614
- success: true,
615
- data: {
616
- summary: `Command "${currentCommand}" executed successfully`,
617
- agentId,
618
- context,
619
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
620
- },
621
- message: "Execution complete"
622
- };
623
- setResult(mockResult);
624
- setState("success");
625
- setProgress(100);
626
- onComplete?.(mockResult);
1285
+ clearInterval(progressInterval);
1286
+ const result2 = {
1287
+ success: true,
1288
+ data: {
1289
+ summary: response.message,
1290
+ thread_id: response.thread_id,
1291
+ agentId,
1292
+ context,
1293
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1294
+ },
1295
+ widgets: response.widgets,
1296
+ message: response.message
1297
+ };
1298
+ setResult(result2);
1299
+ setState("success");
1300
+ setProgress(100);
1301
+ onComplete?.(result2);
1302
+ }
627
1303
  }
628
1304
  } catch (err) {
629
1305
  const error2 = err instanceof Error ? err : new Error("Unknown error");
@@ -638,12 +1314,69 @@ function Command({
638
1314
  setError(null);
639
1315
  setProgress(0);
640
1316
  setCommand("");
1317
+ setPlan("");
1318
+ setPendingCommand("");
1319
+ setShowPlanDetails(false);
1320
+ setUploadedFiles([]);
641
1321
  };
642
- const handleFileSelect = (e) => {
1322
+ const approvePlan = () => {
1323
+ setShowPlanDetails(false);
1324
+ const planToExecute = plan;
1325
+ setPlan("");
1326
+ setPendingCommand("");
1327
+ const executionMessage = `Execute this plan now:
1328
+
1329
+ ${planToExecute}`;
1330
+ executeCommand(executionMessage);
1331
+ };
1332
+ const rejectPlan = () => {
1333
+ setCommand(pendingCommand);
1334
+ setPlan("");
1335
+ setPendingCommand("");
1336
+ setShowPlanDetails(false);
1337
+ setState("idle");
1338
+ };
1339
+ const handleFileSelect = async (e) => {
643
1340
  if (e.target.files && e.target.files.length > 0) {
644
1341
  onFileUpload?.(e.target.files);
1342
+ const files = [];
1343
+ for (let i = 0; i < e.target.files.length; i++) {
1344
+ const file = e.target.files[i];
1345
+ const reader = new FileReader();
1346
+ await new Promise((resolve) => {
1347
+ reader.onload = (event) => {
1348
+ if (event.target?.result) {
1349
+ const fullDataUrl = event.target.result;
1350
+ const base64Data = fullDataUrl.split(",")[1];
1351
+ if (file.type.startsWith("image/")) {
1352
+ files.push({
1353
+ type: "image",
1354
+ data: base64Data,
1355
+ mediaType: file.type,
1356
+ preview: fullDataUrl,
1357
+ // Keep full data URL for preview
1358
+ name: file.name
1359
+ });
1360
+ } else if (file.type === "application/pdf" || file.type.startsWith("application/")) {
1361
+ files.push({
1362
+ type: "document",
1363
+ data: base64Data,
1364
+ mediaType: file.type,
1365
+ name: file.name
1366
+ });
1367
+ }
1368
+ }
1369
+ resolve();
1370
+ };
1371
+ reader.readAsDataURL(file);
1372
+ });
1373
+ }
1374
+ setUploadedFiles((prev) => [...prev, ...files]);
645
1375
  }
646
1376
  };
1377
+ const removeFile = (index) => {
1378
+ setUploadedFiles((prev) => prev.filter((_, i) => i !== index));
1379
+ };
647
1380
  const isCompact = variant === "compact";
648
1381
  return /* @__PURE__ */ jsxs8(
649
1382
  "div",
@@ -653,6 +1386,7 @@ function Command({
653
1386
  state === "loading" && "animate-pulse-border",
654
1387
  state === "idle" && "border-gray-300 dark:border-gray-700",
655
1388
  state === "loading" && "border-blue-500",
1389
+ state === "plan-pending" && "border-blue-400",
656
1390
  state === "success" && "border-green-500",
657
1391
  state === "error" && "border-red-500",
658
1392
  className
@@ -660,32 +1394,133 @@ function Command({
660
1394
  style: { minHeight: isCompact ? "auto" : "180px" },
661
1395
  children: [
662
1396
  /* @__PURE__ */ jsxs8("div", { className: cn("flex-1 flex", isCompact ? "flex-row items-center p-3 gap-3" : "flex-col p-4"), children: [
663
- state === "idle" && allowInput && !isCompact && /* @__PURE__ */ jsx10(
664
- "textarea",
665
- {
666
- value: command,
667
- onChange: (e) => setCommand(e.target.value),
668
- onKeyDown: (e) => {
669
- if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
670
- e.preventDefault();
671
- executeCommand();
672
- }
673
- },
674
- placeholder,
675
- className: "flex-1 w-full resize-none bg-transparent border-none focus:outline-none !text-gray-900 dark:!text-gray-100 placeholder-gray-400 dark:placeholder-gray-500",
676
- rows: 6
677
- }
678
- ),
679
- state === "idle" && allowInput && isCompact && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1397
+ state === "idle" && allowInput && !isCompact && /* @__PURE__ */ jsxs8(Fragment2, { children: [
680
1398
  /* @__PURE__ */ jsx10(
681
- "button",
1399
+ "textarea",
682
1400
  {
683
- onClick: () => fileInputRef.current?.click(),
684
- 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",
685
- title: "Attach file",
686
- children: /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx10("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)" }) })
1401
+ value: command,
1402
+ onChange: (e) => setCommand(e.target.value),
1403
+ onKeyDown: (e) => {
1404
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
1405
+ e.preventDefault();
1406
+ executeCommand();
1407
+ }
1408
+ },
1409
+ placeholder,
1410
+ className: "flex-1 w-full resize-none bg-transparent border-none focus:outline-none !text-gray-900 dark:!text-gray-100 placeholder-gray-400 dark:placeholder-gray-500",
1411
+ rows: 6
687
1412
  }
688
1413
  ),
1414
+ uploadedFiles.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex flex-wrap gap-2 mt-2", children: uploadedFiles.map((file, index) => /* @__PURE__ */ jsxs8("div", { className: "relative group", children: [
1415
+ file.type === "image" ? /* @__PURE__ */ jsx10(
1416
+ "img",
1417
+ {
1418
+ src: file.preview,
1419
+ alt: file.name,
1420
+ className: "w-20 h-20 object-cover rounded-lg border-2 border-gray-300 dark:border-gray-600"
1421
+ }
1422
+ ) : /* @__PURE__ */ jsxs8("div", { className: "w-20 h-20 flex flex-col items-center justify-center rounded-lg border-2 border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800", children: [
1423
+ /* @__PURE__ */ jsx10("svg", { className: "w-8 h-8 text-gray-500 dark:text-gray-400", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx10("path", { fillRule: "evenodd", d: "M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z", clipRule: "evenodd" }) }),
1424
+ /* @__PURE__ */ jsx10("span", { className: "text-[8px] text-gray-500 dark:text-gray-400 mt-1 px-1 truncate max-w-full", children: file.name.length > 12 ? file.name.slice(0, 12) + "..." : file.name })
1425
+ ] }),
1426
+ /* @__PURE__ */ jsx10(
1427
+ "button",
1428
+ {
1429
+ onClick: () => removeFile(index),
1430
+ className: "absolute -top-2 -right-2 w-6 h-6 bg-red-500 hover:bg-red-600 text-white rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity",
1431
+ title: `Remove ${file.type}`,
1432
+ children: /* @__PURE__ */ jsx10("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1433
+ }
1434
+ )
1435
+ ] }, index)) })
1436
+ ] }),
1437
+ state === "idle" && allowInput && isCompact && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1438
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-0.5 flex-shrink-0", children: [
1439
+ enableFileUpload && /* @__PURE__ */ jsx10(
1440
+ "button",
1441
+ {
1442
+ onClick: () => fileInputRef.current?.click(),
1443
+ 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
+ title: "Attach file",
1445
+ children: /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx10("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)" }) })
1446
+ }
1447
+ ),
1448
+ planMode && /* @__PURE__ */ jsxs8("div", { className: "relative settings-menu-container", children: [
1449
+ /* @__PURE__ */ jsx10(
1450
+ "button",
1451
+ {
1452
+ onClick: () => setShowSettingsMenu(!showSettingsMenu),
1453
+ className: cn(
1454
+ "w-8 h-8 rounded-lg flex items-center justify-center transition-all flex-shrink-0 hover:bg-gray-100 dark:hover:bg-gray-800",
1455
+ internalPlanMode ? "!text-blue-600 dark:!text-blue-400" : "!text-gray-500 dark:!text-gray-500"
1456
+ ),
1457
+ title: "Settings",
1458
+ children: /* @__PURE__ */ jsxs8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1459
+ /* @__PURE__ */ jsx10("line", { x1: "4", y1: "21", x2: "4", y2: "14" }),
1460
+ /* @__PURE__ */ jsx10("line", { x1: "4", y1: "10", x2: "4", y2: "3" }),
1461
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "21", x2: "12", y2: "12" }),
1462
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "8", x2: "12", y2: "3" }),
1463
+ /* @__PURE__ */ jsx10("line", { x1: "20", y1: "21", x2: "20", y2: "16" }),
1464
+ /* @__PURE__ */ jsx10("line", { x1: "20", y1: "12", x2: "20", y2: "3" }),
1465
+ /* @__PURE__ */ jsx10("line", { x1: "1", y1: "14", x2: "7", y2: "14" }),
1466
+ /* @__PURE__ */ jsx10("line", { x1: "9", y1: "8", x2: "15", y2: "8" }),
1467
+ /* @__PURE__ */ jsx10("line", { x1: "17", y1: "16", x2: "23", y2: "16" })
1468
+ ] })
1469
+ }
1470
+ ),
1471
+ showSettingsMenu && /* @__PURE__ */ jsx10("div", { className: "absolute top-10 left-0 z-50 w-56 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg p-2.5 settings-menu-container", children: /* @__PURE__ */ jsxs8("label", { className: "flex items-center justify-between cursor-pointer group", children: [
1472
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1473
+ /* @__PURE__ */ jsx10("svg", { className: "w-3.5 h-3.5 text-gray-500 dark:text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" }) }),
1474
+ /* @__PURE__ */ jsxs8("div", { children: [
1475
+ /* @__PURE__ */ jsx10("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300", children: "Plan Mode" }),
1476
+ /* @__PURE__ */ jsx10("div", { className: "text-[10px] text-gray-500 dark:text-gray-400", children: "Review first" })
1477
+ ] })
1478
+ ] }),
1479
+ /* @__PURE__ */ jsx10(
1480
+ "button",
1481
+ {
1482
+ onClick: (e) => {
1483
+ e.stopPropagation();
1484
+ setInternalPlanMode(!internalPlanMode);
1485
+ },
1486
+ className: cn(
1487
+ "relative inline-flex h-4 w-8 items-center rounded-full transition-colors",
1488
+ internalPlanMode ? "bg-blue-600" : "bg-gray-300 dark:bg-gray-600"
1489
+ ),
1490
+ type: "button",
1491
+ children: /* @__PURE__ */ jsx10(
1492
+ "span",
1493
+ {
1494
+ className: cn(
1495
+ "inline-block h-3 w-3 transform rounded-full bg-white transition-transform",
1496
+ internalPlanMode ? "translate-x-4.5" : "translate-x-0.5"
1497
+ )
1498
+ }
1499
+ )
1500
+ }
1501
+ )
1502
+ ] }) })
1503
+ ] })
1504
+ ] }),
1505
+ uploadedFiles.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex gap-1 flex-shrink-0", children: uploadedFiles.map((file, index) => /* @__PURE__ */ jsxs8("div", { className: "relative group", children: [
1506
+ file.type === "image" ? /* @__PURE__ */ jsx10(
1507
+ "img",
1508
+ {
1509
+ src: file.preview,
1510
+ alt: file.name,
1511
+ className: "w-8 h-8 object-cover rounded border border-gray-300 dark:border-gray-600"
1512
+ }
1513
+ ) : /* @__PURE__ */ jsx10("div", { className: "w-8 h-8 flex items-center justify-center rounded border border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800", title: file.name, children: /* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-gray-500 dark:text-gray-400", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx10("path", { fillRule: "evenodd", d: "M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z", clipRule: "evenodd" }) }) }),
1514
+ /* @__PURE__ */ jsx10(
1515
+ "button",
1516
+ {
1517
+ onClick: () => removeFile(index),
1518
+ className: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 hover:bg-red-600 text-white rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity",
1519
+ title: "Remove",
1520
+ children: /* @__PURE__ */ jsx10("svg", { className: "w-2.5 h-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
1521
+ }
1522
+ )
1523
+ ] }, index)) }),
689
1524
  /* @__PURE__ */ jsx10(
690
1525
  "input",
691
1526
  {
@@ -705,7 +1540,7 @@ function Command({
705
1540
  /* @__PURE__ */ jsx10(
706
1541
  "button",
707
1542
  {
708
- onClick: executeCommand,
1543
+ onClick: () => executeCommand(),
709
1544
  disabled: !command.trim(),
710
1545
  className: cn(
711
1546
  "w-8 h-8 rounded-lg flex items-center justify-center font-bold transition-all flex-shrink-0",
@@ -760,6 +1595,64 @@ function Command({
760
1595
  }
761
1596
  )
762
1597
  ] }),
1598
+ state === "plan-pending" && !isCompact && /* @__PURE__ */ jsx10("div", { className: "flex-1 flex flex-col", children: /* @__PURE__ */ jsxs8("div", { className: "mb-4 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg", children: [
1599
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-2 mb-3", children: [
1600
+ /* @__PURE__ */ jsx10("svg", { className: "w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" }) }),
1601
+ /* @__PURE__ */ jsxs8("div", { className: "flex-1", children: [
1602
+ /* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-blue-800 dark:text-blue-300 mb-1", children: "Proposed Plan" }),
1603
+ /* @__PURE__ */ jsx10("div", { className: "text-blue-700 dark:text-blue-300 text-sm whitespace-pre-line leading-relaxed", children: plan })
1604
+ ] })
1605
+ ] }),
1606
+ /* @__PURE__ */ jsxs8("div", { className: "flex gap-2 mt-4", children: [
1607
+ /* @__PURE__ */ jsx10(
1608
+ "button",
1609
+ {
1610
+ onClick: approvePlan,
1611
+ className: "flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium",
1612
+ children: "Approve & Execute"
1613
+ }
1614
+ ),
1615
+ /* @__PURE__ */ jsx10(
1616
+ "button",
1617
+ {
1618
+ onClick: rejectPlan,
1619
+ className: "flex-1 px-4 py-2 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-sm font-medium",
1620
+ children: "Modify"
1621
+ }
1622
+ )
1623
+ ] })
1624
+ ] }) }),
1625
+ state === "plan-pending" && isCompact && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1626
+ /* @__PURE__ */ jsxs8(
1627
+ "button",
1628
+ {
1629
+ onClick: () => setShowPlanDetails(true),
1630
+ className: "flex-1 flex items-center gap-2 px-3 py-2 bg-blue-50 dark:bg-blue-900/30 hover:bg-blue-100 dark:hover:bg-blue-900/40 border border-blue-200 dark:border-blue-800 rounded-lg transition-colors",
1631
+ children: [
1632
+ /* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-blue-600 dark:text-blue-400 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" }) }),
1633
+ /* @__PURE__ */ jsx10("span", { className: "text-sm font-medium text-blue-700 dark:text-blue-300 truncate flex-1", children: "View Execution Plan" })
1634
+ ]
1635
+ }
1636
+ ),
1637
+ /* @__PURE__ */ jsxs8("div", { className: "flex gap-2 flex-shrink-0", children: [
1638
+ /* @__PURE__ */ jsx10(
1639
+ "button",
1640
+ {
1641
+ onClick: approvePlan,
1642
+ className: "px-3 py-1.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-xs font-medium",
1643
+ children: "Approve"
1644
+ }
1645
+ ),
1646
+ /* @__PURE__ */ jsx10(
1647
+ "button",
1648
+ {
1649
+ onClick: rejectPlan,
1650
+ className: "px-3 py-1.5 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",
1651
+ children: "Modify"
1652
+ }
1653
+ )
1654
+ ] })
1655
+ ] }),
763
1656
  state === "error" && /* @__PURE__ */ jsxs8("div", { className: "flex-1 flex flex-col", children: [
764
1657
  /* @__PURE__ */ jsx10("div", { className: "mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-2", children: [
765
1658
  /* @__PURE__ */ jsx10("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__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
@@ -785,28 +1678,36 @@ function Command({
785
1678
  }
786
1679
  )
787
1680
  ] }),
788
- state === "success" && result && !isCompact && /* @__PURE__ */ jsx10("div", { className: "flex-1 overflow-auto", children: resultRenderer ? resultRenderer(result.data) : /* @__PURE__ */ jsxs8("div", { children: [
789
- /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-3 mb-3 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg", children: [
1681
+ state === "success" && result && !isCompact && /* @__PURE__ */ jsx10("div", { className: "flex-1 overflow-auto", children: resultRenderer ? resultRenderer(result.data) : /* @__PURE__ */ jsxs8("div", { className: "space-y-4", children: [
1682
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-3 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg", children: [
790
1683
  /* @__PURE__ */ jsx10("svg", { className: "w-5 h-5 text-green-600 mt-0.5 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
791
1684
  /* @__PURE__ */ jsxs8("div", { className: "flex-1", children: [
792
1685
  /* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-green-800 dark:text-green-400 mb-1", children: "Success" }),
793
- /* @__PURE__ */ jsx10("p", { className: "text-green-700 dark:text-green-300 text-sm", children: result.message || "Command executed successfully" })
1686
+ /* @__PURE__ */ jsx10("p", { className: "text-green-700 dark:text-green-300 text-sm", children: "Command executed successfully" })
794
1687
  ] })
795
1688
  ] }),
796
- result.data?.summary && /* @__PURE__ */ jsx10("div", { className: "text-gray-700 dark:text-gray-300 text-sm leading-relaxed", children: result.data.summary })
1689
+ result.data?.summary && /* @__PURE__ */ jsx10("div", { className: "text-gray-700 dark:text-gray-300 text-sm leading-relaxed whitespace-pre-line", children: result.data.summary }),
1690
+ result.widgets && result.widgets.length > 0 && /* @__PURE__ */ jsx10("div", { className: "space-y-3", children: result.widgets.map((widget) => /* @__PURE__ */ jsx10(
1691
+ WidgetRenderer,
1692
+ {
1693
+ widget,
1694
+ onAction
1695
+ },
1696
+ widget.id
1697
+ )) })
797
1698
  ] }) }),
798
1699
  state === "success" && result && isCompact && /* @__PURE__ */ jsxs8(Fragment2, { children: [
799
1700
  /* @__PURE__ */ jsxs8(
800
1701
  "div",
801
1702
  {
802
- className: "flex-1 flex items-center gap-2 py-1 cursor-text",
1703
+ className: "flex-1 flex items-center gap-2 py-1 cursor-text min-w-0",
803
1704
  onClick: () => {
804
1705
  setState("idle");
805
1706
  setResult(null);
806
1707
  },
807
1708
  children: [
808
1709
  /* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-green-600 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
809
- /* @__PURE__ */ jsx10("div", { className: "text-green-700 dark:text-green-300 text-sm truncate", children: resultRenderer ? resultRenderer(result.data) : result.message || "Command executed successfully" })
1710
+ /* @__PURE__ */ jsx10("div", { className: "text-green-700 dark:text-green-300 text-sm truncate flex-1 min-w-0", children: resultRenderer ? resultRenderer(result.data) : result.message || "Command executed successfully" })
810
1711
  ]
811
1712
  }
812
1713
  ),
@@ -832,15 +1733,73 @@ function Command({
832
1733
  ] })
833
1734
  ] }),
834
1735
  !isCompact && /* @__PURE__ */ jsxs8("div", { className: "p-3 flex items-center justify-between gap-2", children: [
835
- state === "idle" && allowInput && /* @__PURE__ */ jsx10(
836
- "button",
837
- {
838
- onClick: () => fileInputRef.current?.click(),
839
- 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",
840
- title: "Attach file",
841
- children: /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx10("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)" }) })
842
- }
843
- ),
1736
+ /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-1", children: state === "idle" && allowInput && /* @__PURE__ */ jsxs8(Fragment2, { children: [
1737
+ enableFileUpload && /* @__PURE__ */ jsx10(
1738
+ "button",
1739
+ {
1740
+ onClick: () => fileInputRef.current?.click(),
1741
+ 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
+ title: "Attach file",
1743
+ children: /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx10("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)" }) })
1744
+ }
1745
+ ),
1746
+ planMode && /* @__PURE__ */ jsxs8("div", { className: "relative settings-menu-container", children: [
1747
+ /* @__PURE__ */ jsx10(
1748
+ "button",
1749
+ {
1750
+ onClick: () => setShowSettingsMenu(!showSettingsMenu),
1751
+ className: cn(
1752
+ "w-8 h-8 rounded-lg flex items-center justify-center transition-all flex-shrink-0 hover:bg-gray-100 dark:hover:bg-gray-800",
1753
+ internalPlanMode ? "!text-blue-600 dark:!text-blue-400" : "!text-gray-500 dark:!text-gray-500"
1754
+ ),
1755
+ title: "Settings",
1756
+ children: /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1757
+ /* @__PURE__ */ jsx10("line", { x1: "4", y1: "21", x2: "4", y2: "14" }),
1758
+ /* @__PURE__ */ jsx10("line", { x1: "4", y1: "10", x2: "4", y2: "3" }),
1759
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "21", x2: "12", y2: "12" }),
1760
+ /* @__PURE__ */ jsx10("line", { x1: "12", y1: "8", x2: "12", y2: "3" }),
1761
+ /* @__PURE__ */ jsx10("line", { x1: "20", y1: "21", x2: "20", y2: "16" }),
1762
+ /* @__PURE__ */ jsx10("line", { x1: "20", y1: "12", x2: "20", y2: "3" }),
1763
+ /* @__PURE__ */ jsx10("line", { x1: "1", y1: "14", x2: "7", y2: "14" }),
1764
+ /* @__PURE__ */ jsx10("line", { x1: "9", y1: "8", x2: "15", y2: "8" }),
1765
+ /* @__PURE__ */ jsx10("line", { x1: "17", y1: "16", x2: "23", y2: "16" })
1766
+ ] })
1767
+ }
1768
+ ),
1769
+ showSettingsMenu && /* @__PURE__ */ jsx10("div", { className: "absolute top-10 left-0 z-50 w-64 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg p-3 settings-menu-container", children: /* @__PURE__ */ jsxs8("label", { className: "flex items-center justify-between cursor-pointer group", children: [
1770
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1771
+ /* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-gray-500 dark:text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" }) }),
1772
+ /* @__PURE__ */ jsxs8("div", { children: [
1773
+ /* @__PURE__ */ jsx10("div", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "Plan Mode" }),
1774
+ /* @__PURE__ */ jsx10("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Review before executing" })
1775
+ ] })
1776
+ ] }),
1777
+ /* @__PURE__ */ jsx10(
1778
+ "button",
1779
+ {
1780
+ onClick: (e) => {
1781
+ e.stopPropagation();
1782
+ setInternalPlanMode(!internalPlanMode);
1783
+ },
1784
+ className: cn(
1785
+ "relative inline-flex h-5 w-9 items-center rounded-full transition-colors",
1786
+ internalPlanMode ? "bg-blue-600" : "bg-gray-300 dark:bg-gray-600"
1787
+ ),
1788
+ type: "button",
1789
+ children: /* @__PURE__ */ jsx10(
1790
+ "span",
1791
+ {
1792
+ className: cn(
1793
+ "inline-block h-3.5 w-3.5 transform rounded-full bg-white transition-transform",
1794
+ internalPlanMode ? "translate-x-5" : "translate-x-0.5"
1795
+ )
1796
+ }
1797
+ )
1798
+ }
1799
+ )
1800
+ ] }) })
1801
+ ] })
1802
+ ] }) }),
844
1803
  !(state === "idle" && allowInput) && /* @__PURE__ */ jsx10("div", {}),
845
1804
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
846
1805
  (state === "success" || state === "error") && allowInput && /* @__PURE__ */ jsx10(
@@ -854,7 +1813,7 @@ function Command({
854
1813
  (state === "idle" || state === "error") && /* @__PURE__ */ jsx10(
855
1814
  "button",
856
1815
  {
857
- onClick: executeCommand,
1816
+ onClick: () => executeCommand(),
858
1817
  disabled: !command.trim(),
859
1818
  className: cn(
860
1819
  "w-8 h-8 rounded-lg flex items-center justify-center font-bold transition-all",
@@ -872,6 +1831,41 @@ function Command({
872
1831
  )
873
1832
  ] })
874
1833
  ] }),
1834
+ showPlanDetails && isCompact && state === "plan-pending" && /* @__PURE__ */ jsx10("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4", onClick: () => setShowPlanDetails(false), children: /* @__PURE__ */ jsxs8("div", { className: "bg-white dark:bg-gray-900 rounded-2xl shadow-2xl max-w-2xl w-full max-h-[80vh] overflow-hidden", onClick: (e) => e.stopPropagation(), children: [
1835
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700", children: [
1836
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
1837
+ /* @__PURE__ */ jsx10("svg", { className: "w-6 h-6 text-blue-600 dark:text-blue-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" }) }),
1838
+ /* @__PURE__ */ jsx10("h2", { className: "text-xl font-semibold text-gray-900 dark:text-white", children: "Proposed Execution Plan" })
1839
+ ] }),
1840
+ /* @__PURE__ */ jsx10(
1841
+ "button",
1842
+ {
1843
+ onClick: () => setShowPlanDetails(false),
1844
+ className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors",
1845
+ children: /* @__PURE__ */ jsx10("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1846
+ }
1847
+ )
1848
+ ] }),
1849
+ /* @__PURE__ */ jsx10("div", { className: "p-6 overflow-y-auto max-h-[calc(80vh-180px)]", children: /* @__PURE__ */ jsx10("div", { className: "prose prose-sm dark:prose-invert max-w-none", children: /* @__PURE__ */ jsx10("div", { className: "text-gray-700 dark:text-gray-300 whitespace-pre-line leading-relaxed", children: plan }) }) }),
1850
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-end gap-3 p-6 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50", children: [
1851
+ /* @__PURE__ */ jsx10(
1852
+ "button",
1853
+ {
1854
+ onClick: rejectPlan,
1855
+ className: "px-6 py-2.5 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 font-medium",
1856
+ children: "Modify Command"
1857
+ }
1858
+ ),
1859
+ /* @__PURE__ */ jsx10(
1860
+ "button",
1861
+ {
1862
+ onClick: approvePlan,
1863
+ className: "px-6 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium",
1864
+ children: "Approve & Execute"
1865
+ }
1866
+ )
1867
+ ] })
1868
+ ] }) }),
875
1869
  /* @__PURE__ */ jsx10(
876
1870
  "input",
877
1871
  {
@@ -910,6 +1904,7 @@ function Prompt({
910
1904
  agentId,
911
1905
  placeholder = "Enter your prompt...",
912
1906
  initialValue = "",
1907
+ useMock = true,
913
1908
  submitOn = "button",
914
1909
  debounceMs = 0,
915
1910
  minLength = 0,
@@ -936,10 +1931,19 @@ function Prompt({
936
1931
  onSubmit?.(value);
937
1932
  setIsLoading(true);
938
1933
  try {
939
- await new Promise((resolve) => setTimeout(resolve, 1500));
940
- const mockResult = `Enhanced version: ${value} [AI-generated content]`;
941
- onResult?.(mockResult);
942
- setValue("");
1934
+ if (useMock) {
1935
+ await new Promise((resolve) => setTimeout(resolve, 1500));
1936
+ const mockResult = `Enhanced version: ${value} [AI-generated content]`;
1937
+ onResult?.(mockResult);
1938
+ setValue("");
1939
+ } else {
1940
+ const response = await aptevaClient.chat({
1941
+ agent_id: agentId,
1942
+ message: value
1943
+ });
1944
+ onResult?.(response.message);
1945
+ setValue("");
1946
+ }
943
1947
  } catch (error) {
944
1948
  console.error("Error processing prompt:", error);
945
1949
  } finally {
@@ -1012,6 +2016,7 @@ function Stream({
1012
2016
  prompt,
1013
2017
  context,
1014
2018
  autoStart = false,
2019
+ useMock = true,
1015
2020
  onStart,
1016
2021
  onChunk,
1017
2022
  onComplete,
@@ -1032,19 +2037,47 @@ function Stream({
1032
2037
  const startStreaming = async () => {
1033
2038
  setIsStreaming(true);
1034
2039
  onStart?.();
1035
- 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.";
1036
2040
  try {
1037
- await generateMockStreamingResponse(
1038
- mockText,
1039
- (chunk) => {
1040
- setText((prev) => prev + chunk);
1041
- onChunk?.(chunk);
1042
- },
1043
- typingSpeed
1044
- );
1045
- setIsComplete(true);
1046
- setIsStreaming(false);
1047
- onComplete?.(text + mockText);
2041
+ if (useMock) {
2042
+ 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.";
2043
+ await generateMockStreamingResponse(
2044
+ mockText,
2045
+ (chunk) => {
2046
+ setText((prev) => prev + chunk);
2047
+ onChunk?.(chunk);
2048
+ },
2049
+ typingSpeed
2050
+ );
2051
+ setIsComplete(true);
2052
+ setIsStreaming(false);
2053
+ onComplete?.(text + mockText);
2054
+ } else {
2055
+ let accumulatedText = "";
2056
+ await aptevaClient.chatStream(
2057
+ {
2058
+ agent_id: agentId,
2059
+ message: prompt,
2060
+ stream: true
2061
+ },
2062
+ (chunk) => {
2063
+ if (chunk.type === "token" && chunk.content) {
2064
+ accumulatedText += chunk.content;
2065
+ setText(accumulatedText);
2066
+ onChunk?.(chunk.content);
2067
+ }
2068
+ },
2069
+ () => {
2070
+ setIsComplete(true);
2071
+ setIsStreaming(false);
2072
+ onComplete?.(accumulatedText);
2073
+ },
2074
+ (error) => {
2075
+ const err = error instanceof Error ? error : new Error("Streaming error");
2076
+ onError?.(err);
2077
+ setIsStreaming(false);
2078
+ }
2079
+ );
2080
+ }
1048
2081
  } catch (error) {
1049
2082
  const err = error instanceof Error ? error : new Error("Streaming error");
1050
2083
  onError?.(err);
@@ -1290,6 +2323,7 @@ function getThemeScript() {
1290
2323
  return themeScript;
1291
2324
  }
1292
2325
  export {
2326
+ AptevaClient,
1293
2327
  Button,
1294
2328
  Card,
1295
2329
  Chat,
@@ -1299,6 +2333,7 @@ export {
1299
2333
  Stream,
1300
2334
  Threads,
1301
2335
  Widgets,
2336
+ aptevaClient,
1302
2337
  cn,
1303
2338
  getThemeScript,
1304
2339
  mockMessages,