Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 1x 1x 1x 1x 1x 1x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 6x 24x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x | import type { Agent } from '@shared/types/data';
import { Badge } from '@web/components/ui/badge';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@web/components/ui/tooltip';
import { useAgentUnreadySkills } from '@web/hooks/use-agent-unready-skills';
import { useAgentValidation } from '@web/hooks/use-agent-validation';
import { AlertCircle } from 'lucide-react';
import type { ReactElement } from 'react';
interface AgentStatusIndicatorProps {
agent: Agent;
/** The size of the icon */
size?: 'sm' | 'md' | 'lg';
/** Which side the tooltip should appear on */
tooltipSide?: 'top' | 'right' | 'bottom' | 'left';
/** Whether to show as a badge or just an icon */
variant?: 'icon' | 'badge';
}
/**
* Displays an indicator when an agent is not ready (missing skills or has unready skills).
* Shows nothing when the agent is ready or loading.
*/
export function AgentStatusIndicator({
agent,
size = 'sm',
tooltipSide = 'right',
variant = 'icon',
}: AgentStatusIndicatorProps): ReactElement | null {
const { isReady, missingRequirements, isLoading } = useAgentValidation(agent);
const {
hasUnreadySkills,
unreadySkillsCount,
isLoading: isLoadingUnreadySkills,
} = useAgentUnreadySkills(agent);
if (isLoading || isLoadingUnreadySkills) return null;
// Show indicator if agent is missing skills OR has unready skills
if (isReady && !hasUnreadySkills) return null;
// Combine requirements
const allRequirements = [...missingRequirements];
if (hasUnreadySkills) {
allRequirements.push(
`${unreadySkillsCount} skill${unreadySkillsCount > 1 ? 's are' : ' is'} not ready (missing models or evaluations)`,
);
}
const iconSizeClass = {
sm: 'size-3',
md: 'size-3.5',
lg: 'size-4',
}[size];
if (variant === 'badge') {
return (
<Tooltip>
<TooltipTrigger asChild>
<Badge className="gap-1.5 bg-orange-100 dark:bg-orange-950 text-orange-800 dark:text-orange-200 hover:bg-orange-200 dark:hover:bg-orange-900 border-orange-200 dark:border-orange-800">
<AlertCircle className={iconSizeClass} />
Not Ready
</Badge>
</TooltipTrigger>
<TooltipContent side={tooltipSide} className="max-w-xs py-2">
<AgentStatusTooltipContent missingRequirements={allRequirements} />
</TooltipContent>
</Tooltip>
);
}
return (
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex shrink-0">
<AlertCircle
className={`${iconSizeClass} text-orange-800 dark:text-orange-200`}
/>
</span>
</TooltipTrigger>
<TooltipContent side={tooltipSide} className="max-w-xs py-2">
<AgentStatusTooltipContent missingRequirements={allRequirements} />
</TooltipContent>
</Tooltip>
);
}
/**
* Reusable tooltip content for agent status indicators
*/
function AgentStatusTooltipContent({
missingRequirements,
}: {
missingRequirements: string[];
}): ReactElement {
return (
<div className="space-y-1.5">
<p className="font-semibold m-0">Agent not ready</p>
<ul className="text-xs list-disc pl-4 space-y-0.5">
{missingRequirements.map((req) => (
<li key={req}>{req}</li>
))}
</ul>
</div>
);
}
|