wegho-agentes 7.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.agent/skills/wegho-global-rules/SKILL.md +20 -0
  2. package/.agent/workflows/PROMPT_GUIDE.md +7 -4
  3. package/.agents/cli.ts +29 -21
  4. package/.agents/core/base-agent.ts +28 -12
  5. package/.agents/core/memory-system.ts +45 -13
  6. package/.agents/core/report-generator.ts +26 -19
  7. package/.agents/orchestrator.ts +104 -74
  8. package/.clinerules +318 -1229
  9. package/.cursorrules +0 -189
  10. package/README.md +3 -3
  11. package/docs/VERSION.md +3 -2
  12. package/package.json +3 -3
  13. package/.agents/agents/ai-agents/README.md +0 -175
  14. package/.agents/agents/ai-agents/agent.ts +0 -83
  15. package/.agents/agents/ai-agents/specialty.md +0 -14
  16. package/.agents/agents/architecture/README.md +0 -61
  17. package/.agents/agents/architecture/agent.ts +0 -238
  18. package/.agents/agents/architecture/memory.md +0 -111
  19. package/.agents/agents/architecture/specialty.md +0 -31
  20. package/.agents/agents/automation/README.md +0 -60
  21. package/.agents/agents/automation/agent.ts +0 -61
  22. package/.agents/agents/automation/specialty.md +0 -14
  23. package/.agents/agents/backend/README.md +0 -155
  24. package/.agents/agents/backend/agent.ts +0 -100
  25. package/.agents/agents/backend/specialty.md +0 -14
  26. package/.agents/agents/cloud/README.md +0 -73
  27. package/.agents/agents/cloud/agent.ts +0 -53
  28. package/.agents/agents/cloud/specialty.md +0 -14
  29. package/.agents/agents/code-auditor/README.md +0 -37
  30. package/.agents/agents/code-auditor/agent.ts +0 -334
  31. package/.agents/agents/code-auditor/specialty.md +0 -14
  32. package/.agents/agents/cro/README.md +0 -200
  33. package/.agents/agents/cro/agent.ts +0 -61
  34. package/.agents/agents/cro/specialty.md +0 -14
  35. package/.agents/agents/database/README.md +0 -67
  36. package/.agents/agents/database/agent.ts +0 -93
  37. package/.agents/agents/database/specialty.md +0 -14
  38. package/.agents/agents/devops/README.md +0 -84
  39. package/.agents/agents/devops/agent.ts +0 -54
  40. package/.agents/agents/devops/specialty.md +0 -14
  41. package/.agents/agents/documentation/README.md +0 -107
  42. package/.agents/agents/documentation/agent.ts +0 -253
  43. package/.agents/agents/documentation/memory.md +0 -56
  44. package/.agents/agents/documentation/specialty.md +0 -33
  45. package/.agents/agents/frontend/README.md +0 -188
  46. package/.agents/agents/frontend/agent.ts +0 -211
  47. package/.agents/agents/frontend/memory.md +0 -139
  48. package/.agents/agents/frontend/specialty.md +0 -30
  49. package/.agents/agents/inventory/README.md +0 -35
  50. package/.agents/agents/inventory/agent.ts +0 -758
  51. package/.agents/agents/inventory/memory.md +0 -50
  52. package/.agents/agents/inventory/specialty.md +0 -129
  53. package/.agents/agents/nextjs/README.md +0 -58
  54. package/.agents/agents/nextjs/agent.ts +0 -114
  55. package/.agents/agents/nextjs/specialty.md +0 -14
  56. package/.agents/agents/pentest/README.md +0 -228
  57. package/.agents/agents/pentest/agent.ts +0 -96
  58. package/.agents/agents/pentest/specialty.md +0 -14
  59. package/.agents/agents/planning/README.md +0 -107
  60. package/.agents/agents/planning/agent.ts +0 -389
  61. package/.agents/agents/planning/specialty.md +0 -14
  62. package/.agents/agents/project-discovery/README.md +0 -35
  63. package/.agents/agents/project-discovery/agent.ts +0 -344
  64. package/.agents/agents/project-discovery/specialty.md +0 -14
  65. package/.agents/agents/quality/README.md +0 -81
  66. package/.agents/agents/quality/agent.ts +0 -269
  67. package/.agents/agents/quality/memory.md +0 -110
  68. package/.agents/agents/quality/specialty.md +0 -31
  69. package/.agents/agents/rag/README.md +0 -41
  70. package/.agents/agents/rag/agent.ts +0 -85
  71. package/.agents/agents/rag/specialty.md +0 -14
  72. package/.agents/agents/security/README.md +0 -152
  73. package/.agents/agents/security/agent.ts +0 -218
  74. package/.agents/agents/security/memory.md +0 -91
  75. package/.agents/agents/security/specialty.md +0 -31
  76. package/.agents/agents/task-analyzer/README.md +0 -36
  77. package/.agents/agents/task-analyzer/agent.ts +0 -462
  78. package/.agents/agents/task-analyzer/specialty.md +0 -14
  79. package/.agents/agents/testing/README.md +0 -161
  80. package/.agents/agents/testing/agent.ts +0 -61
  81. package/.agents/agents/testing/specialty.md +0 -14
  82. package/.agents/agents/uiux/README.md +0 -68
  83. package/.agents/agents/uiux/agent.ts +0 -95
  84. package/.agents/agents/uiux/specialty.md +0 -14
  85. package/.agents/base/base-agent.ts +0 -331
  86. package/.agents/base/memory-system.ts +0 -397
  87. package/.agents/base/skill-manager.ts +0 -95
  88. package/.agents/convert-memory.ps1 +0 -153
  89. package/.agents/examples/reporting-example.md +0 -203
  90. package/.agents/managers/build-manager.ts +0 -304
  91. package/.agents/managers/cache-manager.ts +0 -184
  92. package/.agents/managers/checkpoint-manager.ts +0 -299
  93. package/.agents/migrate-agents.ps1 +0 -117
  94. package/.agents/templates/change-report.md +0 -55
  95. package/.agents/templates/execution-plan.md +0 -36
  96. package/.agents/unmapped-skills.txt +0 -0
  97. package/.agents/utils/agent-migrator.ts +0 -360
  98. package/.agents/utils/agent-monitor.ts +0 -102
  99. package/.agents/utils/agent-parallelizer.ts +0 -108
  100. package/.agents/utils/context-monitor.ts +0 -140
  101. package/.agents/utils/feedback-collector.ts +0 -207
  102. package/.agents/utils/file-generator.ts +0 -304
  103. package/.agents/utils/memory-converter.ts +0 -217
  104. package/.agents/utils/memory-dashboard.ts +0 -147
  105. package/.agents/utils/performance-tracker.ts +0 -275
  106. package/.agents/utils/report-generator.ts +0 -193
  107. package/.agents/utils/retry-utility.ts +0 -140
  108. package/.agents/utils/workflow-validator.ts +0 -158
