| | |
| | """ |
| | 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", |
| | ] |
| |
|