AkurAI Build
Menu

popagent

public

Latest change 4565eb356975518dfc0202eab29b56dff51e8f71 - add deterministic agent health validation by AkurAI Build

import type { AgentSettings, AgentSkill } from "./api-types";

export type AgentHealthFinding = {
  severity: "error" | "warning";
  code: string;
  agentId: string;
  skillId?: string;
  message: string;
};

export type AgentHealthReport = {
  status: "ok" | "warning" | "error";
  checkedAt: string;
  summary: { agents: number; skills: number; errors: number; warnings: number };
  findings: AgentHealthFinding[];
};

export function validateAgentHealth(
  agents: AgentSettings[],
  skills: AgentSkill[],
  checkedAt = new Date().toISOString(),
): AgentHealthReport {
  const findings: AgentHealthFinding[] = [];
  const agentIds = new Set(agents.map(({ id }) => id));

  for (const agent of agents) {
    if (new Set(agent.tools).size !== agent.tools.length) findings.push({
      severity: "error", code: "duplicate-agent-tool", agentId: agent.id,
      message: "Agent has duplicate tool assignments.",
    });
  }

  for (const skill of skills) {
    if (!agentIds.has(skill.agentId)) findings.push({
      severity: "error", code: "orphaned-skill", agentId: skill.agentId, skillId: skill.id,
      message: "Skill references an unknown agent.",
    });
    if (skill.name.endsWith("-practice")) findings.push({
      severity: "warning", code: "generic-practice-skill", agentId: skill.agentId, skillId: skill.id,
      message: "Generic practice skill duplicates the shared agent execution contract.",
    });
  }

  for (const agent of agents) {
    const agentSkills = skills.filter((skill) => skill.agentId === agent.id && skill.enabled);
    const seen = new Set<string>();
    for (const skill of agentSkills) {
      if (seen.has(skill.name)) findings.push({
        severity: "error", code: "duplicate-skill-name", agentId: agent.id, skillId: skill.id,
        message: `Enabled skill name is duplicated: ${skill.name}.`,
      });
      seen.add(skill.name);
    }
    if (agentSkills.length > 12) findings.push({
      severity: "warning", code: "excessive-enabled-skills", agentId: agent.id,
      message: `Agent has ${agentSkills.length} enabled skills; narrow its selection surface.`,
    });
  }

  findings.sort((left, right) =>
    (left.severity === right.severity ? 0 : left.severity === "error" ? -1 : 1)
    || left.code.localeCompare(right.code)
    || left.agentId.localeCompare(right.agentId)
    || (left.skillId ?? "").localeCompare(right.skillId ?? ""));
  const errors = findings.filter(({ severity }) => severity === "error").length;
  const warnings = findings.length - errors;
  return {
    status: errors ? "error" : warnings ? "warning" : "ok",
    checkedAt,
    summary: { agents: agents.length, skills: skills.length, errors, warnings },
    findings,
  };
}