Spaces:
No application file
No application file
| /** | |
| * Agent Configuration Panel | |
| * UI for viewing and managing AI agents in the registry | |
| */ | |
| 'use client'; | |
| import { useState } from 'react'; | |
| import { useAgentRegistry } from '@/lib/orchestration/registry/store'; | |
| import { Button } from '@/components/ui/button'; | |
| import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; | |
| import { Badge } from '@/components/ui/badge'; | |
| import { ScrollArea } from '@/components/ui/scroll-area'; | |
| import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; | |
| import { PlusIcon, Trash2Icon, EditIcon } from 'lucide-react'; | |
| export function AgentConfigPanel() { | |
| const { listAgents, deleteAgent } = useAgentRegistry(); | |
| const agents = listAgents(); | |
| const [selectedAgent, setSelectedAgent] = useState<string | null>(null); | |
| const handleDelete = (agentId: string) => { | |
| if (confirm('确定要删除这个智能体吗?')) { | |
| deleteAgent(agentId); | |
| if (selectedAgent === agentId) { | |
| setSelectedAgent(null); | |
| } | |
| } | |
| }; | |
| return ( | |
| <div className="flex flex-col h-full p-4 gap-4"> | |
| <div className="flex items-center justify-between"> | |
| <div> | |
| <h2 className="text-lg font-semibold">智能体配置</h2> | |
| <p className="text-sm text-muted-foreground">管理课堂讨论的AI智能体</p> | |
| </div> | |
| <Button size="sm" variant="outline"> | |
| <PlusIcon className="w-4 h-4 mr-2" /> | |
| 新建 | |
| </Button> | |
| </div> | |
| <ScrollArea className="flex-1"> | |
| <div className="space-y-3"> | |
| {agents.map((agent) => ( | |
| <Card | |
| key={agent.id} | |
| className={`cursor-pointer transition-colors ${ | |
| selectedAgent === agent.id ? 'border-primary' : '' | |
| }`} | |
| onClick={() => setSelectedAgent(agent.id)} | |
| > | |
| <CardHeader className="p-4"> | |
| <div className="flex items-start justify-between"> | |
| <div className="flex items-center gap-3"> | |
| <Avatar | |
| className="size-10" | |
| style={{ | |
| borderColor: agent.color, | |
| borderWidth: 2, | |
| }} | |
| > | |
| <AvatarImage src={agent.avatar} alt={agent.name} /> | |
| <AvatarFallback | |
| style={{ | |
| backgroundColor: `${agent.color}20`, | |
| color: agent.color, | |
| }} | |
| > | |
| {agent.name.charAt(0)} | |
| </AvatarFallback> | |
| </Avatar> | |
| <div> | |
| <CardTitle className="text-base">{agent.name}</CardTitle> | |
| <CardDescription className="text-sm">{agent.role}</CardDescription> | |
| </div> | |
| </div> | |
| <div className="flex gap-2"> | |
| <Badge variant="secondary" className="text-xs"> | |
| 优先级 {agent.priority} | |
| </Badge> | |
| {agent.isDefault && ( | |
| <Badge variant="outline" className="text-xs"> | |
| 默认 | |
| </Badge> | |
| )} | |
| </div> | |
| </div> | |
| </CardHeader> | |
| <CardContent className="p-4 pt-0"> | |
| <div className="space-y-2"> | |
| <div> | |
| <p className="text-xs font-medium text-muted-foreground mb-1">能力描述</p> | |
| <p className="text-sm line-clamp-2">{agent.persona}</p> | |
| </div> | |
| <div> | |
| <p className="text-xs font-medium text-muted-foreground mb-1"> | |
| 可用动作 ({agent.allowedActions.length}) | |
| </p> | |
| <div className="flex flex-wrap gap-1"> | |
| {agent.allowedActions.slice(0, 3).map((tool) => ( | |
| <Badge key={tool} variant="secondary" className="text-xs"> | |
| {tool} | |
| </Badge> | |
| ))} | |
| {agent.allowedActions.length > 3 && ( | |
| <Badge variant="secondary" className="text-xs"> | |
| +{agent.allowedActions.length - 3} | |
| </Badge> | |
| )} | |
| </div> | |
| </div> | |
| {!agent.isDefault && ( | |
| <div className="flex gap-2 pt-2"> | |
| <Button size="sm" variant="outline" className="flex-1"> | |
| <EditIcon className="w-3 h-3 mr-1" /> | |
| 编辑 | |
| </Button> | |
| <Button | |
| size="sm" | |
| variant="destructive" | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| handleDelete(agent.id); | |
| }} | |
| > | |
| <Trash2Icon className="w-3 h-3" /> | |
| </Button> | |
| </div> | |
| )} | |
| </div> | |
| </CardContent> | |
| </Card> | |
| ))} | |
| </div> | |
| </ScrollArea> | |
| {agents.length === 0 && ( | |
| <div className="flex-1 flex items-center justify-center text-center p-8"> | |
| <div className="max-w-sm"> | |
| <p className="text-muted-foreground mb-4">还没有配置智能体</p> | |
| <Button> | |
| <PlusIcon className="w-4 h-4 mr-2" /> | |
| 创建第一个智能体 | |
| </Button> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |