From f6bf7ce0eda2a4a08f1b8a30d53b475f06c9432b Mon Sep 17 00:00:00 2001 From: Frederico Castro Date: Sat, 28 Feb 2026 01:59:38 -0300 Subject: [PATCH] =?UTF-8?q?Adicionar=20delega=C3=A7=C3=A3o=20autom=C3=A1ti?= =?UTF-8?q?ca=20entre=20agentes=20coordenadores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/app.html | 10 ++++++++++ public/js/components/agents.js | 13 ++++++++++++ src/agents/manager.js | 36 +++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/public/app.html b/public/app.html index 2ebeea9..6f6c306 100644 --- a/public/app.html +++ b/public/app.html @@ -852,6 +852,16 @@ +
+
+ + +

Ao concluir, delega automaticamente o resultado para este agente.

+
+
+
diff --git a/public/js/components/agents.js b/public/js/components/agents.js index d3949ac..517f6b0 100644 --- a/public/js/components/agents.js +++ b/public/js/components/agents.js @@ -192,6 +192,8 @@ const AgentsUI = { const retryMax = document.getElementById('agent-retry-max'); if (retryMax) retryMax.value = '3'; + AgentsUI._populateDelegateSelect(''); + const secretsSection = document.getElementById('agent-secrets-section'); if (secretsSection) secretsSection.hidden = true; @@ -250,6 +252,8 @@ const AgentsUI = { const retryMax = document.getElementById('agent-retry-max'); if (retryMax) retryMax.value = (agent.config && agent.config.maxRetries) || '3'; + AgentsUI._populateDelegateSelect(agent.config?.delegateTo || '', agent.id); + const secretsSection = document.getElementById('agent-secrets-section'); if (secretsSection) secretsSection.hidden = false; @@ -296,6 +300,7 @@ const AgentsUI = { permissionMode: document.getElementById('agent-permission-mode')?.value || '', retryOnFailure: !!document.getElementById('agent-retry-toggle')?.checked, maxRetries: parseInt(document.getElementById('agent-retry-max')?.value) || 3, + delegateTo: document.getElementById('agent-delegate-to')?.value || '', }, }; @@ -468,6 +473,14 @@ const AgentsUI = { }); }, + _populateDelegateSelect(currentValue, excludeId) { + const select = document.getElementById('agent-delegate-to'); + if (!select) return; + const activeAgents = AgentsUI.agents.filter(a => a.status === 'active' && a.id !== excludeId); + select.innerHTML = '' + + activeAgents.map(a => ``).join(''); + }, + _setupModalListeners() { const retryToggle = document.getElementById('agent-retry-toggle'); const retryMaxGroup = document.getElementById('agent-retry-max-group'); diff --git a/src/agents/manager.js b/src/agents/manager.js index 18d63d8..4aefc07 100644 --- a/src/agents/manager.js +++ b/src/agents/manager.js @@ -172,9 +172,17 @@ export function executeTask(agentId, task, instructions, wsCallback, metadata = const agentSecrets = loadAgentSecrets(agentId); + let effectiveInstructions = instructions || ''; + const tags = agent.tags || []; + if (tags.includes('coordinator')) { + const allAgents = agentsStore.getAll().filter(a => a.id !== agentId && a.status === 'active'); + const agentList = allAgents.map(a => `- **${a.agent_name}**: ${a.description || 'Sem descrição'}`).join('\n'); + effectiveInstructions += `\n\n\n${agentList}\n`; + } + const executionId = executor.execute( agent.config, - { description: task, instructions }, + { description: task, instructions: effectiveInstructions }, { onData: (parsed, execId) => { if (cb) cb({ type: 'execution_output', executionId: execId, agentId, data: parsed }); @@ -234,6 +242,32 @@ export function executeTask(agentId, task, instructions, wsCallback, metadata = } } catch (e) { console.error('[manager] Erro ao gerar relatório:', e.message); } if (cb) cb({ type: 'execution_complete', executionId: execId, agentId, data: result }); + + const isPipelineStep = !!metadata.pipelineExecutionId; + const delegateTo = agent.config?.delegateTo; + if (!isPipelineStep && delegateTo && result.result) { + const delegateAgent = agentsStore.getById(delegateTo); + if (delegateAgent && delegateAgent.status === 'active') { + console.log(`[manager] Auto-delegando de "${agent.agent_name}" para "${delegateAgent.agent_name}"`); + if (cb) cb({ + type: 'execution_output', + executionId: execId, + agentId, + data: { type: 'system', content: `Delegando para ${delegateAgent.agent_name}...` }, + }); + setTimeout(() => { + try { + executeTask(delegateTo, result.result, null, wsCallback, { + delegatedFrom: agent.agent_name, + originalTask: taskText, + }); + } catch (delegateErr) { + console.error(`[manager] Erro ao delegar para "${delegateAgent.agent_name}":`, delegateErr.message); + if (cb) cb({ type: 'execution_error', executionId: execId, agentId: delegateTo, data: { error: delegateErr.message } }); + } + }, 3000); + } + } }, }, agentSecrets