All files / web/src/hooks use-agent-unready-skills.ts

100% Statements 49/49
76.92% Branches 10/13
100% Functions 3/3
100% Lines 49/49

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  1x 1x 1x                                     1x 53x 53x   53x 53x 53x 33x 33x 33x 53x 53x 53x     53x 53x 53x 6x     6x 6x 11x 11x 11x 11x   11x 11x 11x 11x 11x 6x 6x   6x 6x 53x 53x 53x     53x 53x 11x 11x 11x 53x   53x 53x 53x 53x 53x 53x  
import type { Agent } from '@shared/types/data';
import { isSkillReady } from '@shared/utils/skill-validation';
import { useQuery } from '@tanstack/react-query';
import {
  getSkillEvaluations,
  getSkillModels,
  getSkills,
} from '@web/api/v1/super-agents/skills';
 
export interface UseAgentUnreadySkillsResult {
  hasUnreadySkills: boolean;
  unreadySkillsCount: number;
  isLoading: boolean;
}
 
/**
 * Hook to check if an agent has any skills that are not ready.
 * A skill is not ready if it's missing models or evaluations (when optimization is enabled).
 *
 * @param agent - The agent to check
 * @returns Result with unready skills status and count
 */
export function useAgentUnreadySkills(
  agent: Agent | null | undefined,
): UseAgentUnreadySkillsResult {
  // Fetch all skills for the agent
  const { data: skills = [], isLoading: isLoadingSkills } = useQuery({
    queryKey: ['agent-unready-skills', agent?.id],
    queryFn: async () => {
      if (!agent) return [];
      return await getSkills({ agent_id: agent.id });
    },
    enabled: !!agent,
    staleTime: 30 * 1000, // Cache for 30 seconds
  });
 
  // Fetch models and evaluations for each skill
  const { data: skillsData = [], isLoading: isLoadingSkillsData } = useQuery({
    queryKey: ['agent-unready-skills-data', agent?.id, skills.map((s) => s.id)],
    queryFn: async () => {
      if (!agent || skills.length === 0) return [];
 
      // Fetch models and evaluations for all skills in parallel
      const skillsWithData = await Promise.all(
        skills.map(async (skill) => {
          const [models, evaluations] = await Promise.all([
            getSkillModels(skill.id),
            getSkillEvaluations(skill.id),
          ]);
 
          return {
            skill,
            modelsCount: models.length,
            evaluationsCount: evaluations.length,
          };
        }),
      );
 
      return skillsWithData;
    },
    enabled: !!agent && skills.length > 0,
    staleTime: 30 * 1000, // Cache for 30 seconds
  });
 
  // Count unready skills
  const unreadySkillsCount = skillsData.filter(
    ({ skill, modelsCount, evaluationsCount }) => {
      const optimize = skill.optimize ?? false;
      return !isSkillReady(modelsCount, evaluationsCount, optimize);
    },
  ).length;
 
  return {
    hasUnreadySkills: unreadySkillsCount > 0,
    unreadySkillsCount,
    isLoading: isLoadingSkills || isLoadingSkillsData,
  };
}