@apteva/apteva-kit 0.1.32 → 0.1.34
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 +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +91 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
import { ClassValue } from 'clsx';
|
|
3
4
|
|
|
@@ -248,6 +249,7 @@ interface ChatProps {
|
|
|
248
249
|
onFileUpload?: (files: FileList) => void;
|
|
249
250
|
onComplete?: (result: CommandResult) => void;
|
|
250
251
|
onError?: (error: Error) => void;
|
|
252
|
+
onToolCall?: (toolName: string, toolId: string) => void;
|
|
251
253
|
onToolResult?: (toolName: string, result?: any) => void;
|
|
252
254
|
theme?: 'light' | 'dark' | 'auto';
|
|
253
255
|
placeholder?: string;
|
|
@@ -363,7 +365,17 @@ interface UseAptevaKitReturn {
|
|
|
363
365
|
error: Error | null;
|
|
364
366
|
}
|
|
365
367
|
|
|
366
|
-
|
|
368
|
+
interface ChatHandle {
|
|
369
|
+
/** Send a message programmatically (as if the user typed it) */
|
|
370
|
+
sendMessage: (text: string) => Promise<void>;
|
|
371
|
+
/** Send a system/background message (not shown as user message, just triggers agent) */
|
|
372
|
+
sendSystemMessage: (text: string) => Promise<void>;
|
|
373
|
+
/** Get current messages */
|
|
374
|
+
getMessages: () => Message[];
|
|
375
|
+
/** Clear all messages */
|
|
376
|
+
clearMessages: () => void;
|
|
377
|
+
}
|
|
378
|
+
declare const Chat: react.ForwardRefExoticComponent<ChatProps & react.RefAttributes<ChatHandle>>;
|
|
367
379
|
|
|
368
380
|
declare function Command({ agentId, command: initialCommand, context, autoExecute, allowInput, placeholder, submitButtonText, variant, useMock, planMode, onPlanModeChange, enableFileUpload, onStart, onProgress, onChunk, onComplete, onError, onFileUpload, onAction, loadingText, showProgress, enableStreaming, resultRenderer, className, }: CommandProps): react_jsx_runtime.JSX.Element;
|
|
369
381
|
|
|
@@ -474,4 +486,4 @@ declare const mockMessages: Message[];
|
|
|
474
486
|
declare const mockThreads: Thread[];
|
|
475
487
|
declare const mockWidgets: Widget[];
|
|
476
488
|
|
|
477
|
-
export { type Action, type ActionEvent, AptevaClient, type AptevaClientConfig, type AptevaKitControl, Button, type ButtonGroupWidget, type ButtonWidget, Card, type CardWidget, type ChartWidget, Chat, type ChatMessage, type ChatProps, type ChatRequest, type ChatResponse, Command, type CommandProps, type CommandResult, type FormField, type FormWidget, type GalleryWidget, type ImageWidget, List, type ListItem, type ListWidget, type MapWidget, type Message, Prompt, type PromptProps, type SendMessageParams, Stream, type StreamChunk, type StreamProps, type SuggestedPrompt, type TableColumn, type TableWidget, type Thread, Threads, type ThreadsProps, type UseAptevaKitReturn, type Widget, Widgets, type WidgetsProps, aptevaClient, cn, getThemeScript, mockMessages, mockThreads, mockWidgets };
|
|
489
|
+
export { type Action, type ActionEvent, AptevaClient, type AptevaClientConfig, type AptevaKitControl, Button, type ButtonGroupWidget, type ButtonWidget, Card, type CardWidget, type ChartWidget, Chat, type ChatHandle, type ChatMessage, type ChatProps, type ChatRequest, type ChatResponse, Command, type CommandProps, type CommandResult, type FormField, type FormWidget, type GalleryWidget, type ImageWidget, List, type ListItem, type ListWidget, type MapWidget, type Message, Prompt, type PromptProps, type SendMessageParams, Stream, type StreamChunk, type StreamProps, type SuggestedPrompt, type TableColumn, type TableWidget, type Thread, Threads, type ThreadsProps, type UseAptevaKitReturn, type Widget, Widgets, type WidgetsProps, aptevaClient, cn, getThemeScript, mockMessages, mockThreads, mockWidgets };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
3
|
import { ClassValue } from 'clsx';
|
|
3
4
|
|
|
@@ -248,6 +249,7 @@ interface ChatProps {
|
|
|
248
249
|
onFileUpload?: (files: FileList) => void;
|
|
249
250
|
onComplete?: (result: CommandResult) => void;
|
|
250
251
|
onError?: (error: Error) => void;
|
|
252
|
+
onToolCall?: (toolName: string, toolId: string) => void;
|
|
251
253
|
onToolResult?: (toolName: string, result?: any) => void;
|
|
252
254
|
theme?: 'light' | 'dark' | 'auto';
|
|
253
255
|
placeholder?: string;
|
|
@@ -363,7 +365,17 @@ interface UseAptevaKitReturn {
|
|
|
363
365
|
error: Error | null;
|
|
364
366
|
}
|
|
365
367
|
|
|
366
|
-
|
|
368
|
+
interface ChatHandle {
|
|
369
|
+
/** Send a message programmatically (as if the user typed it) */
|
|
370
|
+
sendMessage: (text: string) => Promise<void>;
|
|
371
|
+
/** Send a system/background message (not shown as user message, just triggers agent) */
|
|
372
|
+
sendSystemMessage: (text: string) => Promise<void>;
|
|
373
|
+
/** Get current messages */
|
|
374
|
+
getMessages: () => Message[];
|
|
375
|
+
/** Clear all messages */
|
|
376
|
+
clearMessages: () => void;
|
|
377
|
+
}
|
|
378
|
+
declare const Chat: react.ForwardRefExoticComponent<ChatProps & react.RefAttributes<ChatHandle>>;
|
|
367
379
|
|
|
368
380
|
declare function Command({ agentId, command: initialCommand, context, autoExecute, allowInput, placeholder, submitButtonText, variant, useMock, planMode, onPlanModeChange, enableFileUpload, onStart, onProgress, onChunk, onComplete, onError, onFileUpload, onAction, loadingText, showProgress, enableStreaming, resultRenderer, className, }: CommandProps): react_jsx_runtime.JSX.Element;
|
|
369
381
|
|
|
@@ -474,4 +486,4 @@ declare const mockMessages: Message[];
|
|
|
474
486
|
declare const mockThreads: Thread[];
|
|
475
487
|
declare const mockWidgets: Widget[];
|
|
476
488
|
|
|
477
|
-
export { type Action, type ActionEvent, AptevaClient, type AptevaClientConfig, type AptevaKitControl, Button, type ButtonGroupWidget, type ButtonWidget, Card, type CardWidget, type ChartWidget, Chat, type ChatMessage, type ChatProps, type ChatRequest, type ChatResponse, Command, type CommandProps, type CommandResult, type FormField, type FormWidget, type GalleryWidget, type ImageWidget, List, type ListItem, type ListWidget, type MapWidget, type Message, Prompt, type PromptProps, type SendMessageParams, Stream, type StreamChunk, type StreamProps, type SuggestedPrompt, type TableColumn, type TableWidget, type Thread, Threads, type ThreadsProps, type UseAptevaKitReturn, type Widget, Widgets, type WidgetsProps, aptevaClient, cn, getThemeScript, mockMessages, mockThreads, mockWidgets };
|
|
489
|
+
export { type Action, type ActionEvent, AptevaClient, type AptevaClientConfig, type AptevaKitControl, Button, type ButtonGroupWidget, type ButtonWidget, Card, type CardWidget, type ChartWidget, Chat, type ChatHandle, type ChatMessage, type ChatProps, type ChatRequest, type ChatResponse, Command, type CommandProps, type CommandResult, type FormField, type FormWidget, type GalleryWidget, type ImageWidget, List, type ListItem, type ListWidget, type MapWidget, type Message, Prompt, type PromptProps, type SendMessageParams, Stream, type StreamChunk, type StreamProps, type SuggestedPrompt, type TableColumn, type TableWidget, type Thread, Threads, type ThreadsProps, type UseAptevaKitReturn, type Widget, Widgets, type WidgetsProps, aptevaClient, cn, getThemeScript, mockMessages, mockThreads, mockWidgets };
|
package/dist/index.js
CHANGED
|
@@ -2256,7 +2256,7 @@ var aptevaClient = new AptevaClient();
|
|
|
2256
2256
|
|
|
2257
2257
|
// src/components/Chat/Chat.tsx
|
|
2258
2258
|
|
|
2259
|
-
|
|
2259
|
+
var Chat = _react.forwardRef.call(void 0, function Chat2({
|
|
2260
2260
|
agentId,
|
|
2261
2261
|
threadId,
|
|
2262
2262
|
initialMessages = [],
|
|
@@ -2288,6 +2288,7 @@ function Chat({
|
|
|
2288
2288
|
onFileUpload,
|
|
2289
2289
|
onComplete,
|
|
2290
2290
|
onError,
|
|
2291
|
+
onToolCall,
|
|
2291
2292
|
onToolResult,
|
|
2292
2293
|
// UI
|
|
2293
2294
|
placeholder,
|
|
@@ -2299,7 +2300,7 @@ function Chat({
|
|
|
2299
2300
|
compactWidgetContext = false,
|
|
2300
2301
|
onWidgetRender,
|
|
2301
2302
|
className
|
|
2302
|
-
}) {
|
|
2303
|
+
}, ref) {
|
|
2303
2304
|
const [messages, setMessages] = _react.useState.call(void 0, initialMessages);
|
|
2304
2305
|
const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
|
|
2305
2306
|
const [currentThreadId, setCurrentThreadId] = _react.useState.call(void 0, threadId || null);
|
|
@@ -2318,6 +2319,21 @@ function Chat({
|
|
|
2318
2319
|
const [internalPlanMode, setInternalPlanMode] = _react.useState.call(void 0, planMode);
|
|
2319
2320
|
const [showSettingsMenu, setShowSettingsMenu] = _react.useState.call(void 0, false);
|
|
2320
2321
|
const fileInputRef = _react.useRef.call(void 0, null);
|
|
2322
|
+
const handleSendMessageRef = _react.useRef.call(void 0, null);
|
|
2323
|
+
_react.useImperativeHandle.call(void 0, ref, () => ({
|
|
2324
|
+
sendMessage: async (text) => {
|
|
2325
|
+
if (handleSendMessageRef.current) {
|
|
2326
|
+
await handleSendMessageRef.current(text);
|
|
2327
|
+
}
|
|
2328
|
+
},
|
|
2329
|
+
sendSystemMessage: async (text) => {
|
|
2330
|
+
if (handleSendMessageRef.current) {
|
|
2331
|
+
await handleSendMessageRef.current(text, void 0, true);
|
|
2332
|
+
}
|
|
2333
|
+
},
|
|
2334
|
+
getMessages: () => messages,
|
|
2335
|
+
clearMessages: () => setMessages([])
|
|
2336
|
+
}), [messages]);
|
|
2321
2337
|
const effectiveContext = _react.useMemo.call(void 0, () => {
|
|
2322
2338
|
if (!enableWidgets) return context;
|
|
2323
2339
|
const widgetContext = compactWidgetContext ? generateCompactWidgetContext(availableWidgets) : generateWidgetContext(availableWidgets);
|
|
@@ -2360,19 +2376,21 @@ ${widgetContext}` : widgetContext;
|
|
|
2360
2376
|
}
|
|
2361
2377
|
};
|
|
2362
2378
|
const defaultPlaceholder = mode === "chat" ? "Type a message..." : "Enter your command...";
|
|
2363
|
-
const handleSendMessage = async (text, files) => {
|
|
2379
|
+
const handleSendMessage = async (text, files, isSystem) => {
|
|
2364
2380
|
const hasFiles = files && files.length > 0;
|
|
2365
2381
|
const fileNames = hasFiles ? files.map((f) => f.name) : [];
|
|
2366
2382
|
const displayContent = hasFiles ? `${text}${text ? "\n" : ""}[Attached: ${fileNames.join(", ")}]` : text;
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2383
|
+
if (!isSystem) {
|
|
2384
|
+
const userMessage = {
|
|
2385
|
+
id: `msg-${Date.now()}`,
|
|
2386
|
+
role: "user",
|
|
2387
|
+
content: displayContent,
|
|
2388
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2389
|
+
metadata: hasFiles ? { attachments: fileNames } : void 0
|
|
2390
|
+
};
|
|
2391
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
2392
|
+
_optionalChain([onMessageSent, 'optionalCall', _58 => _58(userMessage)]);
|
|
2393
|
+
}
|
|
2376
2394
|
setIsLoading(true);
|
|
2377
2395
|
try {
|
|
2378
2396
|
const messagePayload = await buildMessageWithAttachments(text, files);
|
|
@@ -2463,6 +2481,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2463
2481
|
contentSegments.push({ type: "tool", id: chunk.tool_id, name: chunk.tool_name });
|
|
2464
2482
|
toolInputBuffer = "";
|
|
2465
2483
|
setChatToolName(chunk.tool_name);
|
|
2484
|
+
_optionalChain([onToolCall, 'optionalCall', _60 => _60(chunk.tool_name, chunk.tool_id)]);
|
|
2466
2485
|
updateMessage();
|
|
2467
2486
|
}
|
|
2468
2487
|
break;
|
|
@@ -2476,7 +2495,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2476
2495
|
const toolSegment = contentSegments.find((s) => s.type === "tool" && s.id === chunk.tool_id);
|
|
2477
2496
|
if (toolSegment) {
|
|
2478
2497
|
toolSegment.result = chunk.content;
|
|
2479
|
-
_optionalChain([onToolResult, 'optionalCall',
|
|
2498
|
+
_optionalChain([onToolResult, 'optionalCall', _61 => _61(toolSegment.name, chunk.content)]);
|
|
2480
2499
|
}
|
|
2481
2500
|
setChatToolName(null);
|
|
2482
2501
|
updateMessage();
|
|
@@ -2519,7 +2538,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2519
2538
|
});
|
|
2520
2539
|
if (threadId2 && threadId2 !== currentThreadId) {
|
|
2521
2540
|
setCurrentThreadId(threadId2);
|
|
2522
|
-
_optionalChain([onThreadChange, 'optionalCall',
|
|
2541
|
+
_optionalChain([onThreadChange, 'optionalCall', _62 => _62(threadId2)]);
|
|
2523
2542
|
}
|
|
2524
2543
|
setIsLoading(false);
|
|
2525
2544
|
setCurrentRequestId(null);
|
|
@@ -2543,7 +2562,7 @@ ${widgetContext}` : widgetContext;
|
|
|
2543
2562
|
setIsLoading(false);
|
|
2544
2563
|
setCurrentRequestId(null);
|
|
2545
2564
|
setChatToolName(null);
|
|
2546
|
-
_optionalChain([onError, 'optionalCall',
|
|
2565
|
+
_optionalChain([onError, 'optionalCall', _63 => _63(error)]);
|
|
2547
2566
|
}
|
|
2548
2567
|
);
|
|
2549
2568
|
}
|
|
@@ -2556,11 +2575,12 @@ ${widgetContext}` : widgetContext;
|
|
|
2556
2575
|
metadata: { error: true }
|
|
2557
2576
|
};
|
|
2558
2577
|
setMessages((prev) => [...prev, errorMessage]);
|
|
2559
|
-
_optionalChain([onError, 'optionalCall',
|
|
2578
|
+
_optionalChain([onError, 'optionalCall', _64 => _64(error instanceof Error ? error : new Error("Unknown error"))]);
|
|
2560
2579
|
} finally {
|
|
2561
2580
|
setIsLoading(false);
|
|
2562
2581
|
}
|
|
2563
2582
|
};
|
|
2583
|
+
handleSendMessageRef.current = handleSendMessage;
|
|
2564
2584
|
const executeCommand = async (commandOverride, files) => {
|
|
2565
2585
|
const currentCommand = commandOverride || commandInput;
|
|
2566
2586
|
if (!currentCommand.trim() && (!files || files.length === 0)) {
|
|
@@ -2601,7 +2621,7 @@ ${planningInstruction}` : planningInstruction;
|
|
|
2601
2621
|
const error = err instanceof Error ? err : new Error("Failed to generate plan");
|
|
2602
2622
|
setCommandError(error);
|
|
2603
2623
|
setCommandState("error");
|
|
2604
|
-
_optionalChain([onError, 'optionalCall',
|
|
2624
|
+
_optionalChain([onError, 'optionalCall', _65 => _65(error)]);
|
|
2605
2625
|
}
|
|
2606
2626
|
}
|
|
2607
2627
|
return;
|
|
@@ -2634,12 +2654,12 @@ ${planningInstruction}` : planningInstruction;
|
|
|
2634
2654
|
setCommandResult(result);
|
|
2635
2655
|
setCommandState("success");
|
|
2636
2656
|
setProgress(100);
|
|
2637
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
2657
|
+
_optionalChain([onComplete, 'optionalCall', _66 => _66(result)]);
|
|
2638
2658
|
},
|
|
2639
2659
|
(error) => {
|
|
2640
2660
|
setCommandError(error);
|
|
2641
2661
|
setCommandState("error");
|
|
2642
|
-
_optionalChain([onError, 'optionalCall',
|
|
2662
|
+
_optionalChain([onError, 'optionalCall', _67 => _67(error)]);
|
|
2643
2663
|
}
|
|
2644
2664
|
);
|
|
2645
2665
|
} else {
|
|
@@ -2652,7 +2672,7 @@ ${planningInstruction}` : planningInstruction;
|
|
|
2652
2672
|
setCommandResult(result);
|
|
2653
2673
|
setCommandState("success");
|
|
2654
2674
|
setProgress(100);
|
|
2655
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
2675
|
+
_optionalChain([onComplete, 'optionalCall', _68 => _68(result)]);
|
|
2656
2676
|
}
|
|
2657
2677
|
} else {
|
|
2658
2678
|
const commandInstruction = `CRITICAL COMMAND MODE: Maximum 10 words per response. Execute the command immediately. Make reasonable assumptions based on context. Use sensible defaults for missing details. DO NOT ask questions unless something is truly impossible without user input (e.g., missing required password). State what you're doing or the result. Examples: "Analyzing customer data from last quarter..." or "Created 5 new database entries successfully" or "Search complete: found 12 matching results". NO greetings, NO filler words, NO clarification requests. Action/result only.`;
|
|
@@ -2681,15 +2701,16 @@ ${commandInstruction}` : commandInstruction;
|
|
|
2681
2701
|
} else if (chunk.type === "tool_call" && chunk.tool_name) {
|
|
2682
2702
|
lastToolName = chunk.tool_name;
|
|
2683
2703
|
setCurrentToolName(chunk.tool_name);
|
|
2704
|
+
_optionalChain([onToolCall, 'optionalCall', _69 => _69(chunk.tool_name, chunk.tool_id || "")]);
|
|
2684
2705
|
accumulatedContent = "";
|
|
2685
2706
|
setStreamedContent("");
|
|
2686
2707
|
} else if (chunk.type === "tool_result") {
|
|
2687
|
-
_optionalChain([onToolResult, 'optionalCall',
|
|
2708
|
+
_optionalChain([onToolResult, 'optionalCall', _70 => _70(lastToolName, chunk.content)]);
|
|
2688
2709
|
setCurrentToolName(null);
|
|
2689
2710
|
} else if (chunk.type === "thread_id" && chunk.thread_id) {
|
|
2690
2711
|
if (!currentThreadId) {
|
|
2691
2712
|
setCurrentThreadId(chunk.thread_id);
|
|
2692
|
-
_optionalChain([onThreadChange, 'optionalCall',
|
|
2713
|
+
_optionalChain([onThreadChange, 'optionalCall', _71 => _71(chunk.thread_id)]);
|
|
2693
2714
|
}
|
|
2694
2715
|
} else if (chunk.type === "request_id" && chunk.request_id) {
|
|
2695
2716
|
setCurrentRequestId(chunk.request_id);
|
|
@@ -2705,13 +2726,13 @@ ${commandInstruction}` : commandInstruction;
|
|
|
2705
2726
|
setCommandState("success");
|
|
2706
2727
|
setProgress(100);
|
|
2707
2728
|
setCurrentRequestId(null);
|
|
2708
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
2729
|
+
_optionalChain([onComplete, 'optionalCall', _72 => _72(result)]);
|
|
2709
2730
|
},
|
|
2710
2731
|
(error) => {
|
|
2711
2732
|
setCommandError(error);
|
|
2712
2733
|
setCommandState("error");
|
|
2713
2734
|
setCurrentRequestId(null);
|
|
2714
|
-
_optionalChain([onError, 'optionalCall',
|
|
2735
|
+
_optionalChain([onError, 'optionalCall', _73 => _73(error)]);
|
|
2715
2736
|
}
|
|
2716
2737
|
);
|
|
2717
2738
|
} else {
|
|
@@ -2731,14 +2752,14 @@ ${commandInstruction}` : commandInstruction;
|
|
|
2731
2752
|
setCommandResult(result);
|
|
2732
2753
|
setCommandState("success");
|
|
2733
2754
|
setProgress(100);
|
|
2734
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
2755
|
+
_optionalChain([onComplete, 'optionalCall', _74 => _74(result)]);
|
|
2735
2756
|
}
|
|
2736
2757
|
}
|
|
2737
2758
|
} catch (err) {
|
|
2738
2759
|
const error = err instanceof Error ? err : new Error("Unknown error");
|
|
2739
2760
|
setCommandError(error);
|
|
2740
2761
|
setCommandState("error");
|
|
2741
|
-
_optionalChain([onError, 'optionalCall',
|
|
2762
|
+
_optionalChain([onError, 'optionalCall', _75 => _75(error)]);
|
|
2742
2763
|
}
|
|
2743
2764
|
};
|
|
2744
2765
|
const resetCommand = () => {
|
|
@@ -2830,8 +2851,8 @@ ${planToExecute}`;
|
|
|
2830
2851
|
executeCommand(text, files);
|
|
2831
2852
|
},
|
|
2832
2853
|
state: commandState,
|
|
2833
|
-
response: _optionalChain([commandResult, 'optionalAccess',
|
|
2834
|
-
error: _optionalChain([commandError, 'optionalAccess',
|
|
2854
|
+
response: _optionalChain([commandResult, 'optionalAccess', _76 => _76.data, 'optionalAccess', _77 => _77.summary]) || _optionalChain([commandResult, 'optionalAccess', _78 => _78.message]),
|
|
2855
|
+
error: _optionalChain([commandError, 'optionalAccess', _79 => _79.message]),
|
|
2835
2856
|
plan,
|
|
2836
2857
|
streamedContent,
|
|
2837
2858
|
toolName: currentToolName,
|
|
@@ -2858,7 +2879,7 @@ ${planToExecute}`;
|
|
|
2858
2879
|
`
|
|
2859
2880
|
} })
|
|
2860
2881
|
] });
|
|
2861
|
-
}
|
|
2882
|
+
});
|
|
2862
2883
|
|
|
2863
2884
|
// src/components/Chat/CommandOutput.tsx
|
|
2864
2885
|
|
|
@@ -2999,13 +3020,13 @@ ${planningInstruction}` : planningInstruction;
|
|
|
2999
3020
|
const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
|
|
3000
3021
|
setError(error2);
|
|
3001
3022
|
setState("error");
|
|
3002
|
-
_optionalChain([onError, 'optionalCall',
|
|
3023
|
+
_optionalChain([onError, 'optionalCall', _80 => _80(error2)]);
|
|
3003
3024
|
});
|
|
3004
3025
|
} catch (err) {
|
|
3005
3026
|
const error2 = err instanceof Error ? err : new Error("Failed to generate plan");
|
|
3006
3027
|
setError(error2);
|
|
3007
3028
|
setState("error");
|
|
3008
|
-
_optionalChain([onError, 'optionalCall',
|
|
3029
|
+
_optionalChain([onError, 'optionalCall', _81 => _81(error2)]);
|
|
3009
3030
|
}
|
|
3010
3031
|
}
|
|
3011
3032
|
return;
|
|
@@ -3016,7 +3037,7 @@ ${planningInstruction}` : planningInstruction;
|
|
|
3016
3037
|
setStreamedContent("");
|
|
3017
3038
|
setCommand("");
|
|
3018
3039
|
setUploadedFiles([]);
|
|
3019
|
-
_optionalChain([onStart, 'optionalCall',
|
|
3040
|
+
_optionalChain([onStart, 'optionalCall', _82 => _82()]);
|
|
3020
3041
|
try {
|
|
3021
3042
|
if (useMock) {
|
|
3022
3043
|
if (enableStreaming) {
|
|
@@ -3027,16 +3048,16 @@ ${planningInstruction}` : planningInstruction;
|
|
|
3027
3048
|
if (chunk.type === "token" && chunk.content) {
|
|
3028
3049
|
accumulatedContent += chunk.content;
|
|
3029
3050
|
setStreamedContent(accumulatedContent);
|
|
3030
|
-
_optionalChain([onChunk, 'optionalCall',
|
|
3051
|
+
_optionalChain([onChunk, 'optionalCall', _83 => _83(chunk.content)]);
|
|
3031
3052
|
const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
|
|
3032
3053
|
setProgress(estimatedProgress);
|
|
3033
|
-
_optionalChain([onProgress, 'optionalCall',
|
|
3054
|
+
_optionalChain([onProgress, 'optionalCall', _84 => _84(estimatedProgress)]);
|
|
3034
3055
|
} else if (chunk.type === "widget" && chunk.widget) {
|
|
3035
3056
|
const widget = chunk.widget;
|
|
3036
3057
|
setResult((prev) => ({
|
|
3037
3058
|
success: true,
|
|
3038
|
-
data: _optionalChain([prev, 'optionalAccess',
|
|
3039
|
-
widgets: [..._optionalChain([prev, 'optionalAccess',
|
|
3059
|
+
data: _optionalChain([prev, 'optionalAccess', _85 => _85.data]) || {},
|
|
3060
|
+
widgets: [..._optionalChain([prev, 'optionalAccess', _86 => _86.widgets]) || [], widget],
|
|
3040
3061
|
message: accumulatedContent || "Command executed successfully"
|
|
3041
3062
|
}));
|
|
3042
3063
|
}
|
|
@@ -3056,19 +3077,19 @@ ${planningInstruction}` : planningInstruction;
|
|
|
3056
3077
|
setResult(result2);
|
|
3057
3078
|
setState("success");
|
|
3058
3079
|
setProgress(100);
|
|
3059
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
3080
|
+
_optionalChain([onComplete, 'optionalCall', _87 => _87(result2)]);
|
|
3060
3081
|
},
|
|
3061
3082
|
(error2) => {
|
|
3062
3083
|
setError(error2);
|
|
3063
3084
|
setState("error");
|
|
3064
|
-
_optionalChain([onError, 'optionalCall',
|
|
3085
|
+
_optionalChain([onError, 'optionalCall', _88 => _88(error2)]);
|
|
3065
3086
|
}
|
|
3066
3087
|
);
|
|
3067
3088
|
} else {
|
|
3068
3089
|
const progressInterval = setInterval(() => {
|
|
3069
3090
|
setProgress((prev) => {
|
|
3070
3091
|
const next = Math.min(prev + 10, 90);
|
|
3071
|
-
_optionalChain([onProgress, 'optionalCall',
|
|
3092
|
+
_optionalChain([onProgress, 'optionalCall', _89 => _89(next)]);
|
|
3072
3093
|
return next;
|
|
3073
3094
|
});
|
|
3074
3095
|
}, 200);
|
|
@@ -3092,7 +3113,7 @@ ${planningInstruction}` : planningInstruction;
|
|
|
3092
3113
|
setResult(result2);
|
|
3093
3114
|
setState("success");
|
|
3094
3115
|
setProgress(100);
|
|
3095
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
3116
|
+
_optionalChain([onComplete, 'optionalCall', _90 => _90(result2)]);
|
|
3096
3117
|
}
|
|
3097
3118
|
} else {
|
|
3098
3119
|
if (enableStreaming) {
|
|
@@ -3138,16 +3159,16 @@ ${commandInstruction}` : commandInstruction;
|
|
|
3138
3159
|
if (chunk.type === "token" && chunk.content) {
|
|
3139
3160
|
accumulatedContent += chunk.content;
|
|
3140
3161
|
setStreamedContent(accumulatedContent);
|
|
3141
|
-
_optionalChain([onChunk, 'optionalCall',
|
|
3162
|
+
_optionalChain([onChunk, 'optionalCall', _91 => _91(chunk.content)]);
|
|
3142
3163
|
const estimatedProgress = Math.min(Math.round(accumulatedContent.length / 10), 90);
|
|
3143
3164
|
setProgress(estimatedProgress);
|
|
3144
|
-
_optionalChain([onProgress, 'optionalCall',
|
|
3165
|
+
_optionalChain([onProgress, 'optionalCall', _92 => _92(estimatedProgress)]);
|
|
3145
3166
|
} else if (chunk.type === "widget" && chunk.widget) {
|
|
3146
3167
|
const widget = chunk.widget;
|
|
3147
3168
|
setResult((prev) => ({
|
|
3148
3169
|
success: true,
|
|
3149
|
-
data: _optionalChain([prev, 'optionalAccess',
|
|
3150
|
-
widgets: [..._optionalChain([prev, 'optionalAccess',
|
|
3170
|
+
data: _optionalChain([prev, 'optionalAccess', _93 => _93.data]) || {},
|
|
3171
|
+
widgets: [..._optionalChain([prev, 'optionalAccess', _94 => _94.widgets]) || [], widget],
|
|
3151
3172
|
message: accumulatedContent || "Command executed successfully"
|
|
3152
3173
|
}));
|
|
3153
3174
|
}
|
|
@@ -3167,20 +3188,20 @@ ${commandInstruction}` : commandInstruction;
|
|
|
3167
3188
|
setResult(result2);
|
|
3168
3189
|
setState("success");
|
|
3169
3190
|
setProgress(100);
|
|
3170
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
3191
|
+
_optionalChain([onComplete, 'optionalCall', _95 => _95(result2)]);
|
|
3171
3192
|
},
|
|
3172
3193
|
(error2) => {
|
|
3173
3194
|
const err = error2 instanceof Error ? error2 : new Error("Unknown error");
|
|
3174
3195
|
setError(err);
|
|
3175
3196
|
setState("error");
|
|
3176
|
-
_optionalChain([onError, 'optionalCall',
|
|
3197
|
+
_optionalChain([onError, 'optionalCall', _96 => _96(err)]);
|
|
3177
3198
|
}
|
|
3178
3199
|
);
|
|
3179
3200
|
} else {
|
|
3180
3201
|
const progressInterval = setInterval(() => {
|
|
3181
3202
|
setProgress((prev) => {
|
|
3182
3203
|
const next = Math.min(prev + 10, 90);
|
|
3183
|
-
_optionalChain([onProgress, 'optionalCall',
|
|
3204
|
+
_optionalChain([onProgress, 'optionalCall', _97 => _97(next)]);
|
|
3184
3205
|
return next;
|
|
3185
3206
|
});
|
|
3186
3207
|
}, 200);
|
|
@@ -3236,14 +3257,14 @@ ${commandInstruction}` : commandInstruction;
|
|
|
3236
3257
|
setResult(result2);
|
|
3237
3258
|
setState("success");
|
|
3238
3259
|
setProgress(100);
|
|
3239
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
3260
|
+
_optionalChain([onComplete, 'optionalCall', _98 => _98(result2)]);
|
|
3240
3261
|
}
|
|
3241
3262
|
}
|
|
3242
3263
|
} catch (err) {
|
|
3243
3264
|
const error2 = err instanceof Error ? err : new Error("Unknown error");
|
|
3244
3265
|
setError(error2);
|
|
3245
3266
|
setState("error");
|
|
3246
|
-
_optionalChain([onError, 'optionalCall',
|
|
3267
|
+
_optionalChain([onError, 'optionalCall', _99 => _99(error2)]);
|
|
3247
3268
|
}
|
|
3248
3269
|
};
|
|
3249
3270
|
const resetCommand = () => {
|
|
@@ -3276,14 +3297,14 @@ ${planToExecute}`;
|
|
|
3276
3297
|
};
|
|
3277
3298
|
const handleFileSelect = async (e) => {
|
|
3278
3299
|
if (e.target.files && e.target.files.length > 0) {
|
|
3279
|
-
_optionalChain([onFileUpload, 'optionalCall',
|
|
3300
|
+
_optionalChain([onFileUpload, 'optionalCall', _100 => _100(e.target.files)]);
|
|
3280
3301
|
const files = [];
|
|
3281
3302
|
for (let i = 0; i < e.target.files.length; i++) {
|
|
3282
3303
|
const file = e.target.files[i];
|
|
3283
3304
|
const reader = new FileReader();
|
|
3284
3305
|
await new Promise((resolve) => {
|
|
3285
3306
|
reader.onload = (event) => {
|
|
3286
|
-
if (_optionalChain([event, 'access',
|
|
3307
|
+
if (_optionalChain([event, 'access', _101 => _101.target, 'optionalAccess', _102 => _102.result])) {
|
|
3287
3308
|
const fullDataUrl = event.target.result;
|
|
3288
3309
|
const base64Data = fullDataUrl.split(",")[1];
|
|
3289
3310
|
if (file.type.startsWith("image/")) {
|
|
@@ -3377,7 +3398,7 @@ ${planToExecute}`;
|
|
|
3377
3398
|
enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3378
3399
|
"button",
|
|
3379
3400
|
{
|
|
3380
|
-
onClick: () => _optionalChain([fileInputRef, 'access',
|
|
3401
|
+
onClick: () => _optionalChain([fileInputRef, 'access', _103 => _103.current, 'optionalAccess', _104 => _104.click, 'call', _105 => _105()]),
|
|
3381
3402
|
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",
|
|
3382
3403
|
title: "Attach file",
|
|
3383
3404
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8.4 2.8L4.4 6.8C3.736 7.464 3.736 8.536 4.4 9.2C5.064 9.864 6.136 9.864 6.8 9.2L11.6 4.4C12.704 3.296 12.704 1.504 11.6 0.4C10.496 -0.704 8.704 -0.704 7.6 0.4L2.8 5.2C1.256 6.744 1.256 9.256 2.8 10.8C4.344 12.344 6.856 12.344 8.4 10.8L12.4 6.8", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(1.6, 2.4)" }) })
|
|
@@ -3596,7 +3617,7 @@ ${planToExecute}`;
|
|
|
3596
3617
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: "w-5 h-5 text-red-600 mt-0.5 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
3597
3618
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
3598
3619
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-semibold text-red-800 dark:text-red-400", children: "Error" }),
|
|
3599
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess',
|
|
3620
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-700 dark:text-red-300 text-sm mt-1", children: _optionalChain([error, 'optionalAccess', _106 => _106.message]) })
|
|
3600
3621
|
] })
|
|
3601
3622
|
] }) }),
|
|
3602
3623
|
allowInput && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -3624,7 +3645,7 @@ ${planToExecute}`;
|
|
|
3624
3645
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-green-700 dark:text-green-300 text-sm", children: "Command executed successfully" })
|
|
3625
3646
|
] })
|
|
3626
3647
|
] }),
|
|
3627
|
-
_optionalChain([result, 'access',
|
|
3648
|
+
_optionalChain([result, 'access', _107 => _107.data, 'optionalAccess', _108 => _108.summary]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-gray-700 dark:text-gray-300 text-sm leading-relaxed whitespace-pre-line", children: result.data.summary }),
|
|
3628
3649
|
result.widgets && result.widgets.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-3", children: result.widgets.map((widget) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3629
3650
|
WidgetRenderer,
|
|
3630
3651
|
{
|
|
@@ -3675,7 +3696,7 @@ ${planToExecute}`;
|
|
|
3675
3696
|
enableFileUpload && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3676
3697
|
"button",
|
|
3677
3698
|
{
|
|
3678
|
-
onClick: () => _optionalChain([fileInputRef, 'access',
|
|
3699
|
+
onClick: () => _optionalChain([fileInputRef, 'access', _109 => _109.current, 'optionalAccess', _110 => _110.click, 'call', _111 => _111()]),
|
|
3679
3700
|
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",
|
|
3680
3701
|
title: "Attach file",
|
|
3681
3702
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8.4 2.8L4.4 6.8C3.736 7.464 3.736 8.536 4.4 9.2C5.064 9.864 6.136 9.864 6.8 9.2L11.6 4.4C12.704 3.296 12.704 1.504 11.6 0.4C10.496 -0.704 8.704 -0.704 7.6 0.4L2.8 5.2C1.256 6.744 1.256 9.256 2.8 10.8C4.344 12.344 6.856 12.344 8.4 10.8L12.4 6.8", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round", transform: "translate(1.6, 2.4)" }) })
|
|
@@ -3861,25 +3882,25 @@ function Prompt({
|
|
|
3861
3882
|
const newValue = e.target.value;
|
|
3862
3883
|
if (!maxLength || newValue.length <= maxLength) {
|
|
3863
3884
|
setValue(newValue);
|
|
3864
|
-
_optionalChain([onChange, 'optionalCall',
|
|
3885
|
+
_optionalChain([onChange, 'optionalCall', _112 => _112(newValue)]);
|
|
3865
3886
|
}
|
|
3866
3887
|
};
|
|
3867
3888
|
const handleSubmit = async () => {
|
|
3868
3889
|
if (value.length < minLength) return;
|
|
3869
|
-
_optionalChain([onSubmit, 'optionalCall',
|
|
3890
|
+
_optionalChain([onSubmit, 'optionalCall', _113 => _113(value)]);
|
|
3870
3891
|
setIsLoading(true);
|
|
3871
3892
|
try {
|
|
3872
3893
|
if (useMock) {
|
|
3873
3894
|
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
3874
3895
|
const mockResult = `Enhanced version: ${value} [AI-generated content]`;
|
|
3875
|
-
_optionalChain([onResult, 'optionalCall',
|
|
3896
|
+
_optionalChain([onResult, 'optionalCall', _114 => _114(mockResult)]);
|
|
3876
3897
|
setValue("");
|
|
3877
3898
|
} else {
|
|
3878
3899
|
const response = await aptevaClient.chat({
|
|
3879
3900
|
agent_id: agentId,
|
|
3880
3901
|
message: value
|
|
3881
3902
|
});
|
|
3882
|
-
_optionalChain([onResult, 'optionalCall',
|
|
3903
|
+
_optionalChain([onResult, 'optionalCall', _115 => _115(response.message)]);
|
|
3883
3904
|
setValue("");
|
|
3884
3905
|
}
|
|
3885
3906
|
} catch (error) {
|
|
@@ -3974,7 +3995,7 @@ function Stream({
|
|
|
3974
3995
|
}, [autoStart]);
|
|
3975
3996
|
const startStreaming = async () => {
|
|
3976
3997
|
setIsStreaming(true);
|
|
3977
|
-
_optionalChain([onStart, 'optionalCall',
|
|
3998
|
+
_optionalChain([onStart, 'optionalCall', _116 => _116()]);
|
|
3978
3999
|
try {
|
|
3979
4000
|
if (useMock) {
|
|
3980
4001
|
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.";
|
|
@@ -3982,13 +4003,13 @@ function Stream({
|
|
|
3982
4003
|
mockText,
|
|
3983
4004
|
(chunk) => {
|
|
3984
4005
|
setText((prev) => prev + chunk);
|
|
3985
|
-
_optionalChain([onChunk, 'optionalCall',
|
|
4006
|
+
_optionalChain([onChunk, 'optionalCall', _117 => _117(chunk)]);
|
|
3986
4007
|
},
|
|
3987
4008
|
typingSpeed
|
|
3988
4009
|
);
|
|
3989
4010
|
setIsComplete(true);
|
|
3990
4011
|
setIsStreaming(false);
|
|
3991
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
4012
|
+
_optionalChain([onComplete, 'optionalCall', _118 => _118(text + mockText)]);
|
|
3992
4013
|
} else {
|
|
3993
4014
|
let accumulatedText = "";
|
|
3994
4015
|
await aptevaClient.chatStream(
|
|
@@ -4001,24 +4022,24 @@ function Stream({
|
|
|
4001
4022
|
if (chunk.type === "token" && chunk.content) {
|
|
4002
4023
|
accumulatedText += chunk.content;
|
|
4003
4024
|
setText(accumulatedText);
|
|
4004
|
-
_optionalChain([onChunk, 'optionalCall',
|
|
4025
|
+
_optionalChain([onChunk, 'optionalCall', _119 => _119(chunk.content)]);
|
|
4005
4026
|
}
|
|
4006
4027
|
},
|
|
4007
4028
|
() => {
|
|
4008
4029
|
setIsComplete(true);
|
|
4009
4030
|
setIsStreaming(false);
|
|
4010
|
-
_optionalChain([onComplete, 'optionalCall',
|
|
4031
|
+
_optionalChain([onComplete, 'optionalCall', _120 => _120(accumulatedText)]);
|
|
4011
4032
|
},
|
|
4012
4033
|
(error) => {
|
|
4013
4034
|
const err = error instanceof Error ? error : new Error("Streaming error");
|
|
4014
|
-
_optionalChain([onError, 'optionalCall',
|
|
4035
|
+
_optionalChain([onError, 'optionalCall', _121 => _121(err)]);
|
|
4015
4036
|
setIsStreaming(false);
|
|
4016
4037
|
}
|
|
4017
4038
|
);
|
|
4018
4039
|
}
|
|
4019
4040
|
} catch (error) {
|
|
4020
4041
|
const err = error instanceof Error ? error : new Error("Streaming error");
|
|
4021
|
-
_optionalChain([onError, 'optionalCall',
|
|
4042
|
+
_optionalChain([onError, 'optionalCall', _122 => _122(err)]);
|
|
4022
4043
|
setIsStreaming(false);
|
|
4023
4044
|
}
|
|
4024
4045
|
};
|
|
@@ -4110,7 +4131,7 @@ function ThreadList({
|
|
|
4110
4131
|
}) {
|
|
4111
4132
|
const [searchQuery, setSearchQuery] = _react.useState.call(void 0, "");
|
|
4112
4133
|
const filteredThreads = threads.filter(
|
|
4113
|
-
(thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access',
|
|
4134
|
+
(thread) => thread.title.toLowerCase().includes(searchQuery.toLowerCase()) || _optionalChain([thread, 'access', _123 => _123.preview, 'optionalAccess', _124 => _124.toLowerCase, 'call', _125 => _125(), 'access', _126 => _126.includes, 'call', _127 => _127(searchQuery.toLowerCase())])
|
|
4114
4135
|
);
|
|
4115
4136
|
const groupedThreads = groupBy === "date" ? groupThreadsByDate(filteredThreads) : { All: filteredThreads };
|
|
4116
4137
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col h-full", children: [
|
|
@@ -4132,8 +4153,8 @@ function ThreadList({
|
|
|
4132
4153
|
{
|
|
4133
4154
|
thread,
|
|
4134
4155
|
isActive: thread.id === currentThreadId,
|
|
4135
|
-
onSelect: () => _optionalChain([onThreadSelect, 'optionalCall',
|
|
4136
|
-
onDelete: () => _optionalChain([onThreadDelete, 'optionalCall',
|
|
4156
|
+
onSelect: () => _optionalChain([onThreadSelect, 'optionalCall', _128 => _128(thread.id)]),
|
|
4157
|
+
onDelete: () => _optionalChain([onThreadDelete, 'optionalCall', _129 => _129(thread.id)])
|
|
4137
4158
|
},
|
|
4138
4159
|
thread.id
|
|
4139
4160
|
))
|
|
@@ -4195,7 +4216,7 @@ function Threads({
|
|
|
4195
4216
|
threads.slice(0, 5).map((thread) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4196
4217
|
"button",
|
|
4197
4218
|
{
|
|
4198
|
-
onClick: () => _optionalChain([onThreadSelect, 'optionalCall',
|
|
4219
|
+
onClick: () => _optionalChain([onThreadSelect, 'optionalCall', _130 => _130(thread.id)]),
|
|
4199
4220
|
className: cn(
|
|
4200
4221
|
"px-4 py-2 whitespace-nowrap font-medium transition-colors",
|
|
4201
4222
|
thread.id === currentThreadId ? "border-b-2 border-apteva-500 text-apteva-500" : "text-gray-600 hover:text-gray-900"
|