Files
antigravity-skills-reference/skills/skill-sentinel/scripts/analyzers/performance.py
ProgramadorBrasil 61ec71c5c7 feat: add 52 specialized AI agent skills (#217)
New skills covering 10 categories:

**Security & Audit**: 007 (STRIDE/PASTA/OWASP), cred-omega (secrets management)
**AI Personas**: Karpathy, Hinton, Sutskever, LeCun (4 sub-skills), Altman, Musk, Gates, Jobs, Buffett
**Multi-agent Orchestration**: agent-orchestrator, task-intelligence, multi-advisor
**Code Analysis**: matematico-tao (Terence Tao-inspired mathematical code analysis)
**Social & Messaging**: Instagram Graph API, Telegram Bot, WhatsApp Cloud API, social-orchestrator
**Image Generation**: AI Studio (Gemini), Stability AI, ComfyUI Gateway, image-studio router
**Brazilian Domain**: 6 auction specialist modules, 2 legal advisors, auctioneers data scraper
**Product & Growth**: design, invention, monetization, analytics, growth engine
**DevOps & LLM Ops**: Docker/CI-CD/AWS, RAG/embeddings/fine-tuning
**Skill Governance**: installer, sentinel auditor, context management

Each skill includes:
- Standardized YAML frontmatter (name, description, risk, source, tags, tools)
- Structured sections (Overview, When to Use, How it Works, Best Practices)
- Python scripts and reference documentation where applicable
- Cross-platform compatibility (Claude Code, Antigravity, Cursor, Gemini CLI, Codex CLI)

Co-authored-by: ProgramadorBrasil <214873561+ProgramadorBrasil@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:04:07 +01:00

165 lines
6.2 KiB
Python

"""
Analyzer de performance.
Verifica: chamadas API sequenciais, caching, N+1 queries,
connection reuse, retry/backoff, timeouts.
"""
from __future__ import annotations
import re
from pathlib import Path
from typing import Any, Dict, List, Tuple
def analyze(skill_data: Dict[str, Any]) -> Tuple[float, List[Dict[str, Any]]]:
"""Analisa performance de uma skill. Retorna (score, findings)."""
score = 100.0
findings: List[Dict[str, Any]] = []
skill_name = skill_data["name"]
skill_path = Path(skill_data["path"])
has_retry = False
has_timeout = False
has_caching = False
has_connection_pool = False
has_async = False
has_concurrency = False
api_call_files = []
for rel_path in skill_data.get("python_files", []):
filepath = skill_path / rel_path
if not filepath.exists():
continue
try:
source = filepath.read_text(encoding="utf-8", errors="replace")
except OSError:
continue
# Detectar patterns de performance
if re.search(r'(?:retry|backoff|MAX_RETRIES|RETRY_BACKOFF)', source, re.I):
has_retry = True
if re.search(r'(?:timeout|REQUEST_TIMEOUT)', source, re.I):
has_timeout = True
if re.search(r'(?:cache|lru_cache|functools\.cache|_cache)', source, re.I):
has_caching = True
if re.search(r'(?:session|Session\(\)|httpx\.Client)', source, re.I):
has_connection_pool = True
if re.search(r'(?:async\s+def|asyncio|aiohttp|httpx\.AsyncClient)', source):
has_async = True
if re.search(r'(?:concurrent|ThreadPool|ProcessPool|asyncio\.gather|--concurrency)', source, re.I):
has_concurrency = True
# Contar chamadas API (requests.get/post, httpx, etc)
api_calls = len(re.findall(
r'(?:requests\.\w+|httpx\.\w+|self\.\w*(?:get|post|put|delete|patch))\s*\(',
source
))
if api_calls > 0:
api_call_files.append((rel_path, api_calls))
# Detectar N+1 patterns (loop com query SQL dentro)
# Analise linha-a-linha para evitar backtracking em regex DOTALL
lines = source.splitlines()
in_for_loop = False
for line_text in lines:
stripped = line_text.strip()
if stripped.startswith("for ") and stripped.endswith(":"):
in_for_loop = True
elif in_for_loop and stripped and not stripped[0].isspace() and not line_text[0].isspace():
in_for_loop = False
elif in_for_loop and re.search(r'(?:SELECT|\.execute)\s*\(', stripped):
findings.append({
"skill_name": skill_name,
"dimension": "performance",
"severity": "medium",
"category": "n_plus_1",
"title": f"Possivel N+1 query em {rel_path}",
"description": "Loop com query SQL pode causar muitas chamadas ao banco",
"file_path": rel_path,
"recommendation": "Carregar dados em batch antes do loop",
"effort": "medium",
"impact": "high",
})
score -= 8
break
# Criar conexao dentro de loop (analise simples)
has_connect_in_loop = False
in_for_loop = False
for line_text in lines:
stripped = line_text.strip()
if stripped.startswith("for ") and stripped.endswith(":"):
in_for_loop = True
elif in_for_loop and stripped and not line_text[0].isspace():
in_for_loop = False
elif in_for_loop and "_connect()" in stripped:
has_connect_in_loop = True
break
if has_connect_in_loop:
findings.append({
"skill_name": skill_name,
"dimension": "performance",
"severity": "medium",
"category": "connection_per_iteration",
"title": f"Conexao criada dentro de loop em {rel_path}",
"file_path": rel_path,
"recommendation": "Mover _connect() para fora do loop, reutilizar conexao",
"effort": "low",
"impact": "high",
})
score -= 5
# Verificar ausencia de boas praticas
if not has_retry and api_call_files:
findings.append({
"skill_name": skill_name,
"dimension": "performance",
"severity": "medium",
"category": "no_retry",
"title": "Sem retry/backoff para chamadas API",
"description": f"Encontradas chamadas API em {len(api_call_files)} arquivo(s) sem mecanismo de retry",
"recommendation": "Implementar retry com exponential backoff (ex: tenacity, ou manual)",
"effort": "medium",
"impact": "high",
})
score -= 10
if not has_timeout and api_call_files:
findings.append({
"skill_name": skill_name,
"dimension": "performance",
"severity": "medium",
"category": "no_timeout",
"title": "Sem timeout configurado para chamadas HTTP",
"recommendation": "Adicionar timeout= em todas as chamadas requests/httpx",
"effort": "low",
"impact": "medium",
})
score -= 5
if not has_connection_pool and len(api_call_files) > 2:
findings.append({
"skill_name": skill_name,
"dimension": "performance",
"severity": "low",
"category": "no_connection_reuse",
"title": "Sem reuso de conexoes HTTP",
"description": "Multiplos arquivos fazem chamadas HTTP sem Session/Client compartilhado",
"recommendation": "Usar requests.Session() ou httpx.Client() para reutilizar conexoes",
"effort": "low",
"impact": "medium",
})
score -= 3
# Bonus
if has_retry:
score = min(100.0, score + 5)
if has_async or has_concurrency:
score = min(100.0, score + 5)
if has_caching:
score = min(100.0, score + 3)
return max(0.0, min(100.0, score)), findings