@@ -1,217 +0,0 @@
1
- /**
2
- * Memory Converter - Converte memória JSON para Markdown
3
- *
4
- * Responsabilidades:
5
- * - Ler arquivos JSON de memória (successes, failures, learnings)
6
- * - Converter para formato markdown estruturado
7
- * - Preservar toda informação histórica
8
- */
9
-
10
- import * as fs from 'fs';
11
- import * as path from 'path';
12
-
13
- interface MemoryEntry {
14
- id: string;
15
- timestamp: string;
16
- taskDescription: string;
17
- context: {
18
- files: string[];
19
- areas: string[];
20
- complexity: 'low' | 'medium' | 'high';
21
- };
22
- result: string;
23
- details: string;
24
- userFeedback?: {
25
- satisfied: boolean;
26
- likes: string[];
27
- dislikes: string[];
28
- suggestions: string[];
29
- };
30
- }
31
-
32
- interface Learning {
33
- pattern: string;
34
- description: string;
35
- recommendation: string;
36
- confidence: number;
37
- exampleIds: string[];
38
- createdAt: string;
39
- }
40
-
41
- export class MemoryConverter {
42
- /**
43
- * Converte memória de um agente de JSON para MD
44
- */
45
- static convertAgentMemory(agentName: string, memoryBasePath: string): string {
46
- const agentMemoryPath = path.join(memoryBasePath, agentName);
47
-
48
- // Ler arquivos JSON
49
- const successes = this.readJsonFile<MemoryEntry[]>(path.join(agentMemoryPath, 'successes.json')) || [];
50
- const failures = this.readJsonFile<MemoryEntry[]>(path.join(agentMemoryPath, 'failures.json')) || [];
51
- const learnings = this.readJsonFile<Learning[]>(path.join(agentMemoryPath, 'learnings.json')) || [];
52
-
53
- // Calcular estatísticas
54
- const totalSuccesses = successes.length;
55
- const totalFailures = failures.length;
56
- const totalTasks = totalSuccesses + totalFailures;
57
- const successRate = totalTasks > 0 ? ((totalSuccesses / totalTasks) * 100).toFixed(1) : '0.0';
58
-
59
- // Gerar markdown
60
- let markdown = `# Memória do Agente ${agentName}\n\n`;
61
- markdown += `Última atualização: ${new Date().toISOString()}\n\n`;
62
- markdown += `---\n\n`;
63
-
64
- // Estatísticas
65
- markdown += `## 📊 Estatísticas\n\n`;
66
- markdown += `- Total de sucessos: ${totalSuccesses}\n`;
67
- markdown += `- Total de falhas: ${totalFailures}\n`;
68
- markdown += `- Taxa de sucesso: ${successRate}%\n`;
69
- markdown += `- Aprendizados acumulados: ${learnings.length}\n\n`;
70
- markdown += `---\n\n`;
71
-
72
- // Sucessos recentes (últimos 10)
73
- markdown += `## ✅ Sucessos Recentes\n\n`;
74
- const recentSuccesses = successes.slice(-10).reverse();
75
-
76
- if (recentSuccesses.length === 0) {
77
- markdown += `_Nenhum sucesso registrado ainda._\n\n`;
78
- } else {
79
- recentSuccesses.forEach(entry => {
80
- const date = new Date(entry.timestamp).toLocaleDateString('pt-BR');
81
- markdown += `### ${date} - \`${entry.id}\`\n\n`;
82
- markdown += `**Tarefa**: ${entry.taskDescription}\n\n`;
83
- markdown += `**Contexto**:\n`;
84
- markdown += `- Arquivos: ${entry.context.files.length > 0 ? entry.context.files.join(', ') : 'nenhum'}\n`;
85
- markdown += `- Áreas: ${entry.context.areas.join(', ')}\n`;
86
- markdown += `- Complexidade: ${entry.complexity || entry.context.complexity}\n\n`;
87
- markdown += `**Resultado**: ${entry.details}\n\n`;
88
-
89
- if (entry.userFeedback) {
90
- const emoji = entry.userFeedback.satisfied ? '👍' : '👎';
91
- markdown += `**Feedback do usuário**: ${emoji}\n`;
92
- if (entry.userFeedback.likes.length > 0) {
93
- markdown += `- Gostou: ${entry.userFeedback.likes.join(', ')}\n`;
94
- }
95
- if (entry.userFeedback.dislikes.length > 0) {
96
- markdown += `- Não gostou: ${entry.userFeedback.dislikes.join(', ')}\n`;
97
- }
98
- if (entry.userFeedback.suggestions.length > 0) {
99
- markdown += `- Sugestões: ${entry.userFeedback.suggestions.join(', ')}\n`;
100
- }
101
- markdown += '\n';
102
- }
103
- });
104
- }
105
-
106
- markdown += `---\n\n`;
107
-
108
- // Falhas registradas (últimas 10)
109
- markdown += `## ❌ Falhas Registradas\n\n`;
110
- const recentFailures = failures.slice(-10).reverse();
111
-
112
- if (recentFailures.length === 0) {
113
- markdown += `_Nenhuma falha registrada._\n\n`;
114
- } else {
115
- recentFailures.forEach(entry => {
116
- const date = new Date(entry.timestamp).toLocaleDateString('pt-BR');
117
- markdown += `### ${date} - \`${entry.id}\`\n\n`;
118
- markdown += `**Tarefa**: ${entry.taskDescription}\n\n`;
119
- markdown += `**Motivo**: ${entry.details}\n\n`;
120
-
121
- if (entry.userFeedback && entry.userFeedback.suggestions.length > 0) {
122
- markdown += `**Lição aprendida**: ${entry.userFeedback.suggestions.join('; ')}\n\n`;
123
- }
124
- });
125
- }
126
-
127
- markdown += `---\n\n`;
128
-
129
- // Aprendizados
130
- markdown += `## 🧠 Aprendizados\n\n`;
131
-
132
- if (learnings.length === 0) {
133
- markdown += `_Nenhum aprendizado registrado ainda._\n\n`;
134
- } else {
135
- learnings.forEach((learning, index) => {
136
- markdown += `### Aprendizado ${index + 1}\n\n`;
137
- markdown += `**Padrão**: ${learning.pattern}\n\n`;
138
- markdown += `**Descrição**: ${learning.description}\n\n`;
139
- markdown += `**Recomendação**: ${learning.recommendation}\n\n`;
140
- markdown += `**Confiança**: ${(learning.confidence * 100).toFixed(0)}%\n\n`;
141
-
142
- if (learning.exampleIds.length > 0) {
143
- markdown += `**Exemplos**: ${learning.exampleIds.map(id => `\`${id}\``).join(', ')}\n\n`;
144
- }
145
-
146
- if (learning.createdAt) {
147
- const date = new Date(learning.createdAt).toLocaleDateString('pt-BR');
148
- markdown += `_Criado em: ${date}_\n\n`;
149
- }
150
- });
151
- }
152
-
153
- return markdown;
154
- }
155
-
156
- /**
157
- * Lê arquivo JSON com tratamento de erros
158
- */
159
- private static readJsonFile<T>(filePath: string): T | null {
160
- try {
161
- if (!fs.existsSync(filePath)) {
162
- return null;
163
- }
164
- const content = fs.readFileSync(filePath, 'utf-8');
165
- return JSON.parse(content) as T;
166
- } catch (error) {
167
- console.warn(`⚠️ Erro ao ler ${filePath}:`, error);
168
- return null;
169
- }
170
- }
171
-
172
- /**
173
- * Converte todos os agentes em um diretório
174
- */
175
- static convertAllAgents(memoryBasePath: string, outputBasePath: string): void {
176
- if (!fs.existsSync(memoryBasePath)) {
177
- console.error(`❌ Pasta de memória não encontrada: ${memoryBasePath}`);
178
- return;
179
- }
180
-
181
- const agentDirs = fs.readdirSync(memoryBasePath, { withFileTypes: true })
182
- .filter(dirent => dirent.isDirectory())
183
- .map(dirent => dirent.name);
184
-
185
- console.log(`🔄 Convertendo memória de ${agentDirs.length} agentes...\n`);
186
-
187
- agentDirs.forEach(agentName => {
188
- try {
189
- const markdown = this.convertAgentMemory(agentName, memoryBasePath);
190
-
191
- // Criar pasta de destino
192
- const agentOutputPath = path.join(outputBasePath, agentName);
193
- if (!fs.existsSync(agentOutputPath)) {
194
- fs.mkdirSync(agentOutputPath, { recursive: true });
195
- }
196
-
197
- // Salvar memory.md
198
- const outputFile = path.join(agentOutputPath, 'memory.md');
199
- fs.writeFileSync(outputFile, markdown, 'utf-8');
200
-
201
- console.log(`✅ ${agentName} → ${outputFile}`);
202
- } catch (error: any) {
203
- console.error(`❌ Erro ao converter ${agentName}:`, error.message);
204
- }
205
- });
206
-
207
- console.log(`\n✅ Conversão concluída!`);
208
- }
209
- }
210
-
211
- // CLI para execução standalone
212
- if (require.main === module) {
213
- const memoryBasePath = path.join(process.cwd(), '.agents', 'memory');
214
- const outputBasePath = path.join(process.cwd(), '.agents', 'agents');
215
-
216
- MemoryConverter.convertAllAgents(memoryBasePath, outputBasePath);
217
- }
@@ -1,147 +0,0 @@
1
- /**
2
- * Memory Dashboard - Dashboard de memórias por agente
3
- */
4
-
5
- import { MemorySystem } from '../base/memory-system.js';
6
-
7
- export interface MemorySummary {
8
- agentName: string;
9
- goodMemories: {
10
- count: number;
11
- examples: string[];
12
- };
13
- badMemories: {
14
- count: number;
15
- examples: string[];
16
- };
17
- totalTasks: number;
18
- successRate: number;
19
- }
20
-
21
- export class MemoryDashboard {
22
- /**
23
- * Gera dashboard completo de memórias de todos os agentes
24
- */
25
- generateFullDashboard(agentNames: string[], memoryPath: string = '.agents/memory'): string {
26
- let dashboard = '\\n📊 DASHBOARD DE MEMÓRIAS\\n\\n';
27
-
28
- for (const agentName of agentNames) {
29
- const summary = this.getAgentMemorySummary(agentName, memoryPath);
30
- dashboard += this.formatAgentSection(summary);
31
- dashboard += '\\n';
32
- }
33
-
34
- return dashboard;
35
- }
36
-
37
- /**
38
- * Gera relatório de um agente específico
39
- */
40
- getAgentMemorySummary(agentName: string, memoryPath: string = '.agents/memory'): MemorySummary {
41
- const memory = new MemorySystem(memoryPath);
42
- const agentMemory = memory.loadMemory(agentName);
43
-
44
- // Separar memórias boas e ruins
45
- const goodMemories = agentMemory.successes;
46
- const badMemories = agentMemory.failures;
47
-
48
- // Pegar top 3 exemplos de cada
49
- const goodExamples = goodMemories
50
- .slice(-3)
51
- .map(e => e.taskDescription);
52
-
53
- const badExamples = badMemories
54
- .slice(-3)
55
- .map(e => e.taskDescription);
56
-
57
- const totalTasks = goodMemories.length + badMemories.length;
58
- const successRate = totalTasks > 0
59
- ? Math.round((goodMemories.length / totalTasks) * 100)
60
- : 0;
61
-
62
- return {
63
- agentName,
64
- goodMemories: {
65
- count: goodMemories.length,
66
- examples: goodExamples
67
- },
68
- badMemories: {
69
- count: badMemories.length,
70
- examples: badExamples
71
- },
72
- totalTasks,
73
- successRate
74
- };
75
- }
76
-
77
- /**
78
- * Formata seção de um agente para exibição
79
- */
80
- private formatAgentSection(summary: MemorySummary): string {
81
- const boxWidth = 50;
82
- const border = '─'.repeat(boxWidth);
83
-
84
- let section = `┌${border}┐\\n`;
85
- section += `│ ${this.pad(summary.agentName, boxWidth - 2)} │\\n`;
86
- section += `├${border}┤\\n`;
87
-
88
- // Memórias boas
89
- section += `│ ✅ Memórias Boas: ${summary.goodMemories.count}${' '.repeat(boxWidth - 20 - summary.goodMemories.count.toString().length)} │\\n`;
90
- if (summary.goodMemories.examples.length > 0) {
91
- summary.goodMemories.examples.forEach(example => {
92
- const truncated = this.truncate(example, boxWidth - 6);
93
- section += `│ - ${this.pad(truncated, boxWidth - 6)} │\\n`;
94
- });
95
- }
96
-
97
- section += `│${' '.repeat(boxWidth)}│\\n`;
98
-
99
- // Memórias ruins
100
- section += `│ ❌ Memórias Ruins: ${summary.badMemories.count}${' '.repeat(boxWidth - 21 - summary.badMemories.count.toString().length)} │\\n`;
101
- if (summary.badMemories.examples.length > 0) {
102
- summary.badMemories.examples.forEach(example => {
103
- const truncated = this.truncate(example, boxWidth - 6);
104
- section += `│ - ${this.pad(truncated, boxWidth - 6)} │\\n`;
105
- });
106
- }
107
-
108
- section += `│${' '.repeat(boxWidth)}│\\n`;
109
- section += `│ 📈 Taxa de Sucesso: ${summary.successRate}%${' '.repeat(boxWidth - 24 - summary.successRate.toString().length)} │\\n`;
110
- section += `└${border}┘`;
111
-
112
- return section;
113
- }
114
-
115
- /**
116
- * Padding helper
117
- */
118
- private pad(text: string, width: number): string {
119
- if (text.length >= width) return text.substring(0, width);
120
- return text + ' '.repeat(width - text.length);
121
- }
122
-
123
- /**
124
- * Truncate helper
125
- */
126
- private truncate(text: string, maxLength: number): string {
127
- if (text.length <= maxLength) return text;
128
- return text.substring(0, maxLength - 3) + '...';
129
- }
130
-
131
- /**
132
- * Gera relatório resumido (apenas estatísticas)
133
- */
134
- generateQuickSummary(agentNames: string[], memoryPath: string = '.agents/memory'): string {
135
- let summary = '📊 RESUMO DE MEMÓRIAS\\n\\n';
136
-
137
- for (const agentName of agentNames) {
138
- const mem = this.getAgentMemorySummary(agentName, memoryPath);
139
- summary += `${agentName}: ✅ ${mem.goodMemories.count} | ❌ ${mem.badMemories.count} | 📈 ${mem.successRate}%\\n`;
140
- }
141
-
142
- return summary;
143
- }
144
- }
145
-
146
- // Singleton global
147
- export const globalMemoryDashboard = new MemoryDashboard();
@@ -1,275 +0,0 @@
1
- /**
2
- * Sistema de Métricas de Performance
3
- *
4
- * Rastreia e analisa a performance de execução dos agentes,
5
- * incluindo duração de cada passo do workflow e identificação de bottlenecks.
6
- */
7
-
8
- export interface PerformanceMetric {
9
- agentName: string;
10
- taskId: string;
11
- stepName: string;
12
- startTime: number;
13
- endTime: number;
14
- duration: number;
15
- success: boolean;
16
- error?: string;
17
- }
18
-
19
- export interface AgentPerformanceSummary {
20
- agentName: string;
21
- totalExecutions: number;
22
- successfulExecutions: number;
23
- failedExecutions: number;
24
- averageDuration: number;
25
- minDuration: number;
26
- maxDuration: number;
27
- p50Duration: number;
28
- p95Duration: number;
29
- p99Duration: number;
30
- }
31
-
32
- export interface PerformanceReport {
33
- taskId: string;
34
- totalDuration: number;
35
- agentMetrics: Map<string, AgentPerformanceSummary>;
36
- bottlenecks: string[];
37
- recommendations: string[];
38
- }
39
-
40
- export class PerformanceTracker {
41
- private metrics: PerformanceMetric[] = [];
42
- private activeTimers: Map<string, number> = new Map();
43
-
44
- /**
45
- * Inicia o rastreamento de uma operação
46
- */
47
- startTracking(agentName: string, taskId: string, stepName: string): string {
48
- const trackingId = `${agentName}-${taskId}-${stepName}-${Date.now()}`;
49
- this.activeTimers.set(trackingId, Date.now());
50
- return trackingId;
51
- }
52
-
53
- /**
54
- * Finaliza o rastreamento de uma operação
55
- */
56
- endTracking(trackingId: string, success: boolean, error?: string): void {
57
- const startTime = this.activeTimers.get(trackingId);
58
- if (!startTime) {
59
- console.warn(`[PerformanceTracker] Tracking ID não encontrado: ${trackingId}`);
60
- return;
61
- }
62
-
63
- const endTime = Date.now();
64
- const [agentName, taskId, stepName] = trackingId.split('-');
65
-
66
- const metric: PerformanceMetric = {
67
- agentName,
68
- taskId,
69
- stepName,
70
- startTime,
71
- endTime,
72
- duration: endTime - startTime,
73
- success,
74
- error
75
- };
76
-
77
- this.metrics.push(metric);
78
- this.activeTimers.delete(trackingId);
79
- }
80
-
81
- /**
82
- * Obtém métricas de um agente específico
83
- */
84
- getAgentMetrics(agentName: string): PerformanceMetric[] {
85
- return this.metrics.filter(m => m.agentName === agentName);
86
- }
87
-
88
- /**
89
- * Obtém métricas de uma tarefa específica
90
- */
91
- getTaskMetrics(taskId: string): PerformanceMetric[] {
92
- return this.metrics.filter(m => m.taskId === taskId);
93
- }
94
-
95
- /**
96
- * Calcula resumo de performance de um agente
97
- */
98
- getAgentSummary(agentName: string): AgentPerformanceSummary {
99
- const agentMetrics = this.getAgentMetrics(agentName);
100
-
101
- if (agentMetrics.length === 0) {
102
- return {
103
- agentName,
104
- totalExecutions: 0,
105
- successfulExecutions: 0,
106
- failedExecutions: 0,
107
- averageDuration: 0,
108
- minDuration: 0,
109
- maxDuration: 0,
110
- p50Duration: 0,
111
- p95Duration: 0,
112
- p99Duration: 0
113
- };
114
- }
115
-
116
- const durations = agentMetrics.map(m => m.duration).sort((a, b) => a - b);
117
- const successfulExecutions = agentMetrics.filter(m => m.success).length;
118
-
119
- return {
120
- agentName,
121
- totalExecutions: agentMetrics.length,
122
- successfulExecutions,
123
- failedExecutions: agentMetrics.length - successfulExecutions,
124
- averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
125
- minDuration: durations[0],
126
- maxDuration: durations[durations.length - 1],
127
- p50Duration: this.calculatePercentile(durations, 50),
128
- p95Duration: this.calculatePercentile(durations, 95),
129
- p99Duration: this.calculatePercentile(durations, 99)
130
- };
131
- }
132
-
133
- /**
134
- * Gera relatório de performance completo para uma tarefa
135
- */
136
- generateReport(taskId: string): PerformanceReport {
137
- const taskMetrics = this.getTaskMetrics(taskId);
138
- const agentNames = [...new Set(taskMetrics.map(m => m.agentName))];
139
-
140
- const agentMetrics = new Map<string, AgentPerformanceSummary>();
141
- agentNames.forEach(name => {
142
- agentMetrics.set(name, this.getAgentSummary(name));
143
- });
144
-
145
- const totalDuration = taskMetrics.reduce((sum, m) => sum + m.duration, 0);
146
- const bottlenecks = this.identifyBottlenecks(agentMetrics);
147
- const recommendations = this.generateRecommendations(agentMetrics, bottlenecks);
148
-
149
- return {
150
- taskId,
151
- totalDuration,
152
- agentMetrics,
153
- bottlenecks,
154
- recommendations
155
- };
156
- }
157
-
158
- /**
159
- * Identifica bottlenecks (agentes mais lentos)
160
- */
161
- private identifyBottlenecks(agentMetrics: Map<string, AgentPerformanceSummary>): string[] {
162
- const bottlenecks: string[] = [];
163
- const avgDurations: Array<{ name: string; duration: number }> = [];
164
-
165
- agentMetrics.forEach((summary, name) => {
166
- avgDurations.push({ name, duration: summary.averageDuration });
167
- });
168
-
169
- // Ordenar por duração (maior primeiro)
170
- avgDurations.sort((a, b) => b.duration - a.duration);
171
-
172
- // Considerar os 30% mais lentos como bottlenecks
173
- const threshold = Math.ceil(avgDurations.length * 0.3);
174
- for (let i = 0; i < threshold && i < avgDurations.length; i++) {
175
- bottlenecks.push(avgDurations[i].name);
176
- }
177
-
178
- return bottlenecks;
179
- }
180
-
181
- /**
182
- * Gera recomendações baseadas nas métricas
183
- */
184
- private generateRecommendations(
185
- agentMetrics: Map<string, AgentPerformanceSummary>,
186
- bottlenecks: string[]
187
- ): string[] {
188
- const recommendations: string[] = [];
189
-
190
- // Recomendações para bottlenecks
191
- bottlenecks.forEach(agentName => {
192
- const summary = agentMetrics.get(agentName);
193
- if (summary && summary.averageDuration > 10000) {
194
- recommendations.push(
195
- `⚠️ ${agentName}: Duração média muito alta (${(summary.averageDuration / 1000).toFixed(2)}s). Considere otimização ou cache.`
196
- );
197
- }
198
- });
199
-
200
- // Recomendações para taxa de falha
201
- agentMetrics.forEach((summary, name) => {
202
- const failureRate = summary.failedExecutions / summary.totalExecutions;
203
- if (failureRate > 0.1) {
204
- recommendations.push(
205
- `🔴 ${name}: Taxa de falha alta (${(failureRate * 100).toFixed(1)}%). Investigar causas.`
206
- );
207
- }
208
- });
209
-
210
- // Recomendações para variabilidade
211
- agentMetrics.forEach((summary, name) => {
212
- const variability = summary.maxDuration / summary.minDuration;
213
- if (variability > 5 && summary.totalExecutions > 5) {
214
- recommendations.push(
215
- `📊 ${name}: Alta variabilidade na duração (${variability.toFixed(1)}x). Pode indicar dependências externas instáveis.`
216
- );
217
- }
218
- });
219
-
220
- if (recommendations.length === 0) {
221
- recommendations.push('✅ Performance está dentro dos padrões esperados.');
222
- }
223
-
224
- return recommendations;
225
- }
226
-
227
- /**
228
- * Calcula percentil de uma lista de valores
229
- */
230
- private calculatePercentile(sortedValues: number[], percentile: number): number {
231
- if (sortedValues.length === 0) return 0;
232
-
233
- const index = Math.ceil((percentile / 100) * sortedValues.length) - 1;
234
- return sortedValues[Math.max(0, index)];
235
- }
236
-
237
- /**
238
- * Limpa métricas antigas (mantém apenas últimas N)
239
- */
240
- clearOldMetrics(keepLast: number = 1000): void {
241
- if (this.metrics.length > keepLast) {
242
- this.metrics = this.metrics.slice(-keepLast);
243
- }
244
- }
245
-
246
- /**
247
- * Exporta métricas para JSON
248
- */
249
- exportMetrics(): string {
250
- return JSON.stringify(this.metrics, null, 2);
251
- }
252
-
253
- /**
254
- * Obtém estatísticas gerais
255
- */
256
- getStats(): {
257
- totalMetrics: number;
258
- totalAgents: number;
259
- totalTasks: number;
260
- averageDuration: number;
261
- } {
262
- const uniqueAgents = new Set(this.metrics.map(m => m.agentName));
263
- const uniqueTasks = new Set(this.metrics.map(m => m.taskId));
264
- const avgDuration = this.metrics.length > 0
265
- ? this.metrics.reduce((sum, m) => sum + m.duration, 0) / this.metrics.length
266
- : 0;
267
-
268
- return {
269
- totalMetrics: this.metrics.length,
270
- totalAgents: uniqueAgents.size,
271
- totalTasks: uniqueTasks.size,
272
- averageDuration: avgDuration
273
- };
274
- }
275
- }