|
1 | 1 | import React, { useState } from 'react'; |
2 | | -import { Robot, Code, ChartBar, TerminalWindow, Cpu, Books, SidebarSimple } from '@phosphor-icons/react'; |
| 2 | +import { Robot, Code, ChartBar, TerminalWindow, Cpu, Books, SidebarSimple, CircleNotch, CheckCircle, XCircle } from '@phosphor-icons/react'; |
3 | 3 | import { cn } from '@/lib/utils'; |
4 | 4 | import { useUIStore } from '@/stores/useUIStore'; |
| 5 | +import { useAgentStore } from '@/stores/useAgentStore'; |
| 6 | +import { AGENT_LABELS } from '@/types'; |
5 | 7 |
|
6 | 8 | type Tab = 'agents' | 'skills' | 'metrics'; |
7 | 9 |
|
8 | 10 | export const RightSidebar: React.FC = () => { |
9 | 11 | const [activeTab, setActiveTab] = useState<Tab>('agents'); |
10 | 12 | const toggleRightSidebar = useUIStore((s) => s.toggleRightSidebar); |
| 13 | + const agentRuns = useAgentStore((s) => s.agentRuns); |
11 | 14 |
|
12 | 15 | const tabs = [ |
13 | 16 | { id: 'agents' as Tab, icon: Robot, label: 'Agents' }, |
@@ -52,13 +55,54 @@ export const RightSidebar: React.FC = () => { |
52 | 55 | <Cpu size={14} weight="duotone" /> |
53 | 56 | Active Agents |
54 | 57 | </h3> |
55 | | - <div className="p-4 rounded-xl border border-[var(--border)] bg-[var(--surface-2)]/50 text-center space-y-2"> |
56 | | - <div className="w-10 h-10 rounded-full bg-[var(--surface)] border border-[var(--border)] flex items-center justify-center mx-auto"> |
57 | | - <TerminalWindow size={20} weight="duotone" className="text-[var(--text)]" /> |
| 58 | + {agentRuns.length === 0 ? ( |
| 59 | + <div className="p-4 rounded-xl border border-[var(--border)] bg-[var(--surface-2)]/50 text-center space-y-2"> |
| 60 | + <div className="w-10 h-10 rounded-full bg-[var(--surface)] border border-[var(--border)] flex items-center justify-center mx-auto"> |
| 61 | + <TerminalWindow size={20} weight="duotone" className="text-[var(--text)]" /> |
| 62 | + </div> |
| 63 | + <p className="text-xs font-medium">No agents running</p> |
| 64 | + <p className="text-[10px] text-[var(--text-muted)]">Spawn an agent from the chat to see progress here.</p> |
58 | 65 | </div> |
59 | | - <p className="text-xs font-medium">No agents running</p> |
60 | | - <p className="text-[10px] text-[var(--text-muted)]">Spawn an agent from the chat to see progress here.</p> |
61 | | - </div> |
| 66 | + ) : ( |
| 67 | + <div className="space-y-2"> |
| 68 | + {agentRuns.map((run) => ( |
| 69 | + <div |
| 70 | + key={run.id} |
| 71 | + className="p-3 rounded-lg border border-[var(--border)] bg-[var(--surface-2)]/30 space-y-2" |
| 72 | + > |
| 73 | + <div className="flex items-center justify-between"> |
| 74 | + <div className="flex items-center gap-2"> |
| 75 | + {run.status === 'running' && ( |
| 76 | + <CircleNotch size={14} weight="bold" className="text-[var(--accent)] animate-spin" /> |
| 77 | + )} |
| 78 | + {run.status === 'completed' && ( |
| 79 | + <CheckCircle size={14} weight="fill" className="text-green-500" /> |
| 80 | + )} |
| 81 | + {run.status === 'failed' && ( |
| 82 | + <XCircle size={14} weight="fill" className="text-red-500" /> |
| 83 | + )} |
| 84 | + <span className="text-xs font-medium text-[var(--text)]"> |
| 85 | + {AGENT_LABELS[run.agentType as keyof typeof AGENT_LABELS] || run.agentType} |
| 86 | + </span> |
| 87 | + </div> |
| 88 | + <span className="text-[10px] text-[var(--text-subtle)] uppercase tracking-wider"> |
| 89 | + {run.status} |
| 90 | + </span> |
| 91 | + </div> |
| 92 | + {run.toolCalls.length > 0 && ( |
| 93 | + <div className="text-[10px] text-[var(--text-muted)]"> |
| 94 | + {run.toolCalls.filter(tc => tc.status === 'completed').length}/{run.toolCalls.length} tools completed |
| 95 | + </div> |
| 96 | + )} |
| 97 | + {run.streamingText && run.status === 'running' && ( |
| 98 | + <div className="text-[10px] text-[var(--text-muted)] truncate"> |
| 99 | + {run.streamingText.slice(0, 60)}... |
| 100 | + </div> |
| 101 | + )} |
| 102 | + </div> |
| 103 | + ))} |
| 104 | + </div> |
| 105 | + )} |
62 | 106 | </div> |
63 | 107 | )} |
64 | 108 |
|
|
0 commit comments