wegho-agentes 4.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.
- package/.agents/AGENT_WORKFLOW.md +528 -0
- package/.agents/AI_COMPATIBILITY.md +332 -0
- package/.agents/CLI.md +222 -0
- package/.agents/README.md +130 -0
- package/.agents/cli.js +389 -0
- package/.agents/code-auditor-agent.ts +333 -0
- package/.agents/config.ts +145 -0
- package/.agents/context-loader.ts +300 -0
- package/.agents/core/agent-parallelizer.test.ts +94 -0
- package/.agents/core/agent-parallelizer.ts +108 -0
- package/.agents/core/architecture-agent.ts +237 -0
- package/.agents/core/base-agent.ts +311 -0
- package/.agents/core/cache-manager.test.ts +147 -0
- package/.agents/core/cache-manager.ts +184 -0
- package/.agents/core/documentation-agent.ts +183 -0
- package/.agents/core/feedback-collector.ts +207 -0
- package/.agents/core/frontend-agent.ts +210 -0
- package/.agents/core/inventory-agent.ts +582 -0
- package/.agents/core/memory-system.ts +397 -0
- package/.agents/core/quality-agent.ts +268 -0
- package/.agents/core/retry-utility.test.ts +165 -0
- package/.agents/core/retry-utility.ts +140 -0
- package/.agents/core/security-agent.ts +217 -0
- package/.agents/core/workflow-validator.test.ts +171 -0
- package/.agents/core/workflow-validator.ts +158 -0
- package/.agents/domains/README.md +53 -0
- package/.agents/domains/logistics/route-agent.ts +177 -0
- package/.agents/domains/news/cms-agent.ts +158 -0
- package/.agents/domains/news/seo-agent.ts +170 -0
- package/.agents/domains/production/production-control-agent.ts +169 -0
- package/.agents/example-learning-system.js +118 -0
- package/.agents/init.ts +164 -0
- package/.agents/memory/architecture-agent/failures.json +1 -0
- package/.agents/memory/architecture-agent/learnings.json +1 -0
- package/.agents/memory/architecture-agent/specialty.md +31 -0
- package/.agents/memory/architecture-agent/successes.json +16 -0
- package/.agents/memory/cms-agent/failures.json +1 -0
- package/.agents/memory/cms-agent/learnings.json +1 -0
- package/.agents/memory/cms-agent/specialty.md +30 -0
- package/.agents/memory/cms-agent/successes.json +16 -0
- package/.agents/memory/documentation-agent/failures.json +1 -0
- package/.agents/memory/documentation-agent/learnings.json +1 -0
- package/.agents/memory/documentation-agent/specialty.md +33 -0
- package/.agents/memory/documentation-agent/successes.json +16 -0
- package/.agents/memory/frontend-agent/failures.json +1 -0
- package/.agents/memory/frontend-agent/learnings.json +1 -0
- package/.agents/memory/frontend-agent/specialty.md +30 -0
- package/.agents/memory/frontend-agent/successes.json +16 -0
- package/.agents/memory/inventory-agent/failures.json +1 -0
- package/.agents/memory/inventory-agent/inventory/index.json +8 -0
- package/.agents/memory/inventory-agent/inventory/types.json +77716 -0
- package/.agents/memory/inventory-agent/inventory/variables.json +405 -0
- package/.agents/memory/inventory-agent/learnings.json +1 -0
- package/.agents/memory/inventory-agent/specialty.md +129 -0
- package/.agents/memory/inventory-agent/successes.json +30 -0
- package/.agents/memory/production-control-agent/failures.json +1 -0
- package/.agents/memory/production-control-agent/learnings.json +1 -0
- package/.agents/memory/production-control-agent/specialty.md +29 -0
- package/.agents/memory/production-control-agent/successes.json +16 -0
- package/.agents/memory/quality-agent/failures.json +16 -0
- package/.agents/memory/quality-agent/learnings.json +1 -0
- package/.agents/memory/quality-agent/specialty.md +31 -0
- package/.agents/memory/quality-agent/successes.json +1 -0
- package/.agents/memory/reference-repositories.json +271 -0
- package/.agents/memory/route-agent/failures.json +1 -0
- package/.agents/memory/route-agent/learnings.json +1 -0
- package/.agents/memory/route-agent/specialty.md +29 -0
- package/.agents/memory/route-agent/successes.json +16 -0
- package/.agents/memory/security-agent/failures.json +1 -0
- package/.agents/memory/security-agent/learnings.json +1 -0
- package/.agents/memory/security-agent/specialty.md +31 -0
- package/.agents/memory/security-agent/successes.json +16 -0
- package/.agents/memory/seo-agent/failures.json +1 -0
- package/.agents/memory/seo-agent/learnings.json +1 -0
- package/.agents/memory/seo-agent/specialty.md +31 -0
- package/.agents/memory/seo-agent/successes.json +16 -0
- package/.agents/orchestrator.ts +438 -0
- package/.agents/project-discovery-agent.ts +342 -0
- package/.agents/security/pentesting-agent.py +387 -0
- package/.agents/security/python-bridge.ts +193 -0
- package/.agents/security/vulnerability-db.json +201 -0
- package/.agents/task-analyzer-agent.ts +346 -0
- package/.agents/test-init-context.js +67 -0
- package/INSTALL.md +300 -0
- package/LICENSE +21 -0
- package/README.md +315 -0
- package/docs/AGENT_RULES.md +292 -0
- package/docs/BUILD_HISTORY.md +65 -0
- package/docs/DESIGN_SYSTEM.md +256 -0
- package/docs/LEARNING_SYSTEM.md +326 -0
- package/docs/SYMBOLS_TREE.md +182 -0
- package/docs/VERSION.md +6 -0
- package/docs/architecture.md +111 -0
- package/package.json +60 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Loader - Sistema "Iniciar Contexto"
|
|
3
|
+
*
|
|
4
|
+
* Carrega toda a base de conhecimento do projeto antes de iniciar qualquer implementação:
|
|
5
|
+
* - DESIGN_SYSTEM.md
|
|
6
|
+
* - SYMBOLS_TREE.md
|
|
7
|
+
* - BUILD_HISTORY.md
|
|
8
|
+
* - AGENT_RULES.md
|
|
9
|
+
* - Build atual (build-XXX.md)
|
|
10
|
+
* - Regras do usuário (MEMORY)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { PATHS, detectDomain, DomainConfig, getCurrentBuildNumber } from './config';
|
|
16
|
+
import { ProjectDiscoveryAgent } from './project-discovery-agent';
|
|
17
|
+
|
|
18
|
+
export interface ProjectContext {
|
|
19
|
+
designSystem: string;
|
|
20
|
+
symbolsTree: string;
|
|
21
|
+
buildHistory: string;
|
|
22
|
+
agentRules: string;
|
|
23
|
+
currentBuild: string | null;
|
|
24
|
+
domainConfig: DomainConfig;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
projectProfile?: any; // ProjectProfile do discovery
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Carrega o conteúdo de um arquivo markdown
|
|
31
|
+
*/
|
|
32
|
+
function loadMarkdown(filePath: string): string {
|
|
33
|
+
try {
|
|
34
|
+
const fullPath = path.resolve(process.cwd(), filePath);
|
|
35
|
+
if (fs.existsSync(fullPath)) {
|
|
36
|
+
return fs.readFileSync(fullPath, 'utf-8');
|
|
37
|
+
}
|
|
38
|
+
console.warn(`⚠️ Arquivo não encontrado: ${filePath}`);
|
|
39
|
+
return '';
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(`❌ Erro ao carregar ${filePath}:`, error);
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Carrega o arquivo de build atual
|
|
48
|
+
*/
|
|
49
|
+
function loadCurrentBuild(): string | null {
|
|
50
|
+
const buildNumber = getCurrentBuildNumber();
|
|
51
|
+
const buildPath = `${PATHS.builds}/build-${String(buildNumber).padStart(3, '0')}.md`;
|
|
52
|
+
|
|
53
|
+
if (fs.existsSync(buildPath)) {
|
|
54
|
+
return loadMarkdown(buildPath);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log(`ℹ️ Build atual (build-${buildNumber}) ainda não existe. Será criado ao finalizar a primeira tarefa.`);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Executa pré-verificações do projeto
|
|
63
|
+
*/
|
|
64
|
+
async function runPreChecks(): Promise<{ success: boolean; issues: string[] }> {
|
|
65
|
+
const issues: string[] = [];
|
|
66
|
+
|
|
67
|
+
// Verificar se estrutura de documentação existe
|
|
68
|
+
if (!fs.existsSync(PATHS.docs)) {
|
|
69
|
+
issues.push('⚠️ Diretório docs/ não encontrado');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!fs.existsSync(PATHS.designSystem)) {
|
|
73
|
+
issues.push('⚠️ DESIGN_SYSTEM.md não encontrado');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!fs.existsSync(PATHS.symbolsTree)) {
|
|
77
|
+
issues.push('⚠️ SYMBOLS_TREE.md não encontrado');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!fs.existsSync(PATHS.buildHistory)) {
|
|
81
|
+
issues.push('⚠️ BUILD_HISTORY.md não encontrado');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!fs.existsSync(PATHS.agentRules)) {
|
|
85
|
+
issues.push('⚠️ AGENT_RULES.md não encontrado');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Verificar package.json
|
|
89
|
+
if (!fs.existsSync('package.json')) {
|
|
90
|
+
issues.push('⚠️ package.json não encontrado');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
success: issues.length === 0,
|
|
95
|
+
issues,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* FUNÇÃO PRINCIPAL: Inicializar Contexto
|
|
101
|
+
*
|
|
102
|
+
* Chamada quando o usuário escreve "inicie o contexto"
|
|
103
|
+
*/
|
|
104
|
+
export async function initializeContext(interactive: boolean = true): Promise<ProjectContext> {
|
|
105
|
+
let projectProfile: any;
|
|
106
|
+
|
|
107
|
+
// NOVO: Descoberta interativa do projeto
|
|
108
|
+
if (interactive) {
|
|
109
|
+
const discovery = new ProjectDiscoveryAgent();
|
|
110
|
+
const isNewProject = discovery.detectNewProject();
|
|
111
|
+
|
|
112
|
+
if (isNewProject) {
|
|
113
|
+
console.log('✨ Projeto novo detectado!\n');
|
|
114
|
+
console.log('Vamos fazer algumas perguntas para configurar os agentes ideais...\n');
|
|
115
|
+
|
|
116
|
+
// Executar descoberta interativa
|
|
117
|
+
projectProfile = await discovery.discoverProject();
|
|
118
|
+
|
|
119
|
+
// Gerar recomendações
|
|
120
|
+
const recommendations = discovery.generateRecommendations(projectProfile);
|
|
121
|
+
|
|
122
|
+
// Mostrar relatório
|
|
123
|
+
const report = discovery.generateReport(projectProfile, recommendations);
|
|
124
|
+
console.log(report);
|
|
125
|
+
|
|
126
|
+
// Salvar perfil
|
|
127
|
+
discovery.saveProfile(projectProfile);
|
|
128
|
+
|
|
129
|
+
// TODO: Auto-criar agentes recomendados com autoCreate: true
|
|
130
|
+
console.log('🚀 Criando agentes recomendados...\n');
|
|
131
|
+
// (implementação futura)
|
|
132
|
+
} else {
|
|
133
|
+
console.log('📦 Projeto existente detectado. Carregando perfil...\n');
|
|
134
|
+
|
|
135
|
+
// Tentar carregar perfil existente
|
|
136
|
+
if (fs.existsSync('docs/PROJECT_PROFILE.json')) {
|
|
137
|
+
projectProfile = JSON.parse(fs.readFileSync('docs/PROJECT_PROFILE.json', 'utf-8'));
|
|
138
|
+
console.log(`✅ Perfil carregado: ${projectProfile.projectName}\n`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Passo 1: Executar pré-verificações
|
|
144
|
+
console.log('📋 Verificando estrutura do projeto...');
|
|
145
|
+
const preCheckResult = await runPreChecks();
|
|
146
|
+
|
|
147
|
+
if (!preCheckResult.success) {
|
|
148
|
+
console.warn('\n⚠️ Avisos encontrados:');
|
|
149
|
+
preCheckResult.issues.forEach((issue) => console.warn(` ${issue}`));
|
|
150
|
+
console.log('');
|
|
151
|
+
} else {
|
|
152
|
+
console.log(' ✅ Estrutura do projeto OK\n');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Passo 2: Carregar documentação base
|
|
156
|
+
console.log('📚 Carregando documentação base...');
|
|
157
|
+
const designSystem = loadMarkdown(PATHS.designSystem);
|
|
158
|
+
const symbolsTree = loadMarkdown(PATHS.symbolsTree);
|
|
159
|
+
const buildHistory = loadMarkdown(PATHS.buildHistory);
|
|
160
|
+
const agentRules = loadMarkdown(PATHS.agentRules);
|
|
161
|
+
console.log(' ✅ Documentação carregada\n');
|
|
162
|
+
|
|
163
|
+
// Passo 3: Carregar build atual
|
|
164
|
+
console.log('📦 Carregando build atual...');
|
|
165
|
+
const currentBuild = loadCurrentBuild();
|
|
166
|
+
console.log(` ${currentBuild ? '✅' : 'ℹ️'} Build atual ${currentBuild ? 'carregado' : 'será criado'}\n`);
|
|
167
|
+
|
|
168
|
+
// Passo 4: Detectar domínio do projeto
|
|
169
|
+
console.log('🎯 Detectando domínio do projeto...');
|
|
170
|
+
const domainConfig = projectProfile ?
|
|
171
|
+
{ name: projectProfile.domain, agents: [], description: projectProfile.customDomain || projectProfile.domain } :
|
|
172
|
+
detectDomain();
|
|
173
|
+
console.log(` ✅ Domínio detectado: ${domainConfig.description || domainConfig.name}`);
|
|
174
|
+
console.log(` 📌 Agentes especializados: ${domainConfig.agents.join(', ') || 'nenhum'}\n`);
|
|
175
|
+
|
|
176
|
+
// Passo 5: Validar regras do usuário (MEMORY)
|
|
177
|
+
console.log('📜 Carregando regras do usuário (MEMORY)...');
|
|
178
|
+
console.log(' ✅ Regras globais carregadas');
|
|
179
|
+
console.log(' ✅ Regras gerais (6 passos + relatórios) carregadas\n');
|
|
180
|
+
|
|
181
|
+
// Passo 6: Resumo final
|
|
182
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
183
|
+
console.log('✅ CONTEXTO CARREGADO COM SUCESSO!');
|
|
184
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
185
|
+
|
|
186
|
+
console.log('📊 Resumo do Contexto:');
|
|
187
|
+
console.log(` • Sistema de Design: ${designSystem ? '✅ Carregado' : '❌ Não encontrado'}`);
|
|
188
|
+
console.log(` • Árvore de Símbolos: ${symbolsTree ? '✅ Carregada' : '❌ Não encontrada'}`);
|
|
189
|
+
console.log(` • Histórico de Builds: ${buildHistory ? '✅ Carregado' : '❌ Não encontrado'}`);
|
|
190
|
+
console.log(` • Regras de Agentes: ${agentRules ? '✅ Carregadas' : '❌ Não encontradas'}`);
|
|
191
|
+
console.log(` • Build Atual: ${currentBuild ? '✅ Carregado' : 'ℹ️ Será criado'}`);
|
|
192
|
+
console.log(` • Domínio: ${domainConfig.description || domainConfig.name}`);
|
|
193
|
+
if (projectProfile) {
|
|
194
|
+
console.log(` • Perfil do Projeto: ✅ ${projectProfile.projectName}`);
|
|
195
|
+
}
|
|
196
|
+
console.log('');
|
|
197
|
+
|
|
198
|
+
console.log('🚀 Sistema pronto para implementar!\n');
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
designSystem,
|
|
202
|
+
symbolsTree,
|
|
203
|
+
buildHistory,
|
|
204
|
+
agentRules,
|
|
205
|
+
currentBuild,
|
|
206
|
+
domainConfig,
|
|
207
|
+
timestamp: new Date().toISOString(),
|
|
208
|
+
projectProfile,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
// Passo 1: Executar pré-verificações
|
|
214
|
+
console.log('📋 Passo 1: Verificando estrutura do projeto...');
|
|
215
|
+
const preCheckResult = await runPreChecks();
|
|
216
|
+
|
|
217
|
+
if (!preCheckResult.success) {
|
|
218
|
+
console.warn('\n⚠️ Avisos encontrados:');
|
|
219
|
+
preCheckResult.issues.forEach((issue) => console.warn(` ${issue}`));
|
|
220
|
+
console.log('');
|
|
221
|
+
} else {
|
|
222
|
+
console.log(' ✅ Estrutura do projeto OK\n');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Passo 2: Carregar documentação base
|
|
226
|
+
console.log('📚 Passo 2: Carregando documentação base...');
|
|
227
|
+
const designSystem = loadMarkdown(PATHS.designSystem);
|
|
228
|
+
const symbolsTree = loadMarkdown(PATHS.symbolsTree);
|
|
229
|
+
const buildHistory = loadMarkdown(PATHS.buildHistory);
|
|
230
|
+
const agentRules = loadMarkdown(PATHS.agentRules);
|
|
231
|
+
console.log(' ✅ Documentação carregada\n');
|
|
232
|
+
|
|
233
|
+
// Passo 3: Carregar build atual
|
|
234
|
+
console.log('📦 Passo 3: Carregando build atual...');
|
|
235
|
+
const currentBuild = loadCurrentBuild();
|
|
236
|
+
console.log(` ${currentBuild ? '✅' : 'ℹ️'} Build atual ${currentBuild ? 'carregado' : 'será criado'}\n`);
|
|
237
|
+
|
|
238
|
+
// Passo 4: Detectar domínio do projeto
|
|
239
|
+
console.log('🎯 Passo 4: Detectando domínio do projeto...');
|
|
240
|
+
const domainConfig = detectDomain();
|
|
241
|
+
console.log(` ✅ Domínio detectado: ${domainConfig.description || domainConfig.name}`);
|
|
242
|
+
console.log(` 📌 Agentes especializados: ${domainConfig.agents.join(', ') || 'nenhum'}\n`);
|
|
243
|
+
|
|
244
|
+
// Passo 5: Validar regras do usuário (MEMORY)
|
|
245
|
+
console.log('📜 Passo 5: Carregando regras do usuário (MEMORY)...');
|
|
246
|
+
console.log(' ✅ Regras globais carregadas');
|
|
247
|
+
console.log(' ✅ Regras gerais (6 passos + relatórios) carregadas\n');
|
|
248
|
+
|
|
249
|
+
// Passo 6: Resumo final
|
|
250
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
251
|
+
console.log('✅ CONTEXTO CARREGADO COM SUCESSO!');
|
|
252
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
253
|
+
|
|
254
|
+
console.log('📊 Resumo do Contexto:');
|
|
255
|
+
console.log(` • Sistema de Design: ${designSystem ? '✅ Carregado' : '❌ Não encontrado'}`);
|
|
256
|
+
console.log(` • Árvore de Símbolos: ${symbolsTree ? '✅ Carregada' : '❌ Não encontrada'}`);
|
|
257
|
+
console.log(` • Histórico de Builds: ${buildHistory ? '✅ Carregado' : '❌ Não encontrado'}`);
|
|
258
|
+
console.log(` • Regras de Agentes: ${agentRules ? '✅ Carregadas' : '❌ Não encontradas'}`);
|
|
259
|
+
console.log(` • Build Atual: ${currentBuild ? '✅ Carregado' : 'ℹ️ Será criado'}`);
|
|
260
|
+
console.log(` • Domínio: ${domainConfig.description || domainConfig.name}`);
|
|
261
|
+
console.log('');
|
|
262
|
+
|
|
263
|
+
console.log('🚀 Sistema pronto para implementar!\n');
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
designSystem,
|
|
267
|
+
symbolsTree,
|
|
268
|
+
buildHistory,
|
|
269
|
+
agentRules,
|
|
270
|
+
currentBuild,
|
|
271
|
+
domainConfig,
|
|
272
|
+
timestamp: new Date().toISOString(),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Valida se o contexto foi carregado antes de prosseguir
|
|
278
|
+
*/
|
|
279
|
+
export function validateContextLoaded(context: ProjectContext | null): boolean {
|
|
280
|
+
if (!context) {
|
|
281
|
+
console.error('❌ ERRO: Contexto não foi carregado!');
|
|
282
|
+
console.error('💡 Execute "inicie o contexto" antes de prosseguir.\n');
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Exibe resumo do contexto atual
|
|
291
|
+
*/
|
|
292
|
+
export function printContextSummary(context: ProjectContext): void {
|
|
293
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
294
|
+
console.log('📋 RESUMO DO CONTEXTO ATUAL');
|
|
295
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
296
|
+
console.log(`🕐 Carregado em: ${new Date(context.timestamp).toLocaleString('pt-BR')}`);
|
|
297
|
+
console.log(`🎯 Domínio: ${context.domainConfig.description || context.domainConfig.name}`);
|
|
298
|
+
console.log(`📦 Build: ${getCurrentBuildNumber()}`);
|
|
299
|
+
console.log('');
|
|
300
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Testes para AgentParallelizer
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { AgentParallelizer } from './agent-parallelizer';
|
|
6
|
+
import { AgentAssignment } from '../task-analyzer-agent';
|
|
7
|
+
|
|
8
|
+
describe('AgentParallelizer', () => {
|
|
9
|
+
describe('groupAgents', () => {
|
|
10
|
+
test('deve agrupar agentes independentes no mesmo grupo', () => {
|
|
11
|
+
const agents: AgentAssignment[] = [
|
|
12
|
+
{ agentName: 'security-agent', subtask: 'test', priority: 1, confidence: 0.9 },
|
|
13
|
+
{ agentName: 'documentation-agent', subtask: 'test', priority: 2, confidence: 0.9 },
|
|
14
|
+
{ agentName: 'cms-agent', subtask: 'test', priority: 3, confidence: 0.9 }
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const groups = AgentParallelizer.groupAgents(agents);
|
|
18
|
+
|
|
19
|
+
// Todos são independentes, devem estar no mesmo grupo
|
|
20
|
+
expect(groups.length).toBe(1);
|
|
21
|
+
expect(groups[0].length).toBe(3);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('deve separar agentes com dependências em grupos diferentes', () => {
|
|
25
|
+
const agents: AgentAssignment[] = [
|
|
26
|
+
{ agentName: 'architecture-agent', subtask: 'test', priority: 1, confidence: 0.9 },
|
|
27
|
+
{ agentName: 'frontend-agent', subtask: 'test', priority: 2, confidence: 0.9 }
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const groups = AgentParallelizer.groupAgents(agents);
|
|
31
|
+
|
|
32
|
+
// frontend-agent depende de architecture-agent
|
|
33
|
+
expect(groups.length).toBe(2);
|
|
34
|
+
expect(groups[0][0].agentName).toBe('architecture-agent');
|
|
35
|
+
expect(groups[1][0].agentName).toBe('frontend-agent');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('deve respeitar dependências complexas', () => {
|
|
39
|
+
const agents: AgentAssignment[] = [
|
|
40
|
+
{ agentName: 'architecture-agent', subtask: 'test', priority: 1, confidence: 0.9 },
|
|
41
|
+
{ agentName: 'frontend-agent', subtask: 'test', priority: 2, confidence: 0.9 },
|
|
42
|
+
{ agentName: 'quality-agent', subtask: 'test', priority: 3, confidence: 0.9 },
|
|
43
|
+
{ agentName: 'security-agent', subtask: 'test', priority: 4, confidence: 0.9 }
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const groups = AgentParallelizer.groupAgents(agents);
|
|
47
|
+
|
|
48
|
+
// architecture primeiro
|
|
49
|
+
// frontend e security em paralelo
|
|
50
|
+
// quality por último (depende de frontend e architecture)
|
|
51
|
+
expect(groups.length).toBeGreaterThanOrEqual(2);
|
|
52
|
+
expect(groups[0][0].agentName).toBe('architecture-agent');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('canRunInParallel', () => {
|
|
57
|
+
test('deve retornar true para agentes independentes', () => {
|
|
58
|
+
const result = AgentParallelizer.canRunInParallel('security-agent', 'documentation-agent');
|
|
59
|
+
expect(result).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('deve retornar false se um depende do outro', () => {
|
|
63
|
+
const result = AgentParallelizer.canRunInParallel('frontend-agent', 'architecture-agent');
|
|
64
|
+
expect(result).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('estimateTimeReduction', () => {
|
|
69
|
+
test('deve calcular redução de tempo corretamente', () => {
|
|
70
|
+
const agents: AgentAssignment[] = [
|
|
71
|
+
{ agentName: 'security-agent', subtask: 'test', priority: 1, confidence: 0.9 },
|
|
72
|
+
{ agentName: 'documentation-agent', subtask: 'test', priority: 2, confidence: 0.9 },
|
|
73
|
+
{ agentName: 'cms-agent', subtask: 'test', priority: 3, confidence: 0.9 }
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const estimate = AgentParallelizer.estimateTimeReduction(agents);
|
|
77
|
+
|
|
78
|
+
expect(estimate.sequential).toBeGreaterThan(estimate.parallel);
|
|
79
|
+
expect(estimate.reduction).toBeGreaterThan(0);
|
|
80
|
+
expect(estimate.reduction).toBeLessThanOrEqual(100);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('deve retornar 0% de redução para agente único', () => {
|
|
84
|
+
const agents: AgentAssignment[] = [
|
|
85
|
+
{ agentName: 'security-agent', subtask: 'test', priority: 1, confidence: 0.9 }
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
const estimate = AgentParallelizer.estimateTimeReduction(agents);
|
|
89
|
+
|
|
90
|
+
expect(estimate.sequential).toBe(estimate.parallel);
|
|
91
|
+
expect(estimate.reduction).toBe(0);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Parallelization Utility
|
|
3
|
+
*
|
|
4
|
+
* Identifica agentes independentes e os executa em paralelo
|
|
5
|
+
* para reduzir tempo total de execução
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { AgentAssignment } from '../task-analyzer-agent';
|
|
9
|
+
|
|
10
|
+
export interface AgentGroup {
|
|
11
|
+
parallel: AgentAssignment[];
|
|
12
|
+
sequential: AgentAssignment[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class AgentParallelizer {
|
|
16
|
+
/**
|
|
17
|
+
* Mapa de dependências entre agentes
|
|
18
|
+
* Agentes que dependem de outros devem executar depois
|
|
19
|
+
*/
|
|
20
|
+
private static readonly DEPENDENCIES: Record<string, string[]> = {
|
|
21
|
+
// Architecture deve rodar antes de outros agentes técnicos
|
|
22
|
+
'frontend-agent': ['architecture-agent'],
|
|
23
|
+
'security-agent': [], // Independente
|
|
24
|
+
'quality-agent': ['frontend-agent', 'architecture-agent'],
|
|
25
|
+
'documentation-agent': [], // Pode rodar em paralelo
|
|
26
|
+
|
|
27
|
+
// Agentes de domínio geralmente independentes
|
|
28
|
+
'cms-agent': [],
|
|
29
|
+
'seo-agent': [],
|
|
30
|
+
'production-control-agent': [],
|
|
31
|
+
'route-agent': [],
|
|
32
|
+
|
|
33
|
+
// Inventory deve rodar primeiro (coleta informações)
|
|
34
|
+
'pentesting-agent': ['security-agent']
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Agrupa agentes em grupos paralelos e sequenciais
|
|
39
|
+
*/
|
|
40
|
+
static groupAgents(agents: AgentAssignment[]): AgentAssignment[][] {
|
|
41
|
+
const groups: AgentAssignment[][] = [];
|
|
42
|
+
const processed = new Set<string>();
|
|
43
|
+
const remaining = [...agents].sort((a, b) => a.priority - b.priority);
|
|
44
|
+
|
|
45
|
+
while (remaining.length > 0) {
|
|
46
|
+
const currentGroup: AgentAssignment[] = [];
|
|
47
|
+
|
|
48
|
+
// Encontrar agentes que podem executar em paralelo
|
|
49
|
+
for (let i = remaining.length - 1; i >= 0; i--) {
|
|
50
|
+
const agent = remaining[i];
|
|
51
|
+
const dependencies = this.DEPENDENCIES[agent.agentName] || [];
|
|
52
|
+
|
|
53
|
+
// Verificar se todas as dependências já foram processadas
|
|
54
|
+
const canRun = dependencies.every(dep => processed.has(dep));
|
|
55
|
+
|
|
56
|
+
if (canRun) {
|
|
57
|
+
currentGroup.push(agent);
|
|
58
|
+
remaining.splice(i, 1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (currentGroup.length === 0) {
|
|
63
|
+
// Deadlock - alguma dependência circular ou não resolvida
|
|
64
|
+
// Executar o próximo agente sequencialmente
|
|
65
|
+
currentGroup.push(remaining.shift()!);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Marcar agentes como processados
|
|
69
|
+
currentGroup.forEach(agent => processed.add(agent.agentName));
|
|
70
|
+
groups.push(currentGroup);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return groups;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Verifica se dois agentes podem executar em paralelo
|
|
78
|
+
*/
|
|
79
|
+
static canRunInParallel(agent1: string, agent2: string): boolean {
|
|
80
|
+
const deps1 = this.DEPENDENCIES[agent1] || [];
|
|
81
|
+
const deps2 = this.DEPENDENCIES[agent2] || [];
|
|
82
|
+
|
|
83
|
+
// Não podem rodar em paralelo se um depende do outro
|
|
84
|
+
return !deps1.includes(agent2) && !deps2.includes(agent1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Estima redução de tempo com paralelização
|
|
89
|
+
*/
|
|
90
|
+
static estimateTimeReduction(agents: AgentAssignment[]): {
|
|
91
|
+
sequential: number;
|
|
92
|
+
parallel: number;
|
|
93
|
+
reduction: number;
|
|
94
|
+
} {
|
|
95
|
+
const groups = this.groupAgents(agents);
|
|
96
|
+
const avgTimePerAgent = 10; // segundos (estimativa)
|
|
97
|
+
|
|
98
|
+
const sequentialTime = agents.length * avgTimePerAgent;
|
|
99
|
+
const parallelTime = groups.length * avgTimePerAgent;
|
|
100
|
+
const reduction = ((sequentialTime - parallelTime) / sequentialTime) * 100;
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
sequential: sequentialTime,
|
|
104
|
+
parallel: parallelTime,
|
|
105
|
+
reduction: Math.round(reduction)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|