@alpaca-editor/core 1.0.4192 → 1.0.4193
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/agents-view/AgentCard.js +1 -1
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentsView.js +5 -7
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/config/config.js +14 -7
- package/dist/config/config.js.map +1 -1
- package/dist/editor/ItemInfo.js +3 -3
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/QuickItemSwitcher.js +1 -1
- package/dist/editor/QuickItemSwitcher.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.d.ts +1 -7
- package/dist/editor/ai/AgentTerminal.js +382 -256
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/Agents.js +84 -198
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +1 -3
- package/dist/editor/ai/AiResponseMessage.js +12 -65
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +1 -2
- package/dist/editor/ai/ToolCallDisplay.js +5 -13
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/client/EditorShell.js +5 -6
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +4 -6
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +0 -2
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/control-center/About.js +1 -1
- package/dist/editor/control-center/About.js.map +1 -1
- package/dist/editor/control-center/AllAgentsPanel.js +1 -1
- package/dist/editor/field-types/MultiLineText.js +1 -1
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +0 -1
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +1 -1
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/PageWizard.js +3 -3
- package/dist/page-wizard/PageWizard.js.map +1 -1
- package/dist/page-wizard/WizardSteps.js +1 -1
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/OpenPage.js +6 -10
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +2 -2
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +1 -1
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +12 -244
- package/package.json +1 -1
- package/src/agents-view/AgentCard.tsx +6 -1
- package/src/agents-view/AgentsView.tsx +30 -18
- package/src/config/config.tsx +17 -8
- package/src/editor/ItemInfo.tsx +2 -3
- package/src/editor/QuickItemSwitcher.tsx +1 -1
- package/src/editor/ai/AgentTerminal.tsx +649 -544
- package/src/editor/ai/Agents.tsx +250 -464
- package/src/editor/ai/AiResponseMessage.tsx +29 -134
- package/src/editor/ai/ToolCallDisplay.tsx +4 -18
- package/src/editor/client/EditorShell.tsx +6 -9
- package/src/editor/client/hooks/useSocketMessageHandler.ts +7 -6
- package/src/editor/commands/componentCommands.tsx +0 -1
- package/src/editor/control-center/About.tsx +2 -2
- package/src/editor/control-center/AllAgentsPanel.tsx +1 -1
- package/src/editor/field-types/MultiLineText.tsx +1 -1
- package/src/editor/services/aiService.ts +0 -2
- package/src/editor/sidebar/Validation.tsx +1 -1
- package/src/index.ts +0 -5
- package/src/page-wizard/PageWizard.tsx +3 -3
- package/src/page-wizard/WizardSteps.tsx +1 -1
- package/src/revision.ts +2 -2
- package/src/splash-screen/OpenPage.tsx +4 -12
- package/src/splash-screen/RecentPages.tsx +61 -58
- package/src/splash-screen/SplashScreen.tsx +1 -1
- package/styles.css +0 -20
- package/dist/components/ui/PlaceholderInput.d.ts +0 -41
- package/dist/components/ui/PlaceholderInput.js +0 -160
- package/dist/components/ui/PlaceholderInput.js.map +0 -1
- package/dist/components/ui/PlaceholderInputTypes.d.ts +0 -41
- package/dist/components/ui/PlaceholderInputTypes.js +0 -48
- package/dist/components/ui/PlaceholderInputTypes.js.map +0 -1
- package/dist/components/ui/PlaceholderItemSelector.d.ts +0 -7
- package/dist/components/ui/PlaceholderItemSelector.js +0 -154
- package/dist/components/ui/PlaceholderItemSelector.js.map +0 -1
- package/dist/editor/ai/MediaImage.d.ts +0 -6
- package/dist/editor/ai/MediaImage.js +0 -38
- package/dist/editor/ai/MediaImage.js.map +0 -1
- package/dist/splash-screen/ModernSplashScreen.d.ts +0 -8
- package/dist/splash-screen/ModernSplashScreen.js +0 -92
- package/dist/splash-screen/ModernSplashScreen.js.map +0 -1
- package/dist/splash-screen/ParheliaAssistantChat.d.ts +0 -8
- package/dist/splash-screen/ParheliaAssistantChat.js +0 -155
- package/dist/splash-screen/ParheliaAssistantChat.js.map +0 -1
- package/dist/splash-screen/RecentAgents.d.ts +0 -7
- package/dist/splash-screen/RecentAgents.js +0 -76
- package/dist/splash-screen/RecentAgents.js.map +0 -1
- package/src/components/ui/PlaceholderInput.tsx +0 -290
- package/src/components/ui/PlaceholderInputTypes.tsx +0 -97
- package/src/components/ui/PlaceholderItemSelector.tsx +0 -253
- package/src/editor/ai/MediaImage.tsx +0 -75
- package/src/splash-screen/ModernSplashScreen.tsx +0 -229
- package/src/splash-screen/ParheliaAssistantChat.tsx +0 -273
- package/src/splash-screen/RecentAgents.tsx +0 -151
package/src/editor/ai/Agents.tsx
CHANGED
|
@@ -34,10 +34,8 @@ import {
|
|
|
34
34
|
DropdownMenuItem,
|
|
35
35
|
DropdownMenuTrigger,
|
|
36
36
|
} from "../../components/ui/dropdown-menu";
|
|
37
|
-
import { ChevronDown
|
|
37
|
+
import { ChevronDown } from "lucide-react";
|
|
38
38
|
import { AgentProfilesOverview } from "./AgentProfilesOverview";
|
|
39
|
-
import { AgentsView } from "../../agents-view/AgentsView";
|
|
40
|
-
import { SecretAgentIcon } from "../ui/Icons";
|
|
41
39
|
|
|
42
40
|
// function convertAgentMessagesToTerminalMessages(
|
|
43
41
|
// agentMessages: AgentChatMessage[],
|
|
@@ -74,13 +72,12 @@ export const Agents = React.memo(function Agents({
|
|
|
74
72
|
const [activeAgentId, setActiveAgentId] = useState<string | null>(null);
|
|
75
73
|
const activeAgentIdRef = useRef<string | null>(null);
|
|
76
74
|
const singleAgentModeRef = useRef<boolean>(false);
|
|
77
|
-
const [
|
|
78
|
-
string | null
|
|
79
|
-
>(null);
|
|
75
|
+
const [historyPopoverOpen, setHistoryPopoverOpen] = useState(false);
|
|
80
76
|
const [menuPopoverOpen, setMenuPopoverOpen] = useState(false);
|
|
81
77
|
const [addPopoverOpen, setAddPopoverOpen] = useState(false);
|
|
82
78
|
const [loadingAgents, setLoadingAgents] = useState(false);
|
|
83
79
|
const [inactiveAgents, setInactiveAgents] = useState<Agent[]>([]);
|
|
80
|
+
const [historyFilter, setHistoryFilter] = useState("");
|
|
84
81
|
const [initialMetadataMap, setInitialMetadataMap] = useState<
|
|
85
82
|
Record<string, AgentMetadata | undefined>
|
|
86
83
|
>({});
|
|
@@ -96,44 +93,6 @@ export const Agents = React.memo(function Agents({
|
|
|
96
93
|
[editContext?.currentItemDescriptor?.id],
|
|
97
94
|
);
|
|
98
95
|
|
|
99
|
-
// Group agents by profile for profile-based tabs
|
|
100
|
-
const agentsGroupedByProfile = useMemo(() => {
|
|
101
|
-
const profileMap = new Map<
|
|
102
|
-
string,
|
|
103
|
-
{
|
|
104
|
-
profileId: string | null;
|
|
105
|
-
profileName: string;
|
|
106
|
-
profileSvgIcon: string | undefined;
|
|
107
|
-
agents: Agent[];
|
|
108
|
-
}
|
|
109
|
-
>();
|
|
110
|
-
|
|
111
|
-
agents.forEach((agent) => {
|
|
112
|
-
const profileId = agent.profileId || null;
|
|
113
|
-
const profileKey = profileId || "general";
|
|
114
|
-
const profile = availableProfiles.find((p) => p.id === profileId);
|
|
115
|
-
|
|
116
|
-
if (!profileMap.has(profileKey)) {
|
|
117
|
-
profileMap.set(profileKey, {
|
|
118
|
-
profileId,
|
|
119
|
-
profileName: agent.profileName || "General",
|
|
120
|
-
profileSvgIcon: profile?.svgIcon,
|
|
121
|
-
agents: [],
|
|
122
|
-
});
|
|
123
|
-
} else {
|
|
124
|
-
// Update icon if current group doesn't have one but this agent does
|
|
125
|
-
const group = profileMap.get(profileKey)!;
|
|
126
|
-
if (!group.profileSvgIcon && profile?.svgIcon) {
|
|
127
|
-
group.profileSvgIcon = profile?.svgIcon;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
profileMap.get(profileKey)!.agents.push(agent);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
return profileMap;
|
|
135
|
-
}, [agents, availableProfiles]);
|
|
136
|
-
|
|
137
96
|
// Detect single-agent mode from query parameter once on mount
|
|
138
97
|
useEffect(() => {
|
|
139
98
|
try {
|
|
@@ -144,6 +103,18 @@ export const Agents = React.memo(function Agents({
|
|
|
144
103
|
} catch {}
|
|
145
104
|
}, []);
|
|
146
105
|
|
|
106
|
+
// Helper function to filter agents by name
|
|
107
|
+
const getFilteredInactiveAgents = (): Agent[] => {
|
|
108
|
+
if (!historyFilter.trim()) {
|
|
109
|
+
return inactiveAgents;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const filterLower = historyFilter.toLowerCase();
|
|
113
|
+
return inactiveAgents.filter((agent) =>
|
|
114
|
+
agent.name.toLowerCase().includes(filterLower),
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
147
118
|
// Helper function to get the most recently updated agent
|
|
148
119
|
const getMostRecentAgent = (agentList: Agent[]): Agent | null => {
|
|
149
120
|
if (agentList.length === 0) return null;
|
|
@@ -154,34 +125,6 @@ export const Agents = React.memo(function Agents({
|
|
|
154
125
|
});
|
|
155
126
|
};
|
|
156
127
|
|
|
157
|
-
// Helper function to get highest priority status for a group of agents
|
|
158
|
-
const getHighestPriorityStatus = (agentList: Agent[]): Agent["status"] => {
|
|
159
|
-
const statusPriority: Record<string, number> = {
|
|
160
|
-
waitingForApproval: 5,
|
|
161
|
-
error: 4,
|
|
162
|
-
running: 3,
|
|
163
|
-
idle: 2,
|
|
164
|
-
completed: 1,
|
|
165
|
-
closed: 0,
|
|
166
|
-
new: 0,
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
let highestPriority = -1;
|
|
170
|
-
let highestStatus: Agent["status"] = "idle";
|
|
171
|
-
|
|
172
|
-
agentList.forEach((agent) => {
|
|
173
|
-
const statusKey =
|
|
174
|
-
typeof agent.status === "string" ? agent.status : "idle";
|
|
175
|
-
const priority = statusPriority[statusKey] ?? 0;
|
|
176
|
-
if (priority > highestPriority) {
|
|
177
|
-
highestPriority = priority;
|
|
178
|
-
highestStatus = agent.status;
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
return highestStatus;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
128
|
// Helper function to set active agent and persist to localStorage
|
|
186
129
|
const setActiveAgentIdWithStorage = (agentId: string | null) => {
|
|
187
130
|
setActiveAgentId(agentId);
|
|
@@ -346,8 +289,7 @@ export const Agents = React.memo(function Agents({
|
|
|
346
289
|
}
|
|
347
290
|
}
|
|
348
291
|
if (message.type === "agent:run:start") {
|
|
349
|
-
const { agentId, agentName, autoSelect
|
|
350
|
-
message.payload;
|
|
292
|
+
const { agentId, agentName, autoSelect } = message.payload;
|
|
351
293
|
|
|
352
294
|
if (!agentId || !agentName) {
|
|
353
295
|
console.warn(
|
|
@@ -367,7 +309,7 @@ export const Agents = React.memo(function Agents({
|
|
|
367
309
|
);
|
|
368
310
|
|
|
369
311
|
if (existingAgentIndex !== -1) {
|
|
370
|
-
// Update existing agent name
|
|
312
|
+
// Update existing agent name
|
|
371
313
|
const updatedAgents = [...prevAgents];
|
|
372
314
|
const existingAgent = updatedAgents[existingAgentIndex]!;
|
|
373
315
|
updatedAgents[existingAgentIndex] = {
|
|
@@ -375,8 +317,6 @@ export const Agents = React.memo(function Agents({
|
|
|
375
317
|
name: agentName,
|
|
376
318
|
status: "running" as const,
|
|
377
319
|
updatedDate: new Date().toISOString(),
|
|
378
|
-
...(profileId && { profileId }),
|
|
379
|
-
...(profileName && { profileName }),
|
|
380
320
|
};
|
|
381
321
|
return updatedAgents;
|
|
382
322
|
} else {
|
|
@@ -387,8 +327,6 @@ export const Agents = React.memo(function Agents({
|
|
|
387
327
|
status: "running" as const,
|
|
388
328
|
userId: "", // Will be populated from backend if needed
|
|
389
329
|
updatedDate: new Date().toISOString(),
|
|
390
|
-
...(profileId && { profileId }),
|
|
391
|
-
...(profileName && { profileName }),
|
|
392
330
|
};
|
|
393
331
|
|
|
394
332
|
return [...prevAgents, newAgent];
|
|
@@ -539,11 +477,13 @@ export const Agents = React.memo(function Agents({
|
|
|
539
477
|
|
|
540
478
|
setAgents(activeAgentsResult);
|
|
541
479
|
|
|
542
|
-
//
|
|
480
|
+
// Determine which agent to select as active
|
|
543
481
|
let selectedAgentId: string | null = null;
|
|
544
482
|
|
|
545
483
|
if (activeAgentsResult.length > 0) {
|
|
484
|
+
// Try to restore the previously active agent from localStorage
|
|
546
485
|
const storedAgentId = localStorage.getItem(ACTIVE_AGENT_STORAGE_KEY);
|
|
486
|
+
|
|
547
487
|
const storedAgent = activeAgentsResult.find(
|
|
548
488
|
(agent) => agent.id === storedAgentId,
|
|
549
489
|
);
|
|
@@ -551,7 +491,7 @@ export const Agents = React.memo(function Agents({
|
|
|
551
491
|
if (storedAgent) {
|
|
552
492
|
selectedAgentId = storedAgent.id;
|
|
553
493
|
} else {
|
|
554
|
-
//
|
|
494
|
+
// Fall back to the most recently updated agent
|
|
555
495
|
const mostRecentAgent = getMostRecentAgent(activeAgentsResult);
|
|
556
496
|
selectedAgentId = mostRecentAgent?.id || null;
|
|
557
497
|
}
|
|
@@ -602,8 +542,6 @@ export const Agents = React.memo(function Agents({
|
|
|
602
542
|
name: `New Agent`,
|
|
603
543
|
updatedDate: new Date().toISOString(),
|
|
604
544
|
userId: "",
|
|
605
|
-
profileId: metadata?.additionalData?.profileId,
|
|
606
|
-
profileName: metadata?.additionalData?.profileName || metadata?.profile,
|
|
607
545
|
};
|
|
608
546
|
setAgents((prev) => [...prev, newAgent]);
|
|
609
547
|
// User-initiated creation should activate the new agent tab
|
|
@@ -730,85 +668,6 @@ export const Agents = React.memo(function Agents({
|
|
|
730
668
|
}
|
|
731
669
|
};
|
|
732
670
|
|
|
733
|
-
const handleCloseProfileAgents = async (
|
|
734
|
-
profileAgents: Agent[],
|
|
735
|
-
profileName: string,
|
|
736
|
-
e: React.MouseEvent,
|
|
737
|
-
) => {
|
|
738
|
-
e.stopPropagation();
|
|
739
|
-
|
|
740
|
-
const agentCount = profileAgents.length;
|
|
741
|
-
const hasActiveAgents = profileAgents.some(
|
|
742
|
-
(agent) =>
|
|
743
|
-
agent.status === "running" ||
|
|
744
|
-
agent.status === "waitingForApproval" ||
|
|
745
|
-
agent.status === 1 ||
|
|
746
|
-
agent.status === 2,
|
|
747
|
-
);
|
|
748
|
-
|
|
749
|
-
if (editContext?.confirm) {
|
|
750
|
-
editContext.confirm({
|
|
751
|
-
header: `Close ${agentCount} Agent${agentCount > 1 ? "s" : ""}`,
|
|
752
|
-
message: hasActiveAgents
|
|
753
|
-
? `This will close all ${agentCount} ${profileName} agent${agentCount > 1 ? "s" : ""}, including ${profileAgents.filter((a) => a.status === "running" || a.status === 1).length} running agent(s). Are you sure?`
|
|
754
|
-
: `Are you sure you want to close all ${agentCount} ${profileName} agent${agentCount > 1 ? "s" : ""}?`,
|
|
755
|
-
acceptLabel: `Close ${agentCount > 1 ? "All" : "Agent"}`,
|
|
756
|
-
accept: async () => {
|
|
757
|
-
// Close all agents in this profile
|
|
758
|
-
const closePromises = profileAgents.map((agent) =>
|
|
759
|
-
closeAgentService(agent.id).catch((error) => {
|
|
760
|
-
console.error(`Failed to close agent ${agent.id}:`, error);
|
|
761
|
-
}),
|
|
762
|
-
);
|
|
763
|
-
|
|
764
|
-
await Promise.all(closePromises);
|
|
765
|
-
|
|
766
|
-
// Update UI state
|
|
767
|
-
setAgents((prev) => {
|
|
768
|
-
const agentIds = new Set(profileAgents.map((a) => a.id));
|
|
769
|
-
const filtered = prev.filter((a) => !agentIds.has(a.id));
|
|
770
|
-
|
|
771
|
-
// Add closed agents to history
|
|
772
|
-
const closedAgents = profileAgents.map((agent) => ({
|
|
773
|
-
...agent,
|
|
774
|
-
status: "closed" as const,
|
|
775
|
-
updatedDate: new Date().toISOString(),
|
|
776
|
-
}));
|
|
777
|
-
|
|
778
|
-
setInactiveAgents((prevInactive) => {
|
|
779
|
-
const newAgents = closedAgents.filter(
|
|
780
|
-
(closedAgent) =>
|
|
781
|
-
!prevInactive.some((a) => a.id === closedAgent.id),
|
|
782
|
-
);
|
|
783
|
-
return [...newAgents, ...prevInactive];
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
// If we're closing the active agent, switch to most recent remaining or null
|
|
787
|
-
if (
|
|
788
|
-
activeAgentIdRef.current &&
|
|
789
|
-
agentIds.has(activeAgentIdRef.current)
|
|
790
|
-
) {
|
|
791
|
-
if (filtered.length > 0) {
|
|
792
|
-
const mostRecentAgent = getMostRecentAgent(filtered);
|
|
793
|
-
setActiveAgentIdWithStorage(mostRecentAgent?.id || null);
|
|
794
|
-
} else {
|
|
795
|
-
setActiveAgentIdWithStorage(null);
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// Reset profile selection if no agents remain
|
|
800
|
-
if (filtered.length === 0) {
|
|
801
|
-
setSelectedProfileId("");
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
return filtered;
|
|
805
|
-
});
|
|
806
|
-
},
|
|
807
|
-
showCancel: true,
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
};
|
|
811
|
-
|
|
812
671
|
const closeOtherAgents = async () => {
|
|
813
672
|
if (!activeAgentIdRef.current) return;
|
|
814
673
|
|
|
@@ -871,45 +730,37 @@ export const Agents = React.memo(function Agents({
|
|
|
871
730
|
if (existingAgent) {
|
|
872
731
|
// Switch to existing agent
|
|
873
732
|
setActiveAgentIdWithStorage(existingAgent.id);
|
|
733
|
+
setHistoryPopoverOpen(false);
|
|
874
734
|
return;
|
|
875
735
|
}
|
|
876
736
|
|
|
877
|
-
// If agent data is incomplete (e.g., only has ID), fetch full details from backend
|
|
878
|
-
let fullAgent = agent;
|
|
879
|
-
if (!agent.name || !agent.userId) {
|
|
880
|
-
try {
|
|
881
|
-
const { getAgent } = await import("../services/agentService");
|
|
882
|
-
const agentDetails = await getAgent(agent.id);
|
|
883
|
-
fullAgent = {
|
|
884
|
-
id: agentDetails.id,
|
|
885
|
-
name: agentDetails.name,
|
|
886
|
-
description: agentDetails.description,
|
|
887
|
-
userId: agentDetails.userId,
|
|
888
|
-
updatedDate: agentDetails.updatedDate,
|
|
889
|
-
status: agentDetails.status,
|
|
890
|
-
isShared: agentDetails.isShared,
|
|
891
|
-
ownerName: agentDetails.ownerName,
|
|
892
|
-
profileId: agentDetails.profileId,
|
|
893
|
-
profileName: agentDetails.profileName,
|
|
894
|
-
profileSvgIcon: agentDetails.profileSvgIcon,
|
|
895
|
-
messageCount: agentDetails.messageCount,
|
|
896
|
-
totalCost: agentDetails.totalCost,
|
|
897
|
-
totalTokensUsed: agentDetails.totalTokensUsed,
|
|
898
|
-
};
|
|
899
|
-
} catch (error) {
|
|
900
|
-
console.error("Failed to fetch agent details:", error);
|
|
901
|
-
// Fall back to using whatever data we have
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
|
|
905
737
|
// Add the closed agent to the active agents list
|
|
906
738
|
const reopenedAgent: Agent = {
|
|
907
|
-
...
|
|
739
|
+
...agent,
|
|
908
740
|
// Keep the original status to allow AgentTerminal to load the full agent data
|
|
909
741
|
};
|
|
910
742
|
|
|
911
743
|
setAgents((prev) => [...prev, reopenedAgent]);
|
|
912
744
|
setActiveAgentIdWithStorage(reopenedAgent.id);
|
|
745
|
+
setHistoryPopoverOpen(false);
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
const deleteAgentFromHistory = async (
|
|
749
|
+
agentId: string,
|
|
750
|
+
event: React.MouseEvent,
|
|
751
|
+
) => {
|
|
752
|
+
event.stopPropagation(); // Prevent opening the agent when clicking delete
|
|
753
|
+
|
|
754
|
+
try {
|
|
755
|
+
// Permanently delete the agent from the backend
|
|
756
|
+
await deleteAgent(agentId);
|
|
757
|
+
|
|
758
|
+
// Remove from inactive agents list
|
|
759
|
+
setInactiveAgents((prev) => prev.filter((agent) => agent.id !== agentId));
|
|
760
|
+
} catch (error) {
|
|
761
|
+
console.error("Failed to delete agent:", error);
|
|
762
|
+
// You might want to show a user-facing error message here
|
|
763
|
+
}
|
|
913
764
|
};
|
|
914
765
|
|
|
915
766
|
if (loadingAgents) {
|
|
@@ -923,55 +774,32 @@ export const Agents = React.memo(function Agents({
|
|
|
923
774
|
// Empty state when no agents are open
|
|
924
775
|
if (!loadingAgents && agents.length === 0) {
|
|
925
776
|
return (
|
|
926
|
-
<div className="flex
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
{closeButton && (
|
|
942
|
-
<div className="flex items-center">{closeButton}</div>
|
|
943
|
-
)}
|
|
944
|
-
</div>
|
|
945
|
-
</div>
|
|
946
|
-
|
|
947
|
-
{/* Content Area */}
|
|
948
|
-
<div className="flex flex-1 items-center justify-center p-4">
|
|
949
|
-
<div className="w-full max-w-4xl">
|
|
950
|
-
{loadingProfiles ? (
|
|
951
|
-
<div className="text-center text-xs text-gray-500">
|
|
952
|
-
Loading profiles...
|
|
953
|
-
</div>
|
|
954
|
-
) : availableProfiles.length > 0 ? (
|
|
955
|
-
<div className="flex flex-col gap-4">
|
|
956
|
-
<div className="text-center">
|
|
957
|
-
<h2 className="text-lg font-semibold text-gray-900">
|
|
958
|
-
Select an AI Agent Profile
|
|
959
|
-
</h2>
|
|
960
|
-
<p className="text-xs text-gray-500">
|
|
961
|
-
Choose a profile to start a new agent
|
|
962
|
-
</p>
|
|
963
|
-
</div>
|
|
964
|
-
<AgentProfilesOverview
|
|
965
|
-
profiles={availableProfiles}
|
|
966
|
-
onSelectProfile={createAgentWithSelectedProfile}
|
|
967
|
-
/>
|
|
968
|
-
</div>
|
|
969
|
-
) : (
|
|
970
|
-
<div className="text-center text-xs text-gray-500">
|
|
971
|
-
No profiles available
|
|
777
|
+
<div className="flex items-center justify-center p-4">
|
|
778
|
+
<div className="w-full max-w-4xl">
|
|
779
|
+
{loadingProfiles ? (
|
|
780
|
+
<div className="text-center text-xs text-gray-500">
|
|
781
|
+
Loading profiles...
|
|
782
|
+
</div>
|
|
783
|
+
) : availableProfiles.length > 0 ? (
|
|
784
|
+
<div className="flex flex-col gap-4">
|
|
785
|
+
<div className="text-center">
|
|
786
|
+
<h2 className="text-lg font-semibold text-gray-900">
|
|
787
|
+
Select an AI Agent Profile
|
|
788
|
+
</h2>
|
|
789
|
+
<p className="text-xs text-gray-500">
|
|
790
|
+
Choose a profile to start a new agent
|
|
791
|
+
</p>
|
|
972
792
|
</div>
|
|
973
|
-
|
|
974
|
-
|
|
793
|
+
<AgentProfilesOverview
|
|
794
|
+
profiles={availableProfiles}
|
|
795
|
+
onSelectProfile={createAgentWithSelectedProfile}
|
|
796
|
+
/>
|
|
797
|
+
</div>
|
|
798
|
+
) : (
|
|
799
|
+
<div className="text-center text-xs text-gray-500">
|
|
800
|
+
No profiles available
|
|
801
|
+
</div>
|
|
802
|
+
)}
|
|
975
803
|
</div>
|
|
976
804
|
</div>
|
|
977
805
|
);
|
|
@@ -982,213 +810,179 @@ export const Agents = React.memo(function Agents({
|
|
|
982
810
|
{/* Tab Header */}
|
|
983
811
|
<div className="flex items-center border-b border-gray-200 bg-gray-50">
|
|
984
812
|
<div className="scrollbar-hide flex flex-1 overflow-x-auto">
|
|
985
|
-
{
|
|
986
|
-
const profileKey = profileGroup.profileId || "general";
|
|
987
|
-
const activeAgent = profileGroup.agents.find(
|
|
988
|
-
(a) => a.id === activeAgentId,
|
|
989
|
-
);
|
|
990
|
-
const isActive = !!activeAgent;
|
|
991
|
-
const agentCount = profileGroup.agents.length;
|
|
992
|
-
const singleAgent =
|
|
993
|
-
agentCount === 1 ? profileGroup.agents[0] : null;
|
|
994
|
-
const highestStatus = getHighestPriorityStatus(profileGroup.agents);
|
|
995
|
-
const statusConfig = getAgentStatusConfig({
|
|
996
|
-
status: highestStatus,
|
|
997
|
-
} as Agent);
|
|
998
|
-
|
|
999
|
-
// Use agent name if: single agent OR active agent from this profile
|
|
1000
|
-
const displayName = activeAgent
|
|
1001
|
-
? activeAgent.name
|
|
1002
|
-
: singleAgent
|
|
1003
|
-
? singleAgent.name
|
|
1004
|
-
: profileGroup.profileName;
|
|
1005
|
-
|
|
1006
|
-
// Always use profile group icon since all agents in the group share the same profile
|
|
1007
|
-
const displayIcon = profileGroup.profileSvgIcon;
|
|
1008
|
-
|
|
1009
|
-
return (
|
|
1010
|
-
<Popover
|
|
1011
|
-
key={profileKey}
|
|
1012
|
-
open={profileTabDropdownOpen === profileKey}
|
|
1013
|
-
onOpenChange={(open) => {
|
|
1014
|
-
setProfileTabDropdownOpen(open ? profileKey : null);
|
|
1015
|
-
}}
|
|
1016
|
-
>
|
|
1017
|
-
<PopoverTrigger asChild>
|
|
1018
|
-
<div
|
|
1019
|
-
className={cn(
|
|
1020
|
-
"flex min-w-0 cursor-pointer items-center gap-2 border-r border-gray-200 p-2 text-xs",
|
|
1021
|
-
isActive
|
|
1022
|
-
? "border-b-white bg-white"
|
|
1023
|
-
: "hover:bg-gray-100",
|
|
1024
|
-
)}
|
|
1025
|
-
onClick={() => {
|
|
1026
|
-
if (singleAgent) {
|
|
1027
|
-
// Single agent: switch directly
|
|
1028
|
-
setActiveAgentIdWithStorage(singleAgent.id);
|
|
1029
|
-
}
|
|
1030
|
-
// Multiple agents: popover will open via PopoverTrigger
|
|
1031
|
-
}}
|
|
1032
|
-
>
|
|
1033
|
-
{/* Profile/Agent Icon */}
|
|
1034
|
-
<div className="flex-shrink-0">
|
|
1035
|
-
{displayIcon ? (
|
|
1036
|
-
<div
|
|
1037
|
-
className="flex h-[18px] w-[18px] items-center justify-center text-gray-500 [&>svg]:h-full [&>svg]:w-full"
|
|
1038
|
-
dangerouslySetInnerHTML={{
|
|
1039
|
-
__html: displayIcon,
|
|
1040
|
-
}}
|
|
1041
|
-
/>
|
|
1042
|
-
) : (
|
|
1043
|
-
<SecretAgentIcon
|
|
1044
|
-
size={18}
|
|
1045
|
-
strokeWidth={1}
|
|
1046
|
-
className="text-gray-500"
|
|
1047
|
-
/>
|
|
1048
|
-
)}
|
|
1049
|
-
</div>
|
|
1050
|
-
|
|
1051
|
-
{/* Profile/Agent Name */}
|
|
1052
|
-
<span className="truncate font-medium">{displayName}</span>
|
|
1053
|
-
|
|
1054
|
-
{/* Agent Count Badge */}
|
|
1055
|
-
{agentCount > 1 && (
|
|
1056
|
-
<div className="flex-shrink-0 rounded-full bg-gray-200 px-1.5 py-0.5 text-[10px] leading-none font-medium text-gray-700">
|
|
1057
|
-
{agentCount}
|
|
1058
|
-
</div>
|
|
1059
|
-
)}
|
|
1060
|
-
|
|
1061
|
-
{/* Status Indicator */}
|
|
1062
|
-
<Tooltip>
|
|
1063
|
-
<TooltipTrigger asChild>
|
|
1064
|
-
<div
|
|
1065
|
-
className={cn(
|
|
1066
|
-
"h-1.5 w-1.5 flex-shrink-0 rounded-full",
|
|
1067
|
-
statusConfig.color,
|
|
1068
|
-
statusConfig.shouldPulse && "animate-pulse",
|
|
1069
|
-
)}
|
|
1070
|
-
title={statusConfig.label}
|
|
1071
|
-
/>
|
|
1072
|
-
</TooltipTrigger>
|
|
1073
|
-
<TooltipContent>{statusConfig.label}</TooltipContent>
|
|
1074
|
-
</Tooltip>
|
|
1075
|
-
|
|
1076
|
-
{/* Chevron for multiple agents */}
|
|
1077
|
-
{agentCount > 1 && (
|
|
1078
|
-
<ChevronDown
|
|
1079
|
-
className="size-3 flex-shrink-0 text-gray-500"
|
|
1080
|
-
strokeWidth={1}
|
|
1081
|
-
/>
|
|
1082
|
-
)}
|
|
1083
|
-
|
|
1084
|
-
{/* Close button - always shown */}
|
|
1085
|
-
<SimpleIconButton
|
|
1086
|
-
onClick={(e) =>
|
|
1087
|
-
singleAgent
|
|
1088
|
-
? handleCloseAgent(singleAgent.id, e)
|
|
1089
|
-
: handleCloseProfileAgents(
|
|
1090
|
-
profileGroup.agents,
|
|
1091
|
-
profileGroup.profileName,
|
|
1092
|
-
e,
|
|
1093
|
-
)
|
|
1094
|
-
}
|
|
1095
|
-
icon={<X className="size-3" strokeWidth={1} />}
|
|
1096
|
-
label={
|
|
1097
|
-
agentCount > 1
|
|
1098
|
-
? `Close all ${agentCount} agents`
|
|
1099
|
-
: "Close"
|
|
1100
|
-
}
|
|
1101
|
-
className="opacity-60 hover:opacity-100"
|
|
1102
|
-
/>
|
|
1103
|
-
</div>
|
|
1104
|
-
</PopoverTrigger>
|
|
1105
|
-
|
|
1106
|
-
{/* Dropdown for multiple agents */}
|
|
1107
|
-
{agentCount > 1 && (
|
|
1108
|
-
<PopoverContent className="w-80 p-0" align="start">
|
|
1109
|
-
<div className="border-b border-gray-100 px-3 py-2 text-xs font-medium text-gray-500">
|
|
1110
|
-
{profileGroup.profileName} Agents
|
|
1111
|
-
</div>
|
|
1112
|
-
<div className="max-h-64 overflow-y-auto">
|
|
1113
|
-
{profileGroup.agents.map((agent) => {
|
|
1114
|
-
const agentStatusConfig = getAgentStatusConfig(agent);
|
|
1115
|
-
return (
|
|
1116
|
-
<div
|
|
1117
|
-
key={agent.id}
|
|
1118
|
-
className={cn(
|
|
1119
|
-
"cursor-pointer border-b border-gray-50 px-3 py-2 hover:bg-gray-50",
|
|
1120
|
-
activeAgentId === agent.id && "bg-blue-50",
|
|
1121
|
-
)}
|
|
1122
|
-
onClick={() => {
|
|
1123
|
-
setActiveAgentIdWithStorage(agent.id);
|
|
1124
|
-
setProfileTabDropdownOpen(null);
|
|
1125
|
-
}}
|
|
1126
|
-
>
|
|
1127
|
-
<div className="flex items-center gap-2">
|
|
1128
|
-
{/* Status Indicator */}
|
|
1129
|
-
<div
|
|
1130
|
-
className={cn(
|
|
1131
|
-
"h-2 w-2 flex-shrink-0 rounded-full",
|
|
1132
|
-
agentStatusConfig.color,
|
|
1133
|
-
agentStatusConfig.shouldPulse &&
|
|
1134
|
-
"animate-pulse",
|
|
1135
|
-
)}
|
|
1136
|
-
title={agentStatusConfig.label}
|
|
1137
|
-
/>
|
|
1138
|
-
{/* Agent Name */}
|
|
1139
|
-
<div className="min-w-0 flex-1">
|
|
1140
|
-
<div className="truncate text-xs font-medium text-gray-900">
|
|
1141
|
-
{agent.name}
|
|
1142
|
-
</div>
|
|
1143
|
-
{agent.description && (
|
|
1144
|
-
<div className="truncate text-[11px] leading-tight text-gray-400">
|
|
1145
|
-
{agent.description}
|
|
1146
|
-
</div>
|
|
1147
|
-
)}
|
|
1148
|
-
</div>
|
|
1149
|
-
{/* Close Button */}
|
|
1150
|
-
<SimpleIconButton
|
|
1151
|
-
onClick={(e) => handleCloseAgent(agent.id, e)}
|
|
1152
|
-
icon={<X className="size-3" strokeWidth={1} />}
|
|
1153
|
-
label="Close"
|
|
1154
|
-
className="opacity-60 hover:opacity-100"
|
|
1155
|
-
/>
|
|
1156
|
-
</div>
|
|
1157
|
-
</div>
|
|
1158
|
-
);
|
|
1159
|
-
})}
|
|
1160
|
-
</div>
|
|
1161
|
-
</PopoverContent>
|
|
1162
|
-
)}
|
|
1163
|
-
</Popover>
|
|
1164
|
-
);
|
|
1165
|
-
})}
|
|
1166
|
-
</div>
|
|
1167
|
-
|
|
1168
|
-
{/* Overview Button - only show when an agent is active (not showing overview) */}
|
|
1169
|
-
{activeAgentId !== null && (
|
|
1170
|
-
<div className="flex items-center px-1">
|
|
1171
|
-
<SimpleIconButton
|
|
1172
|
-
onClick={() => setActiveAgentIdWithStorage(null)}
|
|
1173
|
-
icon={<List className="size-4" strokeWidth={1} />}
|
|
1174
|
-
label="Agent Overview"
|
|
1175
|
-
className="text-gray-600 hover:text-gray-800"
|
|
1176
|
-
/>
|
|
1177
|
-
</div>
|
|
1178
|
-
)}
|
|
1179
|
-
|
|
1180
|
-
{/* Overview Tab - show as active tab when overview is displayed */}
|
|
1181
|
-
{activeAgentId === null && (
|
|
1182
|
-
<div className="flex items-center px-1">
|
|
813
|
+
{agents.map((agent) => (
|
|
1183
814
|
<div
|
|
815
|
+
key={agent.id}
|
|
1184
816
|
className={cn(
|
|
1185
|
-
"flex min-w-0 cursor-
|
|
1186
|
-
|
|
817
|
+
"flex min-w-0 cursor-pointer items-center gap-1 border-r border-gray-200 px-2 py-2 pr-1.5 text-xs",
|
|
818
|
+
activeAgentId === agent.id
|
|
819
|
+
? "border-b-white bg-white"
|
|
820
|
+
: "hover:bg-gray-100",
|
|
1187
821
|
)}
|
|
822
|
+
data-agent-id={agent.id}
|
|
823
|
+
data-active={activeAgentId === agent.id ? "true" : "false"}
|
|
824
|
+
onClick={() => setActiveAgentIdWithStorage(agent.id)}
|
|
825
|
+
onContextMenu={(e) => {
|
|
826
|
+
e.preventDefault();
|
|
827
|
+
e.stopPropagation();
|
|
828
|
+
// Capture coordinates before state update to avoid pooled/react event issues
|
|
829
|
+
const contextEvent = {
|
|
830
|
+
clientX: e.clientX,
|
|
831
|
+
clientY: e.clientY,
|
|
832
|
+
pageX: e.pageX,
|
|
833
|
+
pageY: e.pageY,
|
|
834
|
+
screenX: (e as any).screenX,
|
|
835
|
+
screenY: (e as any).screenY,
|
|
836
|
+
button: 2,
|
|
837
|
+
buttons: 2,
|
|
838
|
+
ctrlKey: e.ctrlKey,
|
|
839
|
+
shiftKey: e.shiftKey,
|
|
840
|
+
altKey: e.altKey,
|
|
841
|
+
preventDefault: () => {},
|
|
842
|
+
} as any;
|
|
843
|
+
|
|
844
|
+
// Show the menu first at the correct position
|
|
845
|
+
setTimeout(() => {
|
|
846
|
+
editContext?.showContextMenu(
|
|
847
|
+
contextEvent,
|
|
848
|
+
getTabsMenuItems(),
|
|
849
|
+
);
|
|
850
|
+
}, 150);
|
|
851
|
+
}}
|
|
1188
852
|
>
|
|
1189
|
-
|
|
1190
|
-
|
|
853
|
+
{/* Status Indicator */}
|
|
854
|
+
{(() => {
|
|
855
|
+
const statusConfig = getAgentStatusConfig(agent);
|
|
856
|
+
return (
|
|
857
|
+
<Tooltip>
|
|
858
|
+
<TooltipTrigger asChild>
|
|
859
|
+
<div
|
|
860
|
+
className={cn(
|
|
861
|
+
"mr-1.5 h-1.5 w-1.5 flex-shrink-0 rounded-full",
|
|
862
|
+
statusConfig.color,
|
|
863
|
+
statusConfig.shouldPulse && "animate-pulse",
|
|
864
|
+
)}
|
|
865
|
+
title={statusConfig.label}
|
|
866
|
+
/>
|
|
867
|
+
</TooltipTrigger>
|
|
868
|
+
<TooltipContent>{statusConfig.label}</TooltipContent>
|
|
869
|
+
</Tooltip>
|
|
870
|
+
);
|
|
871
|
+
})()}
|
|
872
|
+
<Tooltip>
|
|
873
|
+
<TooltipTrigger asChild>
|
|
874
|
+
<span className="truncate" title={agent.name}>
|
|
875
|
+
{agent.name}
|
|
876
|
+
</span>
|
|
877
|
+
</TooltipTrigger>
|
|
878
|
+
<TooltipContent>{agent.name}</TooltipContent>
|
|
879
|
+
</Tooltip>
|
|
880
|
+
<SimpleIconButton
|
|
881
|
+
onClick={(e) => handleCloseAgent(agent.id, e)}
|
|
882
|
+
icon={<X className="size-3" strokeWidth={1} />}
|
|
883
|
+
label="Close"
|
|
884
|
+
className="ml-1 opacity-60 hover:opacity-100"
|
|
885
|
+
/>
|
|
1191
886
|
</div>
|
|
887
|
+
))}
|
|
888
|
+
</div>
|
|
889
|
+
|
|
890
|
+
{/* History Popover */}
|
|
891
|
+
{agents.length > 0 && (
|
|
892
|
+
<div className="flex items-center px-1">
|
|
893
|
+
<Popover
|
|
894
|
+
open={historyPopoverOpen}
|
|
895
|
+
onOpenChange={(open) => {
|
|
896
|
+
setHistoryPopoverOpen(open);
|
|
897
|
+
if (!open) {
|
|
898
|
+
setHistoryFilter(""); // Clear filter when popover closes
|
|
899
|
+
}
|
|
900
|
+
}}
|
|
901
|
+
>
|
|
902
|
+
<PopoverTrigger asChild>
|
|
903
|
+
<SimpleIconButton
|
|
904
|
+
onClick={() => {}}
|
|
905
|
+
icon={<History className="size-4" strokeWidth={1} />}
|
|
906
|
+
label="Agent History"
|
|
907
|
+
className="text-gray-600 hover:text-gray-800"
|
|
908
|
+
/>
|
|
909
|
+
</PopoverTrigger>
|
|
910
|
+
<PopoverContent className="w-64 p-0" align="end">
|
|
911
|
+
<div className="border-b border-gray-100 px-3 py-2 text-xs font-medium text-gray-500">
|
|
912
|
+
Closed Agents
|
|
913
|
+
</div>
|
|
914
|
+
{inactiveAgents.length > 0 && (
|
|
915
|
+
<div className="border-b border-gray-100 px-3 py-2">
|
|
916
|
+
<input
|
|
917
|
+
type="text"
|
|
918
|
+
placeholder="Filter agents..."
|
|
919
|
+
value={historyFilter}
|
|
920
|
+
onChange={(e) => setHistoryFilter(e.target.value)}
|
|
921
|
+
className="w-full rounded border border-gray-200 px-2 py-1 text-xs focus:border-blue-500 focus:outline-none"
|
|
922
|
+
/>
|
|
923
|
+
</div>
|
|
924
|
+
)}
|
|
925
|
+
<div className="max-h-80 overflow-y-auto">
|
|
926
|
+
{(() => {
|
|
927
|
+
const filteredAgents = getFilteredInactiveAgents();
|
|
928
|
+
|
|
929
|
+
if (inactiveAgents.length === 0) {
|
|
930
|
+
return (
|
|
931
|
+
<div className="px-3 py-2 text-xs text-gray-500">
|
|
932
|
+
No closed agents found
|
|
933
|
+
</div>
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if (filteredAgents.length === 0) {
|
|
938
|
+
return (
|
|
939
|
+
<div className="px-3 py-2 text-xs text-gray-500">
|
|
940
|
+
No agents match your filter
|
|
941
|
+
</div>
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return filteredAgents.map((agent) => (
|
|
946
|
+
<div
|
|
947
|
+
key={agent.id}
|
|
948
|
+
className="cursor-pointer border-b border-gray-50 px-3 py-2 text-xs hover:bg-gray-50"
|
|
949
|
+
onClick={() => openAgentFromHistory(agent)}
|
|
950
|
+
>
|
|
951
|
+
<div className="flex items-center justify-between">
|
|
952
|
+
<div className="min-w-0 flex-1">
|
|
953
|
+
<div className="truncate font-medium text-gray-900">
|
|
954
|
+
{agent.name}
|
|
955
|
+
</div>
|
|
956
|
+
<div className="text-xs text-gray-400">
|
|
957
|
+
{(() => {
|
|
958
|
+
try {
|
|
959
|
+
const {
|
|
960
|
+
formatDateTime,
|
|
961
|
+
} = require("../utils");
|
|
962
|
+
return formatDateTime(
|
|
963
|
+
new Date(agent.updatedDate),
|
|
964
|
+
);
|
|
965
|
+
} catch {
|
|
966
|
+
return new Date(
|
|
967
|
+
agent.updatedDate,
|
|
968
|
+
).toLocaleString();
|
|
969
|
+
}
|
|
970
|
+
})()}
|
|
971
|
+
</div>
|
|
972
|
+
</div>
|
|
973
|
+
<SimpleIconButton
|
|
974
|
+
onClick={(e) => deleteAgentFromHistory(agent.id, e)}
|
|
975
|
+
icon={<Trash className="size-3" strokeWidth={1} />}
|
|
976
|
+
label="Delete Agent"
|
|
977
|
+
className="ml-2 text-red-600 opacity-60 hover:text-red-700 hover:opacity-100"
|
|
978
|
+
/>
|
|
979
|
+
</div>
|
|
980
|
+
</div>
|
|
981
|
+
));
|
|
982
|
+
})()}
|
|
983
|
+
</div>
|
|
984
|
+
</PopoverContent>
|
|
985
|
+
</Popover>
|
|
1192
986
|
</div>
|
|
1193
987
|
)}
|
|
1194
988
|
|
|
@@ -1278,30 +1072,22 @@ export const Agents = React.memo(function Agents({
|
|
|
1278
1072
|
|
|
1279
1073
|
{/* Agent Content */}
|
|
1280
1074
|
<div className="relative flex-1">
|
|
1281
|
-
{
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1075
|
+
{agents.map((agent) => (
|
|
1076
|
+
<div
|
|
1077
|
+
key={agent.id}
|
|
1078
|
+
className={cn(
|
|
1079
|
+
"absolute inset-0",
|
|
1080
|
+
activeAgentId === agent.id ? "block" : "hidden",
|
|
1081
|
+
)}
|
|
1082
|
+
>
|
|
1083
|
+
<AgentTerminal
|
|
1084
|
+
agentStub={agent}
|
|
1085
|
+
initialMetadata={initialMetadataMap[agent.id]}
|
|
1086
|
+
profiles={availableProfiles}
|
|
1087
|
+
isActive={activeAgentId === agent.id}
|
|
1088
|
+
/>
|
|
1285
1089
|
</div>
|
|
1286
|
-
)
|
|
1287
|
-
// Show agent terminals
|
|
1288
|
-
agents.map((agent) => (
|
|
1289
|
-
<div
|
|
1290
|
-
key={agent.id}
|
|
1291
|
-
className={cn(
|
|
1292
|
-
"absolute inset-0",
|
|
1293
|
-
activeAgentId === agent.id ? "block" : "hidden",
|
|
1294
|
-
)}
|
|
1295
|
-
>
|
|
1296
|
-
<AgentTerminal
|
|
1297
|
-
agentStub={agent}
|
|
1298
|
-
initialMetadata={initialMetadataMap[agent.id]}
|
|
1299
|
-
profiles={availableProfiles}
|
|
1300
|
-
isActive={activeAgentId === agent.id}
|
|
1301
|
-
/>
|
|
1302
|
-
</div>
|
|
1303
|
-
))
|
|
1304
|
-
)}
|
|
1090
|
+
))}
|
|
1305
1091
|
</div>
|
|
1306
1092
|
</div>
|
|
1307
1093
|
);
|