168 lines
4.4 KiB
Bash
168 lines
4.4 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
#
|
||
|
|
# Validate agents.json structure and prompt files
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# ./scripts/validate-agents.sh # Validate agents.json
|
||
|
|
# ./scripts/validate-agents.sh --help # Show help
|
||
|
|
#
|
||
|
|
# Checks:
|
||
|
|
# - agents.json is valid JSON
|
||
|
|
# - Each agent has required fields (description, mode, model, prompt, permission)
|
||
|
|
# - All referenced prompt files exist
|
||
|
|
# - All prompt files are non-empty
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||
|
|
|
||
|
|
RED='\033[0;31m'
|
||
|
|
GREEN='\033[0;32m'
|
||
|
|
YELLOW='\033[1;33m'
|
||
|
|
NC='\033[0m'
|
||
|
|
|
||
|
|
usage() {
|
||
|
|
echo "Usage: $0 [OPTIONS]"
|
||
|
|
echo ""
|
||
|
|
echo "Validate agents.json structure and prompt files."
|
||
|
|
echo ""
|
||
|
|
echo "Options:"
|
||
|
|
echo " --help Show this help message"
|
||
|
|
echo ""
|
||
|
|
echo "Validates:"
|
||
|
|
echo " - agents.json is valid JSON"
|
||
|
|
echo " - Each agent has required fields"
|
||
|
|
echo " - All referenced prompt files exist"
|
||
|
|
echo " - All prompt files are non-empty"
|
||
|
|
}
|
||
|
|
|
||
|
|
check_json_valid() {
|
||
|
|
local agents_file="$1"
|
||
|
|
|
||
|
|
if ! python3 -m json.tool "$agents_file" > /dev/null 2>&1; then
|
||
|
|
echo -e "${RED}❌ agents.json is not valid JSON${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e "${GREEN}✅ agents.json is valid JSON${NC}"
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
check_required_fields() {
|
||
|
|
local agents_file="$1"
|
||
|
|
local agent_name="$2"
|
||
|
|
local agent_data="$3"
|
||
|
|
|
||
|
|
local required_fields=("description" "mode" "model" "prompt" "permission")
|
||
|
|
local missing_fields=()
|
||
|
|
|
||
|
|
for field in "${required_fields[@]}"; do
|
||
|
|
if ! echo "$agent_data" | python3 -c "import sys, json; data = json.load(sys.stdin); exit(0 if '$field' in data else 1)" 2>/dev/null; then
|
||
|
|
missing_fields+=("$field")
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
if [[ ${#missing_fields[@]} -gt 0 ]]; then
|
||
|
|
echo -e " ${RED}❌ Missing required fields for '$agent_name': ${missing_fields[*]}${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e " ${GREEN}✅ '$agent_name' has all required fields${NC}"
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
check_prompt_file() {
|
||
|
|
local agent_name="$1"
|
||
|
|
local prompt_ref="$2"
|
||
|
|
|
||
|
|
# Extract filename from {file:./prompts/filename}
|
||
|
|
if [[ ! $prompt_ref =~ \{file:./prompts/([^}]+)\} ]]; then
|
||
|
|
echo -e " ${RED}❌ '$agent_name': Invalid prompt reference format: $prompt_ref${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
local prompt_file="prompts/${BASH_REMATCH[1]}"
|
||
|
|
|
||
|
|
if [[ ! -f "$REPO_ROOT/$prompt_file" ]]; then
|
||
|
|
echo -e " ${RED}❌ '$agent_name': Prompt file not found: $prompt_file${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ ! -s "$REPO_ROOT/$prompt_file" ]]; then
|
||
|
|
echo -e " ${RED}❌ '$agent_name': Prompt file is empty: $prompt_file${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e " ${GREEN}✅ '$agent_name': Prompt file exists and is non-empty ($prompt_file)${NC}"
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
validate_agents() {
|
||
|
|
local agents_file="$REPO_ROOT/agents/agents.json"
|
||
|
|
|
||
|
|
echo -e "${YELLOW}Validating agents.json...${NC}"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [[ ! -f "$agents_file" ]]; then
|
||
|
|
echo -e "${RED}❌ agents.json not found at $agents_file${NC}"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
check_json_valid "$agents_file" || exit 1
|
||
|
|
|
||
|
|
local agent_names
|
||
|
|
agent_names=$(python3 -c "import json; data = json.load(open('$agents_file')); print('\n'.join(data.keys()))")
|
||
|
|
|
||
|
|
local failed=0
|
||
|
|
|
||
|
|
while IFS= read -r agent_name; do
|
||
|
|
[[ -z "$agent_name" ]] && continue
|
||
|
|
|
||
|
|
echo -n " Checking '$agent_name': "
|
||
|
|
|
||
|
|
local agent_data
|
||
|
|
agent_data=$(python3 -c "import json; data = json.load(open('$agents_file')); print(json.dumps(data['$agent_name']))")
|
||
|
|
|
||
|
|
if ! check_required_fields "$agents_file" "$agent_name" "$agent_data"; then
|
||
|
|
((failed++)) || true
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
|
||
|
|
local prompt_ref
|
||
|
|
prompt_ref=$(python3 -c "import json, sys; data = json.load(open('$agents_file')); print(data['$agent_name'].get('prompt', ''))")
|
||
|
|
|
||
|
|
if ! check_prompt_file "$agent_name" "$prompt_ref"; then
|
||
|
|
((failed++)) || true
|
||
|
|
fi
|
||
|
|
|
||
|
|
done <<< "$agent_names"
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [[ $failed -eq 0 ]]; then
|
||
|
|
echo -e "${GREEN}✅ All agents validated successfully!${NC}"
|
||
|
|
exit 0
|
||
|
|
else
|
||
|
|
echo -e "${RED}❌ $failed agent(s) failed validation${NC}"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Main
|
||
|
|
case "${1:-}" in
|
||
|
|
--help|-h)
|
||
|
|
usage
|
||
|
|
exit 0
|
||
|
|
;;
|
||
|
|
"")
|
||
|
|
validate_agents
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo -e "${RED}Unknown option: $1${NC}"
|
||
|
|
echo ""
|
||
|
|
usage
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|