@alpaca-editor/core 1.0.4190 → 1.0.4191
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 -63
- 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 -241
- 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 -154
- 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/splash-screen/ModernSplashScreen.d.ts +0 -8
- package/dist/splash-screen/ModernSplashScreen.js +0 -36
- 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/splash-screen/ModernSplashScreen.tsx +0 -158
- package/src/splash-screen/ParheliaAssistantChat.tsx +0 -273
- package/src/splash-screen/RecentAgents.tsx +0 -151
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { useState, useEffect, useCallback, startTransition, ViewTransition } from "react";
|
|
4
|
-
import { Loader2, RotateCcw, MessageSquare, X } from "lucide-react";
|
|
5
|
-
import { useEditContext } from "../editor/client/editContext";
|
|
6
|
-
import { AiProfile, loadAiProfiles } from "../editor/services/aiService";
|
|
7
|
-
import { Agent, getActiveAgents, closeAgent } from "../editor/services/agentService";
|
|
8
|
-
import { AgentTerminal } from "../editor/ai/AgentTerminal";
|
|
9
|
-
import { cn } from "../lib/utils";
|
|
10
|
-
import { Button } from "../components/ui/button";
|
|
11
|
-
|
|
12
|
-
interface ParheliaAssistantChatProps {
|
|
13
|
-
className?: string;
|
|
14
|
-
externalAgent?: Agent | null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const ParheliaAssistantChat: React.FC<ParheliaAssistantChatProps> = ({
|
|
18
|
-
className,
|
|
19
|
-
externalAgent,
|
|
20
|
-
}) => {
|
|
21
|
-
const editContext = useEditContext();
|
|
22
|
-
const [profile, setProfile] = useState<AiProfile | null>(null);
|
|
23
|
-
const [profiles, setProfiles] = useState<AiProfile[]>([]);
|
|
24
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
25
|
-
const [agent, setAgent] = useState<Agent | null>(null);
|
|
26
|
-
const [agentKey, setAgentKey] = useState(0); // Force re-render of AgentTerminal
|
|
27
|
-
const [isTerminalVisible, setIsTerminalVisible] = useState(false);
|
|
28
|
-
|
|
29
|
-
// Create a new agent
|
|
30
|
-
const createNewAgent = useCallback((selectedProfile: AiProfile) => {
|
|
31
|
-
const agentDisplayName = selectedProfile.agentName || "Parhelia";
|
|
32
|
-
const agentId = crypto.randomUUID();
|
|
33
|
-
|
|
34
|
-
const newAgent: Agent = {
|
|
35
|
-
status: "new",
|
|
36
|
-
id: agentId,
|
|
37
|
-
name: agentDisplayName,
|
|
38
|
-
updatedDate: new Date().toISOString(),
|
|
39
|
-
userId: "",
|
|
40
|
-
profileId: selectedProfile.id,
|
|
41
|
-
profileName: selectedProfile.name,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
setAgent(newAgent);
|
|
45
|
-
return newAgent;
|
|
46
|
-
}, []);
|
|
47
|
-
|
|
48
|
-
// Load AI profiles on mount
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
const loadProfile = async () => {
|
|
51
|
-
try {
|
|
52
|
-
setIsLoading(true);
|
|
53
|
-
const profileList = await loadAiProfiles();
|
|
54
|
-
|
|
55
|
-
// Try to find Parhelia profile with multiple strategies
|
|
56
|
-
let assistantProfile: AiProfile | undefined;
|
|
57
|
-
|
|
58
|
-
// Strategy 1: Look for exact ID match
|
|
59
|
-
assistantProfile = profileList.find(
|
|
60
|
-
(p) => p.id === "7d45ab97-f253-4915-8b32-f9e8c762c5e9",
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
// Strategy 2: Look for exact name match (case-insensitive)
|
|
64
|
-
if (!assistantProfile) {
|
|
65
|
-
assistantProfile = profileList.find(
|
|
66
|
-
(p) => p.name.toLowerCase() === "parhelia",
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Strategy 3: Look for profile containing "parhelia" in name or displayTitle
|
|
71
|
-
if (!assistantProfile) {
|
|
72
|
-
assistantProfile = profileList.find(
|
|
73
|
-
(p) =>
|
|
74
|
-
p.name.toLowerCase().includes("parhelia") ||
|
|
75
|
-
p.displayTitle?.toLowerCase().includes("parhelia"),
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Strategy 4: Fallback to first available profile
|
|
80
|
-
const selectedProfile = assistantProfile || profileList[0];
|
|
81
|
-
|
|
82
|
-
if (selectedProfile) {
|
|
83
|
-
setProfile(selectedProfile);
|
|
84
|
-
setProfiles(profileList);
|
|
85
|
-
|
|
86
|
-
// Try to find latest idle Parhelia agent
|
|
87
|
-
try {
|
|
88
|
-
const response = await getActiveAgents({ limit: 50 });
|
|
89
|
-
|
|
90
|
-
// Filter for Parhelia agents (by profileId) that are idle/completed
|
|
91
|
-
// Exclude agents that are "running" (1) or "waitingForApproval" (2) to avoid showing stuck dancing dots
|
|
92
|
-
const parheliaAgents = response.agents.filter(
|
|
93
|
-
(a) =>
|
|
94
|
-
a.profileId === selectedProfile.id &&
|
|
95
|
-
a.status !== "running" &&
|
|
96
|
-
a.status !== 1 &&
|
|
97
|
-
a.status !== "waitingForApproval" &&
|
|
98
|
-
a.status !== 2,
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (parheliaAgents.length > 0 && parheliaAgents[0]) {
|
|
102
|
-
// Use the most recent idle agent (agents are typically ordered by updatedDate)
|
|
103
|
-
const latestAgent = parheliaAgents[0];
|
|
104
|
-
setAgent(latestAgent);
|
|
105
|
-
// Show terminal immediately for existing agents
|
|
106
|
-
setIsTerminalVisible(true);
|
|
107
|
-
} else {
|
|
108
|
-
// No existing idle agent, create new one
|
|
109
|
-
createNewAgent(selectedProfile);
|
|
110
|
-
// Terminal stays hidden for new agents
|
|
111
|
-
}
|
|
112
|
-
} catch (err) {
|
|
113
|
-
// Failed to fetch active agents, create new one
|
|
114
|
-
createNewAgent(selectedProfile);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
} catch (err) {
|
|
118
|
-
console.error("Failed to load AI profile:", err);
|
|
119
|
-
} finally {
|
|
120
|
-
setIsLoading(false);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
loadProfile();
|
|
125
|
-
}, [createNewAgent]);
|
|
126
|
-
|
|
127
|
-
// Handle external agent selection
|
|
128
|
-
useEffect(() => {
|
|
129
|
-
if (externalAgent) {
|
|
130
|
-
setAgent(externalAgent);
|
|
131
|
-
setAgentKey((prev) => prev + 1);
|
|
132
|
-
setIsTerminalVisible(true);
|
|
133
|
-
}
|
|
134
|
-
}, [externalAgent]);
|
|
135
|
-
|
|
136
|
-
// Handle revealing the terminal when user clicks into chat
|
|
137
|
-
const handleRevealTerminal = useCallback(() => {
|
|
138
|
-
startTransition(() => {
|
|
139
|
-
setIsTerminalVisible(true);
|
|
140
|
-
});
|
|
141
|
-
}, []);
|
|
142
|
-
|
|
143
|
-
// Handle start over
|
|
144
|
-
const handleStartOver = useCallback(async () => {
|
|
145
|
-
if (!profile || !agent) return;
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
// Close the current agent first
|
|
149
|
-
await closeAgent(agent.id);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
console.error("Failed to close agent:", error);
|
|
152
|
-
// Continue anyway to create new agent
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Create new agent and force re-render
|
|
156
|
-
createNewAgent(profile);
|
|
157
|
-
setAgentKey((prev) => prev + 1);
|
|
158
|
-
// Keep terminal visible when starting over
|
|
159
|
-
}, [profile, agent, createNewAgent]);
|
|
160
|
-
|
|
161
|
-
// Handle close
|
|
162
|
-
const handleClose = useCallback(async () => {
|
|
163
|
-
if (!agent) return;
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
await closeAgent(agent.id);
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error("Failed to close agent:", error);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Hide the terminal
|
|
172
|
-
setIsTerminalVisible(false);
|
|
173
|
-
}, [agent]);
|
|
174
|
-
|
|
175
|
-
if (isLoading) {
|
|
176
|
-
return (
|
|
177
|
-
<div
|
|
178
|
-
className={cn(
|
|
179
|
-
"flex items-center justify-center rounded-lg bg-white p-8 shadow-md",
|
|
180
|
-
className,
|
|
181
|
-
)}
|
|
182
|
-
>
|
|
183
|
-
<Loader2 className="h-6 w-6 animate-spin text-gray-400" />
|
|
184
|
-
</div>
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!agent || !profile) {
|
|
189
|
-
return (
|
|
190
|
-
<div
|
|
191
|
-
className={cn(
|
|
192
|
-
"flex items-center justify-center rounded-lg bg-white p-8 shadow-md",
|
|
193
|
-
className,
|
|
194
|
-
)}
|
|
195
|
-
>
|
|
196
|
-
<p className="text-sm text-gray-500">
|
|
197
|
-
Assistant unavailable. Please try again later.
|
|
198
|
-
</p>
|
|
199
|
-
</div>
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<div
|
|
205
|
-
onClick={handleRevealTerminal}
|
|
206
|
-
className={cn(
|
|
207
|
-
"flex flex-col overflow-hidden rounded-lg bg-white shadow-md",
|
|
208
|
-
!isTerminalVisible && "cursor-pointer",
|
|
209
|
-
className,
|
|
210
|
-
)}
|
|
211
|
-
>
|
|
212
|
-
{/* Header with Start Over and Close buttons */}
|
|
213
|
-
<div className="flex items-center justify-between border-b border-gray-200 px-4 py-2">
|
|
214
|
-
<div className="text-sm font-medium text-gray-700">
|
|
215
|
-
Chat with {agent.name || profile.agentName || "Parhelia"}
|
|
216
|
-
</div>
|
|
217
|
-
{isTerminalVisible && (
|
|
218
|
-
<div className="flex items-center gap-1">
|
|
219
|
-
<Button
|
|
220
|
-
variant="ghost"
|
|
221
|
-
size="sm"
|
|
222
|
-
onClick={handleStartOver}
|
|
223
|
-
className="h-7 gap-1.5 text-xs"
|
|
224
|
-
>
|
|
225
|
-
<RotateCcw className="h-3.5 w-3.5" strokeWidth={1} />
|
|
226
|
-
Start Over
|
|
227
|
-
</Button>
|
|
228
|
-
<Button
|
|
229
|
-
variant="ghost"
|
|
230
|
-
size="sm"
|
|
231
|
-
onClick={handleClose}
|
|
232
|
-
className="h-7 w-7 p-0"
|
|
233
|
-
aria-label="Close"
|
|
234
|
-
>
|
|
235
|
-
<X className="h-4 w-4" strokeWidth={1.5} />
|
|
236
|
-
</Button>
|
|
237
|
-
</div>
|
|
238
|
-
)}
|
|
239
|
-
</div>
|
|
240
|
-
|
|
241
|
-
{/* Agent Terminal or Placeholder */}
|
|
242
|
-
<div className="flex-1 overflow-hidden">
|
|
243
|
-
{isTerminalVisible && (
|
|
244
|
-
|
|
245
|
-
<ViewTransition enter="slide-fade-in">
|
|
246
|
-
<div className="h-[600px]">
|
|
247
|
-
<AgentTerminal
|
|
248
|
-
|
|
249
|
-
key={agentKey}
|
|
250
|
-
agentStub={agent}
|
|
251
|
-
initialMetadata={{
|
|
252
|
-
profile: profile.name,
|
|
253
|
-
additionalData: {
|
|
254
|
-
profileId: profile.id,
|
|
255
|
-
profileName: profile.name,
|
|
256
|
-
},
|
|
257
|
-
}}
|
|
258
|
-
profiles={profiles}
|
|
259
|
-
isActive={true}
|
|
260
|
-
compact={true}
|
|
261
|
-
hideContext={true}
|
|
262
|
-
hideBottomControls={true}
|
|
263
|
-
hideGreeting={false}
|
|
264
|
-
className="h-full"
|
|
265
|
-
initialPrompt={agent.status === "new" ? "" : undefined}
|
|
266
|
-
/>
|
|
267
|
-
</div>
|
|
268
|
-
</ViewTransition>
|
|
269
|
-
) }
|
|
270
|
-
</div>
|
|
271
|
-
</div>
|
|
272
|
-
);
|
|
273
|
-
};
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { useState, useEffect } from "react";
|
|
4
|
-
import { MessageSquare } from "lucide-react";
|
|
5
|
-
import { AiProfile, loadAiProfiles } from "../editor/services/aiService";
|
|
6
|
-
import { Agent, getAgentsGrouped } from "../editor/services/agentService";
|
|
7
|
-
import { useEditContext } from "../editor/client/editContext";
|
|
8
|
-
import { Button } from "../components/ui/button";
|
|
9
|
-
|
|
10
|
-
interface RecentAgentsProps {
|
|
11
|
-
onSelectAgent?: (agent: Agent) => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const RecentAgents: React.FC<RecentAgentsProps> = ({ onSelectAgent }) => {
|
|
15
|
-
const editContext = useEditContext();
|
|
16
|
-
const [agents, setAgents] = useState<Agent[]>([]);
|
|
17
|
-
const [profile, setProfile] = useState<AiProfile | null>(null);
|
|
18
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
19
|
-
const [showExpanded, setShowExpanded] = useState(false);
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
const loadData = async () => {
|
|
23
|
-
try {
|
|
24
|
-
setIsLoading(true);
|
|
25
|
-
|
|
26
|
-
// Load Parhelia profile
|
|
27
|
-
const profileList = await loadAiProfiles();
|
|
28
|
-
let assistantProfile: AiProfile | undefined;
|
|
29
|
-
|
|
30
|
-
assistantProfile = profileList.find(
|
|
31
|
-
(p) => p.id === "7d45ab97-f253-4915-8b32-f9e8c762c5e9",
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
if (!assistantProfile) {
|
|
35
|
-
assistantProfile = profileList.find(
|
|
36
|
-
(p) => p.name.toLowerCase() === "parhelia",
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!assistantProfile) {
|
|
41
|
-
assistantProfile = profileList.find(
|
|
42
|
-
(p) =>
|
|
43
|
-
p.name.toLowerCase().includes("parhelia") ||
|
|
44
|
-
p.displayTitle?.toLowerCase().includes("parhelia"),
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const selectedProfile = assistantProfile || profileList[0] || null;
|
|
49
|
-
setProfile(selectedProfile);
|
|
50
|
-
|
|
51
|
-
// Fetch all agents (both active and closed) for this profile
|
|
52
|
-
if (selectedProfile) {
|
|
53
|
-
const response = await getAgentsGrouped();
|
|
54
|
-
|
|
55
|
-
// Combine active agents with closed agents
|
|
56
|
-
const allAgents: Agent[] = [...response.activeAgents];
|
|
57
|
-
|
|
58
|
-
// Add closed agents from all profiles
|
|
59
|
-
response.closedAgentsByProfile.forEach(group => {
|
|
60
|
-
allAgents.push(...group.agents);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Filter for Parhelia agents only
|
|
64
|
-
const parheliaAgents = allAgents.filter(
|
|
65
|
-
(a) => a.profileId === selectedProfile.id
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
// Take the most recent 15 agents
|
|
69
|
-
setAgents(parheliaAgents.slice(0, 15));
|
|
70
|
-
}
|
|
71
|
-
} catch (err) {
|
|
72
|
-
console.error("Failed to load agents:", err);
|
|
73
|
-
} finally {
|
|
74
|
-
setIsLoading(false);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
loadData();
|
|
79
|
-
}, []);
|
|
80
|
-
|
|
81
|
-
const handleOpenAgent = (agent: Agent) => {
|
|
82
|
-
// Use the callback to set the selected agent in the parent component
|
|
83
|
-
if (onSelectAgent) {
|
|
84
|
-
onSelectAgent(agent);
|
|
85
|
-
// Scroll to the top to show the chat interface
|
|
86
|
-
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const handleShowAll = () => {
|
|
91
|
-
editContext?.switchView("agents-overview");
|
|
92
|
-
editContext?.setShowAgentsPanel?.(true);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
if (isLoading || agents.length === 0) {
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Show 3 agents by default, or 15 when expanded
|
|
100
|
-
const displayedAgents = showExpanded ? agents : agents.slice(0, 3);
|
|
101
|
-
const hasMoreAgents = agents.length > 3;
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<div className="w-full">
|
|
105
|
-
<h2 className="mb-3 text-center text-sm font-medium text-gray-700">
|
|
106
|
-
Recent Conversations
|
|
107
|
-
</h2>
|
|
108
|
-
<div className="space-y-1.5">
|
|
109
|
-
{displayedAgents.map((agent) => (
|
|
110
|
-
<button
|
|
111
|
-
key={agent.id}
|
|
112
|
-
onClick={() => handleOpenAgent(agent)}
|
|
113
|
-
className="flex w-full items-center gap-2 px-2 py-1.5 text-left transition-colors hover:bg-white/50 rounded"
|
|
114
|
-
>
|
|
115
|
-
<MessageSquare className="h-3.5 w-3.5 flex-shrink-0 text-gray-400" strokeWidth={1.5} />
|
|
116
|
-
<div className="flex-1 min-w-0">
|
|
117
|
-
<span className="text-xs text-gray-700 truncate block">
|
|
118
|
-
{agent.name}
|
|
119
|
-
</span>
|
|
120
|
-
</div>
|
|
121
|
-
</button>
|
|
122
|
-
))}
|
|
123
|
-
</div>
|
|
124
|
-
|
|
125
|
-
{hasMoreAgents && (
|
|
126
|
-
<div className="mt-3 flex gap-2">
|
|
127
|
-
{!showExpanded ? (
|
|
128
|
-
<Button
|
|
129
|
-
variant="outline"
|
|
130
|
-
size="sm"
|
|
131
|
-
onClick={() => setShowExpanded(true)}
|
|
132
|
-
className="flex-1 text-xs"
|
|
133
|
-
>
|
|
134
|
-
Show More
|
|
135
|
-
</Button>
|
|
136
|
-
) : (
|
|
137
|
-
<Button
|
|
138
|
-
variant="outline"
|
|
139
|
-
size="sm"
|
|
140
|
-
onClick={handleShowAll}
|
|
141
|
-
className="flex-1 text-xs"
|
|
142
|
-
>
|
|
143
|
-
Show All
|
|
144
|
-
</Button>
|
|
145
|
-
)}
|
|
146
|
-
</div>
|
|
147
|
-
)}
|
|
148
|
-
</div>
|
|
149
|
-
);
|
|
150
|
-
};
|
|
151
|
-
|