import { useMemo } from 'react'; import { Activity, Bot, Sparkles } from 'lucide-react'; import { buildAgentActivityRows, formatAgentActivityLabel, isAgentActivityActive, isAgentActivityCompleted, type SessionActivityState, } from '@renderer/lib/sessionActivity'; import { inferProvider, type ModelProvider } from '@shared/domain/models'; import type { PatternDefinition } from '@shared/domain/pattern'; import type { SessionRecord } from '@shared/domain/session'; const providerStyles: Record = { openai: { bg: 'bg-emerald-500/15', text: 'text-emerald-400', label: 'AI' }, anthropic: { bg: 'bg-orange-500/15', text: 'text-orange-400', label: 'A' }, google: { bg: 'bg-blue-500/15', text: 'text-blue-400', label: 'G' }, }; function formatModel(model: string): string { return model.replace(/-/g, '\u2011'); } function formatEffort(effort: string | undefined): string | undefined { if (!effort) return undefined; const labels: Record = { low: 'Low effort', medium: 'Medium effort', high: 'High effort', xhigh: 'Max effort', }; return labels[effort] ?? effort; } interface ActivityPanelProps { activity?: SessionActivityState; pattern: PatternDefinition; session: SessionRecord; } export function ActivityPanel({ activity, pattern, session }: ActivityPanelProps) { const activityRows = useMemo( () => buildAgentActivityRows(activity, pattern.agents), [activity, pattern.agents], ); const isBusy = session.status === 'running'; return (
{/* Header — top padding clears the title bar overlay zone */}
Activity {isBusy && }
{/* Agent cards */}
{activityRows.map((row, index) => { const agent = pattern.agents[index]; const isActive = isAgentActivityActive(row.activity); const isCompleted = isAgentActivityCompleted(row.activity); return (
{/* Agent name + status dot */}
{row.agentName}
{/* Model + reasoning effort badges */} {agent && (
{(() => { const prov = inferProvider(agent.model); if (prov) { const s = providerStyles[prov]; return ( {s.label} ); } return null; })()} {formatModel(agent.model)} {agent.reasoningEffort && ( {formatEffort(agent.reasoningEffort)} )}
)} {/* Description */} {agent?.description && (

{agent.description}

)} {/* Activity status */}
{formatAgentActivityLabel(row.activity)}
); })}
{activityRows.length === 0 && (

No agents configured

)}
); }