|
|
|
|
|
""" |
|
|
tools/selfmod.py |
|
|
Comandos de auto-modificação do HASHIRU 6.1: |
|
|
- /self:analyze |
|
|
- /self:plan <objetivo> |
|
|
- /self:apply <objetivo> |
|
|
- /self:status |
|
|
""" |
|
|
|
|
|
from __future__ import annotations |
|
|
|
|
|
import json |
|
|
import time |
|
|
from pathlib import Path |
|
|
from typing import Any, Dict, List, Optional |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
from utils.self_modification_engine import self_modification_engine |
|
|
except Exception: |
|
|
self_modification_engine = None |
|
|
|
|
|
try: |
|
|
|
|
|
from autonomous_config import autonomous_config, is_self_modification_enabled |
|
|
_CONFIG_OK = True |
|
|
except Exception: |
|
|
autonomous_config = None |
|
|
def is_self_modification_enabled() -> bool: |
|
|
return False |
|
|
_CONFIG_OK = False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ARTIFACTS_DIR = Path("artifacts") |
|
|
|
|
|
|
|
|
def _ensure_artifacts_dir() -> None: |
|
|
ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
|
|
|
def _build_analysis_summary(analysis: Dict[str, Any]) -> Dict[str, Any]: |
|
|
""" |
|
|
Constrói um resumo compatível, caso o engine não gere "summary". |
|
|
Espera analysis['files'] com metadados. |
|
|
""" |
|
|
files: List[Dict[str, Any]] = analysis.get("files", []) or [] |
|
|
total_files = len(files) |
|
|
total_lines = 0 |
|
|
|
|
|
|
|
|
COMPLEXITY_THRESHOLD = 20 |
|
|
PARAMS_THRESHOLD = 6 |
|
|
|
|
|
high_complexity_files: List[Dict[str, Any]] = [] |
|
|
large_functions: List[Dict[str, Any]] = [] |
|
|
improvement_opportunities: List[Dict[str, Any]] = [] |
|
|
|
|
|
for f in files: |
|
|
if f.get("error"): |
|
|
continue |
|
|
|
|
|
lines = int(f.get("lines", 0) or 0) |
|
|
total_lines += lines |
|
|
|
|
|
complexity = int(f.get("complexity", 0) or 0) |
|
|
if complexity > COMPLEXITY_THRESHOLD: |
|
|
high_complexity_files.append( |
|
|
{"file": f.get("path", ""), "complexity": complexity} |
|
|
) |
|
|
improvement_opportunities.append( |
|
|
{ |
|
|
"type": "complexity_reduction", |
|
|
"priority": "high", |
|
|
"description": f"Complexidade {complexity} em {f.get('path','')}", |
|
|
"file": f.get("path", ""), |
|
|
"action": "refactor_complex_functions", |
|
|
} |
|
|
) |
|
|
|
|
|
for func in f.get("functions", []) or []: |
|
|
args_qtd = int(func.get("args", 0) or 0) |
|
|
if args_qtd > PARAMS_THRESHOLD: |
|
|
large_functions.append( |
|
|
{ |
|
|
"file": f.get("path", ""), |
|
|
"function": func.get("name", ""), |
|
|
"args": args_qtd, |
|
|
} |
|
|
) |
|
|
improvement_opportunities.append( |
|
|
{ |
|
|
"type": "parameter_optimization", |
|
|
"priority": "medium", |
|
|
"description": f"Função {func.get('name','')} com {args_qtd} parâmetros em {f.get('path','')}", |
|
|
"file": f.get("path", ""), |
|
|
"function": func.get("name", ""), |
|
|
"action": "reduce_parameters", |
|
|
} |
|
|
) |
|
|
|
|
|
high_complexity_files.sort(key=lambda x: x.get("complexity", 0) or 0, reverse=True) |
|
|
large_functions.sort(key=lambda x: x.get("args", 0) or 0, reverse=True) |
|
|
|
|
|
return { |
|
|
"total_files": total_files, |
|
|
"total_lines": total_lines, |
|
|
"high_complexity_files": high_complexity_files, |
|
|
"large_functions": large_functions, |
|
|
"improvement_opportunities": improvement_opportunities, |
|
|
"generated_at": time.strftime("%Y-%m-%d %H:%M:%S"), |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def handle_self_analyze(args: str, block: str) -> str: |
|
|
""" |
|
|
/self:analyze |
|
|
Analisa o código atual e identifica oportunidades de melhoria. |
|
|
""" |
|
|
if self_modification_engine is None: |
|
|
return "❌ Motor de auto-modificação não disponível. Verifique `utils/self_modification_engine.py`." |
|
|
|
|
|
if _CONFIG_OK and not is_self_modification_enabled(): |
|
|
return "❌ Auto-modificação desabilitada na configuração." |
|
|
|
|
|
try: |
|
|
analysis = self_modification_engine.analyze_current_codebase() |
|
|
|
|
|
|
|
|
summary = analysis.get("summary") |
|
|
if not summary: |
|
|
summary = _build_analysis_summary(analysis) |
|
|
analysis["summary"] = summary |
|
|
|
|
|
|
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_analysis.json", "w", encoding="utf-8") as f: |
|
|
json.dump(analysis, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
|
|
|
resp_lines: List[str] = [] |
|
|
resp_lines.append("🔍 **ANÁLISE DO CÓDIGO CONCLUÍDA**\n") |
|
|
resp_lines.append("📊 **Resumo Geral:**") |
|
|
resp_lines.append(f"- **Arquivos analisados:** {summary['total_files']}") |
|
|
resp_lines.append(f"- **Total de linhas:** {summary['total_lines']:,}") |
|
|
resp_lines.append(f"- **Arquivos complexos:** {len(summary['high_complexity_files'])}") |
|
|
resp_lines.append(f"- **Funções com muitos parâmetros:** {len(summary['large_functions'])}") |
|
|
resp_lines.append(f"- **Oportunidades de melhoria:** {len(summary['improvement_opportunities'])}") |
|
|
|
|
|
|
|
|
resp_lines.append("\n🔥 **Arquivos com Alta Complexidade:**") |
|
|
for complex_file in summary["high_complexity_files"][:5]: |
|
|
resp_lines.append(f"- **{complex_file['file']}** (complexidade: {complex_file['complexity']})") |
|
|
extra_c = len(summary["high_complexity_files"]) - 5 |
|
|
if extra_c > 0: |
|
|
resp_lines.append(f"- ... e mais {extra_c} arquivos") |
|
|
|
|
|
|
|
|
resp_lines.append("\n⚠️ **Funções com Muitos Parâmetros:**") |
|
|
for large_func in summary["large_functions"][:5]: |
|
|
resp_lines.append(f"- **{large_func['function']}** em {large_func['file']} ({large_func['args']} parâmetros)") |
|
|
extra_f = len(summary["large_functions"]) - 5 |
|
|
if extra_f > 0: |
|
|
resp_lines.append(f"- ... e mais {extra_f} funções") |
|
|
|
|
|
|
|
|
resp_lines.append("\n💡 **Principais Oportunidades:**") |
|
|
for opportunity in summary["improvement_opportunities"][:5]: |
|
|
pr = opportunity.get("priority", "medium") |
|
|
icon = "🔴" if pr == "high" else "🟡" if pr == "medium" else "🟢" |
|
|
resp_lines.append(f"{icon} **{opportunity['type']}:** {opportunity['description']}") |
|
|
extra_o = len(summary["improvement_opportunities"]) - 5 |
|
|
if extra_o > 0: |
|
|
resp_lines.append(f"- ... e mais {extra_o} oportunidades") |
|
|
|
|
|
|
|
|
resp_lines.append("\n📁 **Artifacts Salvos:**") |
|
|
resp_lines.append("- `artifacts/last_analysis.json` - Análise completa") |
|
|
resp_lines.append(f"- Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}") |
|
|
resp_lines.append("\n💡 **Próximos Passos:**") |
|
|
resp_lines.append("- Use `/self:plan <objetivo>` para criar plano de melhorias") |
|
|
resp_lines.append("- Use `/self:apply <objetivo>` para aplicar melhorias automaticamente") |
|
|
|
|
|
return "\n".join(resp_lines) |
|
|
|
|
|
except Exception as exc: |
|
|
return f"💥 **Erro na análise:** {exc}" |
|
|
|
|
|
|
|
|
async def handle_self_plan(args: str, block: str) -> str: |
|
|
""" |
|
|
/self:plan <objetivo> |
|
|
Cria um plano de melhorias baseado no objetivo especificado. |
|
|
""" |
|
|
if self_modification_engine is None: |
|
|
return "❌ Motor de auto-modificação não disponível." |
|
|
|
|
|
objective = (args or "").strip() |
|
|
if not objective: |
|
|
return ( |
|
|
"❌ **Objetivo não especificado.**\n\n" |
|
|
"**Uso:** `/self:plan <objetivo>`\n\n" |
|
|
"**Exemplos:**\n" |
|
|
"- `/self:plan Otimizar performance do sistema`\n" |
|
|
"- `/self:plan Reduzir complexidade do código`\n" |
|
|
"- `/self:plan Adicionar cache inteligente`\n" |
|
|
"- `/self:plan Corrigir bugs identificados`\n" |
|
|
"- `/self:plan Melhorar documentação`" |
|
|
) |
|
|
|
|
|
try: |
|
|
|
|
|
try: |
|
|
with open(ARTIFACTS_DIR / "last_analysis.json", "r", encoding="utf-8") as f: |
|
|
analysis = json.load(f) |
|
|
except FileNotFoundError: |
|
|
analysis = self_modification_engine.analyze_current_codebase() |
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_analysis.json", "w", encoding="utf-8") as f: |
|
|
json.dump(analysis, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
plan = self_modification_engine.generate_improvement_plan(analysis, objective) |
|
|
plan.setdefault("user_goal", objective) |
|
|
plan.setdefault("priority", "medium") |
|
|
plan.setdefault("estimated_impact", "moderate") |
|
|
|
|
|
|
|
|
backup_enabled = True |
|
|
try: |
|
|
if _CONFIG_OK: |
|
|
backup_enabled = bool(autonomous_config.SELF_MODIFICATION.get("auto_backup", True)) |
|
|
except Exception: |
|
|
backup_enabled = True |
|
|
plan["backup_strategy"] = "auto_backup_on_write" if backup_enabled else "no_auto_backup" |
|
|
|
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_plan.json", "w", encoding="utf-8") as f: |
|
|
json.dump(plan, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
|
|
|
lines = [] |
|
|
lines.append("📋 **PLANO DE MELHORIAS CRIADO**\n") |
|
|
lines.append(f"🎯 **Objetivo:** {objective}") |
|
|
lines.append(f"⏰ **Criado em:** {time.strftime('%Y-%m-%d %H:%M:%S')}") |
|
|
lines.append(f"📊 **Prioridade:** {plan.get('priority','medium')}") |
|
|
lines.append(f"💪 **Impacto Estimado:** {plan.get('estimated_impact','moderate')}") |
|
|
|
|
|
improvements = plan.get("improvements", []) or [] |
|
|
lines.append(f"\n🔧 **Melhorias Planejadas ({len(improvements)}):**") |
|
|
for i, imp in enumerate(improvements[:10], 1): |
|
|
pr = imp.get("priority", "medium") |
|
|
icon_p = "🔴" if pr == "high" else "🟡" if pr == "medium" else "🟢" |
|
|
eff = imp.get("estimated_effort", "medium") |
|
|
icon_e = "🔥" if eff == "high" else "⚡" if eff == "medium" else "💨" |
|
|
desc = imp.get("description", imp.get("type", "improvement")) |
|
|
lines.append(f"{i}. {icon_p}{icon_e} **{imp.get('type','improvement').replace('_',' ').title()}**") |
|
|
lines.append(f" - {desc}") |
|
|
if imp.get("file"): |
|
|
lines.append(f" - Arquivo: `{imp['file']}`") |
|
|
if imp.get("function"): |
|
|
lines.append(f" - Função: `{imp['function']}`") |
|
|
|
|
|
extra = len(improvements) - 10 |
|
|
if extra > 0: |
|
|
lines.append(f"... e mais {extra} melhorias") |
|
|
|
|
|
lines.append(f"\n💾 **Estratégia de Backup:** {plan['backup_strategy']}") |
|
|
lines.append("📁 **Plano salvo em:** `artifacts/last_plan.json`") |
|
|
lines.append("\n🚀 **Próximos Passos:**") |
|
|
lines.append(f"- Use `/self:apply {objective}` para executar automaticamente") |
|
|
lines.append("- Ou execute melhorias individuais conforme necessário") |
|
|
|
|
|
return "\n".join(lines) |
|
|
|
|
|
except Exception as exc: |
|
|
return f"💥 **Erro ao criar plano:** {exc}" |
|
|
|
|
|
|
|
|
async def handle_self_apply(args: str, block: str) -> str: |
|
|
""" |
|
|
/self:apply <objetivo> |
|
|
Aplica automaticamente as melhorias do plano especificado. |
|
|
""" |
|
|
if self_modification_engine is None: |
|
|
return "❌ Motor de auto-modificação não disponível." |
|
|
|
|
|
if _CONFIG_OK and not is_self_modification_enabled(): |
|
|
return "❌ Auto-modificação desabilitada na configuração." |
|
|
|
|
|
objective = (args or "").strip() |
|
|
if not objective: |
|
|
return ( |
|
|
"❌ **Objetivo não especificado.**\n\n" |
|
|
"**Uso:** `/self:apply <objetivo>`\n\n" |
|
|
"⚠️ **ATENÇÃO:** Este comando modifica arquivos automaticamente!\n" |
|
|
"Certifique-se de ter backups adequados." |
|
|
) |
|
|
|
|
|
try: |
|
|
|
|
|
try: |
|
|
with open(ARTIFACTS_DIR / "last_plan.json", "r", encoding="utf-8") as f: |
|
|
plan = json.load(f) |
|
|
if str(plan.get("user_goal", "")).lower() != objective.lower(): |
|
|
raise FileNotFoundError |
|
|
except FileNotFoundError: |
|
|
try: |
|
|
with open(ARTIFACTS_DIR / "last_analysis.json", "r", encoding="utf-8") as f: |
|
|
analysis = json.load(f) |
|
|
except FileNotFoundError: |
|
|
analysis = self_modification_engine.analyze_current_codebase() |
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_analysis.json", "w", encoding="utf-8") as f: |
|
|
json.dump(analysis, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
plan = self_modification_engine.generate_improvement_plan(analysis, objective) |
|
|
plan.setdefault("user_goal", objective) |
|
|
plan.setdefault("priority", "medium") |
|
|
plan.setdefault("estimated_impact", "moderate") |
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_plan.json", "w", encoding="utf-8") as f: |
|
|
json.dump(plan, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
results = self_modification_engine.implement_improvements(plan) |
|
|
results.setdefault("implemented", []) |
|
|
results.setdefault("failed", []) |
|
|
results.setdefault("created_files", []) |
|
|
results.setdefault("modified_files", []) |
|
|
results.setdefault("backups_created", []) |
|
|
|
|
|
_ensure_artifacts_dir() |
|
|
with open(ARTIFACTS_DIR / "last_results.json", "w", encoding="utf-8") as f: |
|
|
json.dump(results, f, ensure_ascii=False, indent=2) |
|
|
|
|
|
|
|
|
lines = [] |
|
|
lines.append("🚀 **MELHORIAS APLICADAS AUTOMATICAMENTE**\n") |
|
|
lines.append(f"🎯 **Objetivo:** {objective}") |
|
|
lines.append(f"⏰ **Executado em:** {time.strftime('%Y-%m-%d %H:%M:%S')}") |
|
|
|
|
|
impl = results["implemented"] |
|
|
lines.append(f"\n✅ **Melhorias Implementadas ({len(impl)}):**") |
|
|
for imp in impl: |
|
|
desc = imp.get("description", imp.get("type", "improvement")) |
|
|
lines.append(f"- ✅ **{imp.get('type','improvement').replace('_',' ').title()}:** {desc}") |
|
|
|
|
|
failed = results["failed"] |
|
|
if failed: |
|
|
lines.append(f"\n❌ **Melhorias que Falharam ({len(failed)}):**") |
|
|
for f in failed: |
|
|
imp = f.get("improvement", {}) |
|
|
lines.append(f"- ❌ **{imp.get('type','improvement')}:** {f.get('error','erro desconhecido')}") |
|
|
|
|
|
lines.append(f"\n📁 **Arquivos Criados ({len(results['created_files'])}):**") |
|
|
for c in results["created_files"]: |
|
|
lines.append(f"- 🆕 `{c}`") |
|
|
|
|
|
lines.append(f"\n📝 **Arquivos Modificados ({len(results['modified_files'])}):**") |
|
|
for m in results["modified_files"]: |
|
|
lines.append(f"- ✏️ `{m}`") |
|
|
|
|
|
backups_ok = [b for b in results["backups_created"] if b] |
|
|
lines.append(f"\n💾 **Backups Criados ({len(backups_ok)}):**") |
|
|
for b in backups_ok: |
|
|
lines.append(f"- 🗂️ `{b}`") |
|
|
|
|
|
lines.append("\n📊 **Resumo:**") |
|
|
lines.append(f"- ✅ Sucessos: {len(results['implemented'])}") |
|
|
lines.append(f"- ❌ Falhas: {len(results['failed'])}") |
|
|
lines.append(f"- 🆕 Arquivos criados: {len(results['created_files'])}") |
|
|
lines.append(f"- ✏️ Arquivos modificados: {len(results['modified_files'])}") |
|
|
lines.append(f"- 💾 Backups: {len(backups_ok)}") |
|
|
|
|
|
lines.append("\n📁 **Resultados salvos em:** `artifacts/last_results.json`") |
|
|
lines.append("\n🎉 **Sistema auto-melhorado com sucesso!**") |
|
|
|
|
|
return "\n".join(lines) |
|
|
|
|
|
except Exception as exc: |
|
|
return f"💥 **Erro na aplicação:** {exc}" |
|
|
|
|
|
|
|
|
async def handle_self_status(args: str, block: str) -> str: |
|
|
""" |
|
|
/self:status |
|
|
Mostra status do sistema de auto-modificação. |
|
|
""" |
|
|
lines = [] |
|
|
lines.append("🔧 **STATUS DO SISTEMA DE AUTO-MODIFICAÇÃO**\n") |
|
|
|
|
|
|
|
|
engine_ok = self_modification_engine is not None |
|
|
config_ok = _CONFIG_OK |
|
|
enabled = False |
|
|
try: |
|
|
enabled = bool(is_self_modification_enabled()) |
|
|
except Exception: |
|
|
enabled = False |
|
|
|
|
|
lines.append("⚙️ **Componentes:**") |
|
|
lines.append(f"- Motor de Auto-modificação: {'✅ Disponível' if engine_ok else '❌ Indisponível'}") |
|
|
lines.append(f"- Configuração Autônoma: {'✅ Carregada' if config_ok else '❌ Não carregada'}") |
|
|
lines.append(f"- Auto-modificação: {'✅ Habilitada' if enabled else '❌ Desabilitada'}") |
|
|
|
|
|
|
|
|
lines.append("\n📁 **Artifacts Disponíveis:**") |
|
|
artifacts = ["last_analysis.json", "last_plan.json", "last_results.json"] |
|
|
if ARTIFACTS_DIR.exists(): |
|
|
for name in artifacts: |
|
|
p = ARTIFACTS_DIR / name |
|
|
if p.exists(): |
|
|
mtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(p.stat().st_mtime)) |
|
|
lines.append(f"- ✅ `{name}` (modificado: {mtime})") |
|
|
else: |
|
|
lines.append(f"- ❌ `{name}` (não encontrado)") |
|
|
else: |
|
|
lines.append("- ❌ Diretório artifacts não encontrado") |
|
|
|
|
|
|
|
|
if engine_ok: |
|
|
try: |
|
|
report = self_modification_engine.create_performance_report() |
|
|
total_mods = report.get("total_modifications", 0) |
|
|
success_rate = float(report.get("success_rate", 0.0)) |
|
|
perf_impact = report.get("performance_impact", "unknown") |
|
|
config_integration = bool(report.get("config_integration", False)) |
|
|
|
|
|
lines.append("\n📊 **Métricas de Performance:**") |
|
|
lines.append(f"- Total de modificações: {total_mods}") |
|
|
lines.append(f"- Taxa de sucesso: {success_rate:.1%}") |
|
|
lines.append(f"- Impacto na performance: {perf_impact}") |
|
|
lines.append(f"- Integração de config: {'✅' if config_integration else '❌'}") |
|
|
except Exception as exc: |
|
|
lines.append(f"\n⚠️ **Erro ao obter métricas:** {exc}") |
|
|
|
|
|
|
|
|
lines.append("\n🔧 **Comandos Disponíveis:**") |
|
|
lines.append("- `/self:analyze` - Analisar código atual") |
|
|
lines.append("- `/self:plan <objetivo>` - Criar plano de melhorias") |
|
|
lines.append("- `/self:apply <objetivo>` - Aplicar melhorias automaticamente") |
|
|
lines.append("- `/self:status` - Este status") |
|
|
lines.append("\n💡 **Exemplo de Uso:**") |
|
|
lines.append("/self:analyze") |
|
|
lines.append("/self:plan Otimizar performance") |
|
|
lines.append("/self:apply Otimizar performance") |
|
|
lines.append("/self:status") |
|
|
|
|
|
return "\n".join(lines) |
|
|
|
|
|
|
|
|
__all__ = [ |
|
|
"handle_self_analyze", |
|
|
"handle_self_plan", |
|
|
"handle_self_apply", |
|
|
"handle_self_status", |
|
|
] |
|
|
|