@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.d.mts +80 -6
- package/dist/index.d.ts +80 -6
- package/dist/index.js +1169 -134
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1148 -113
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
-
|
|
558
|
-
|
|
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
|
-
|
|
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 (
|
|
572
|
-
|
|
573
|
-
"
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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
|
|
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__ */
|
|
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
|
-
"
|
|
1399
|
+
"textarea",
|
|
682
1400
|
{
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
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
|
|
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:
|
|
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__ */
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
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
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
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
|
-
|
|
1038
|
-
mockText,
|
|
1039
|
-
(
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
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,
|