UNPKG

@oliverlessa/gemini-agent-lib

Version:

Uma biblioteca NodeJS para criar agentes de IA com Gemini LLM

654 lines (538 loc) 35.1 kB
// auto-gen-orchestrator.js const debug = require('./debug').create('gemini-agent-lib:orchestrator:auto-gen'); const VertexAILLM = require('./vertex-ai-llm'); // LLM VertexAI const Agent = require('./agent'); const ThinkingAgent = require('./thinking-agent'); class AutoGenOrchestrator { constructor({ apiKey, projectId, location = 'us-central1', credentialsPath, modelName = 'gemini-2.0-flash-001', mode = 'oneshot' }) { // Construtor recebe parâmetros expandidos if (!projectId) { throw new Error("Project ID do Google Cloud não fornecido para AutoGenOrchestrator."); } if (!credentialsPath) { throw new Error("Caminho para as credenciais do Google Cloud não fornecido para AutoGenOrchestrator."); } // Armazenar configurações para uso posterior na criação de agentes this.config = { apiKey, projectId, location, credentialsPath, modelName, mode }; // Criar um ThinkingAgent para o orquestrador em vez de usar VertexAILLM diretamente this.orchestratorAgent = new ThinkingAgent({ role: "Orquestrador Autônomo", objective: "Orquestrar tarefas complexas dividindo-as em sub-tarefas e delegando-as a agentes especializados", context: "Você é um orquestrador autônomo de agentes de IA. Sua função é analisar tarefas complexas, dividi-las em sub-tarefas menores, e coordenar agentes especializados para executá-las.", task: "", // Será definido dinamicamente para cada operação apiKey: apiKey, useVertexAI: true, vertexConfig: { projectId: projectId, location: location, credentialsPath: credentialsPath } }); this.agents = []; // Array para armazenar os agentes especialistas criados dinamicamente } async orchestrateTask(userTask) { debug("--- AutoGenOrchestrator - Iniciando Orquestração Autônoma ---"); debug(`Tarefa do Usuário: ${userTask}`); // *** Fase 1: Planejamento da Tarefa *** const plan = await this.generateTaskPlan(userTask); debug("--- AutoGenOrchestrator - Plano Gerado ---"); debug("Plano: %o", plan); if (!plan || !Array.isArray(plan.subTasks) || plan.subTasks.length === 0) { debug("AutoGenOrchestrator - Plano vazio ou inválido retornado pelo LLM."); return "Não foi possível gerar um plano válido para a tarefa."; // Tratar plano vazio } // *** Fase 2: Execução das Sub-Tarefas pelos Agentes *** const subTaskResults = await this.executeSubTasks(plan.subTasks); debug("--- AutoGenOrchestrator - Resultados das Sub-Tarefas ---"); debug("Resultados: %o", subTaskResults); // *** Fase 3: Geração da Resposta Final *** const finalResponse = await this.generateFinalResponse(userTask, plan, subTaskResults); debug("--- AutoGenOrchestrator - Resposta Final ---"); debug("Resposta: %o", finalResponse); debug("--- AutoGenOrchestrator - Orquestração Autônoma Concluída ---"); return finalResponse; } async generateTaskPlan(userTask) { // *** Implementar a lógica para gerar o plano de tarefas usando o ThinkingAgent *** const promptForPlanning = ` **Tarefa Principal do Usuário:** ${userTask} **Instruções:** 1. Analise a tarefa principal e crie um plano detalhado e passo a passo para alcançar o objetivo. 2. Divida a tarefa em sub-tarefas **claras, específicas e acionáveis**. Cada sub-tarefa deve ser pequena e bem definida, representando um passo lógico no caminho para completar a tarefa principal. 3. Para cada sub-tarefa, determine qual **tipo de agente** é mais adequado para executá-la de forma eficiente (ex: "Agente de Pesquisa", "Agente de Análise", "Agente de Escrita", etc.). Seja específico sobre o papel do agente. 4. **IMPORTANTE**: Identifique as dependências entre sub-tarefas. Se uma sub-tarefa precisa do resultado de outra para ser executada, especifique essa dependência. 5. Para cada sub-tarefa e agente, defina um **objetivo conciso e um prompt (tarefa)** muito **específico** que guie o agente na execução da sub-tarefa. O prompt deve ser *direto e objetivo*, indicando exatamente o que o agente deve fazer e qual resultado entregar. 6. Se alguma sub-tarefa se beneficiar da **pesquisa Google Search**, indique explicitamente qual agente deve ter a pesquisa Google habilitada. 7. Retorne o plano em formato JSON. O JSON deve ser um array de objetos, onde cada objeto representa uma sub-tarefa e tem as seguintes propriedades: "id" (identificador único da sub-tarefa), "taskDescription" (descrição da sub-tarefa), "agentRole" (papel do agente), "agentObjective" (objetivo do agente), "agentTaskPrompt" (prompt/tarefa para o agente), "enableGoogleSearch" (booleano, se o agente deve usar Google Search), "dependsOn" (array de IDs de sub-tarefas das quais esta depende). **Formato de Resposta JSON Esperado:** { "subTasks": [ { "id": "task1", "taskDescription": "Descrição da primeira sub-tarefa", "agentRole": "Papel do agente para a primeira sub-tarefa", "agentObjective": "Objetivo do agente para a primeira sub-tarefa", "agentTaskPrompt": "Prompt detalhado para o agente executar a primeira sub-tarefa", "enableGoogleSearch": false, "dependsOn": [] // Array vazio indica que não depende de nenhuma outra tarefa }, { "id": "task2", "taskDescription": "Descrição da segunda sub-tarefa", "agentRole": "Papel do agente para a segunda sub-tarefa", "agentObjective": "Objetivo do agente para a segunda sub-tarefa", "agentTaskPrompt": "Prompt detalhado para o agente executar a segunda sub-tarefa", "enableGoogleSearch": true, "dependsOn": ["task1"] // Esta sub-tarefa depende da task1 }, // ... mais sub-tarefas ... ] } `; debug("--- AutoGenOrchestrator - Gerando Plano de Tarefas com ThinkingAgent ---"); debug("Prompt para Planejamento: %o", promptForPlanning); try { // Definir a tarefa para o ThinkingAgent this.orchestratorAgent.task = promptForPlanning; // Executar a tarefa e obter a resposta bruta const rawResponse = await this.orchestratorAgent.executeTask(); // Processar a resposta usando o método processThinkingResponse const processedResponse = this.orchestratorAgent.processThinkingResponse(rawResponse); debug("--- AutoGenOrchestrator - Resposta Processada do ThinkingAgent ---"); debug("Resposta Final: %o", processedResponse.finalAnswer); debug("Passos de Raciocínio: %s", processedResponse.thinkingSteps ? "Disponíveis" : "Não disponíveis"); // Tentar extrair o JSON da resposta final try { debug("--- AutoGenOrchestrator - Tentando extrair JSON da resposta ---"); // Procurar por blocos de código JSON na resposta const jsonMatch = processedResponse.finalAnswer.match(/```json\s*([\s\S]*?)\s*```/) || processedResponse.finalAnswer.match(/```\s*([\s\S]*?)\s*```/) || processedResponse.finalAnswer.match(/{[\s\S]*?}/); if (!jsonMatch) { debug("Não foi possível encontrar um bloco JSON válido na resposta"); debug("Resposta completa: %o", processedResponse.finalAnswer); return { subTasks: [] }; } let jsonContent = jsonMatch[1] || jsonMatch[0]; // Limpar o conteúdo JSON (remover caracteres que possam interferir no parsing) jsonContent = jsonContent.replace(/```json|```/g, '').trim(); // Remover comentários que possam estar no JSON jsonContent = jsonContent.replace(/\/\/.*$/gm, ''); // Verificar se o JSON começa com { e termina com } if (!jsonContent.startsWith('{') || !jsonContent.endsWith('}')) { debug("O conteúdo extraído não parece ser um JSON válido"); // Tentar encontrar o início e fim do objeto JSON const startIndex = jsonContent.indexOf('{'); const endIndex = jsonContent.lastIndexOf('}'); if (startIndex >= 0 && endIndex > startIndex) { jsonContent = jsonContent.substring(startIndex, endIndex + 1); debug("JSON extraído após correção: %o", jsonContent); } else { debug("Não foi possível corrigir o JSON"); return { subTasks: [] }; } } // Abordagem completamente nova: extrair e reconstruir o JSON manualmente try { debug("Reconstruindo o JSON manualmente..."); // Imprimir o conteúdo JSON para depuração debug("Conteúdo JSON original: %o", jsonContent); // Verificar se o conteúdo contém a string "subTasks" if (!jsonContent.includes("subTasks")) { debug("A string 'subTasks' não foi encontrada no conteúdo JSON"); // Verificar se o conteúdo contém tarefas if (jsonContent.includes("task1") || jsonContent.includes("taskDescription")) { debug("Encontradas tarefas no conteúdo, mas sem a estrutura subTasks"); // Retornar um array vazio de subTasks e registrar o problema debug("Não foi possível extrair a estrutura de tarefas da resposta. Retornando plano vazio."); return { subTasks: [] }; } else { debug("Nenhuma tarefa encontrada no conteúdo JSON"); return { subTasks: [] }; } } // Abordagem mais direta: procurar por padrões de tarefas no texto completo // Procurar por padrões como "id": "task1" const idMatches = jsonContent.match(/"id"\s*:\s*"([^"]*)"/g) || []; debug(`Encontrados ${idMatches.length} IDs de tarefas`); if (idMatches.length === 0) { debug("Nenhum ID de tarefa encontrado no conteúdo JSON"); return { subTasks: [] }; } // Array para armazenar as tarefas reconstruídas const tasks = []; // Para cada ID encontrado, extrair os dados da tarefa correspondente for (let i = 0; i < idMatches.length; i++) { // Extrair o ID da tarefa const idMatch = idMatches[i].match(/"id"\s*:\s*"([^"]*)"/); const taskId = idMatch ? idMatch[1] : `task${i + 1}`; debug(`Processando tarefa com ID: ${taskId}`); // Encontrar a descrição da tarefa const descRegex = new RegExp(`"taskDescription"\\s*:\\s*"([^"]*)"`, 'g'); const descMatches = [...jsonContent.matchAll(descRegex)]; const descMatch = descMatches[i] || null; const taskDescription = descMatch ? descMatch[1] : `Tarefa ${i + 1}`; // Encontrar o papel do agente const roleRegex = new RegExp(`"agentRole"\\s*:\\s*"([^"]*)"`, 'g'); const roleMatches = [...jsonContent.matchAll(roleRegex)]; const roleMatch = roleMatches[i] || null; const agentRole = roleMatch ? roleMatch[1] : "Agente Especialista"; // Encontrar o objetivo do agente const objectiveRegex = new RegExp(`"agentObjective"\\s*:\\s*"([^"]*)"`, 'g'); const objectiveMatches = [...jsonContent.matchAll(objectiveRegex)]; const objectiveMatch = objectiveMatches[i] || null; const agentObjective = objectiveMatch ? objectiveMatch[1] : "Executar a tarefa designada"; // Encontrar o prompt da tarefa const promptRegex = new RegExp(`"agentTaskPrompt"\\s*:\\s*"([^"]*)"`, 'g'); const promptMatches = [...jsonContent.matchAll(promptRegex)]; const promptMatch = promptMatches[i] || null; const agentTaskPrompt = promptMatch ? promptMatch[1] : "Executar a tarefa conforme necessário"; // Encontrar se a pesquisa Google está habilitada const searchRegex = new RegExp(`"enableGoogleSearch"\\s*:\\s*(true|false)`, 'g'); const searchMatches = [...jsonContent.matchAll(searchRegex)]; const searchMatch = searchMatches[i] || null; const enableGoogleSearch = searchMatch ? searchMatch[1] === "true" : false; // Encontrar as dependências // Primeiro, encontrar todas as ocorrências de "dependsOn": [...] const dependsOnRegex = new RegExp(`"dependsOn"\\s*:\\s*\\[(.*?)\\]`, 'g'); const dependsOnMatches = [...jsonContent.matchAll(dependsOnRegex)]; const dependsOnMatch = dependsOnMatches[i] || null; let dependsOn = []; if (dependsOnMatch && dependsOnMatch[1]) { // Extrair os IDs das dependências const depsStr = dependsOnMatch[1]; // Procurar por strings entre aspas const depsRegex = /"([^"]*)"/g; let depMatch; while ((depMatch = depsRegex.exec(depsStr)) !== null) { dependsOn.push(depMatch[1]); } // Se não encontrou nenhuma dependência com aspas, tente sem aspas if (dependsOn.length === 0) { dependsOn = depsStr.split(/\s+/).filter(s => s.trim() && s !== ','); } } // Criar o objeto de tarefa com os campos extraídos const task = { id: taskId, taskDescription: taskDescription, agentRole: agentRole, agentObjective: agentObjective, agentTaskPrompt: agentTaskPrompt, enableGoogleSearch: enableGoogleSearch, dependsOn: dependsOn }; debug(`Tarefa ${i + 1} reconstruída: %o`, JSON.stringify(task, null, 2)); tasks.push(task); } // Criar o objeto JSON final const planJSON = { subTasks: tasks }; debug("JSON reconstruído manualmente: %o", JSON.stringify(planJSON, null, 2)); // Verificar se o JSON tem a estrutura esperada if (!planJSON.subTasks || !Array.isArray(planJSON.subTasks) || planJSON.subTasks.length === 0) { debug("JSON reconstruído não contém subTasks válidas"); return { subTasks: [] }; } return planJSON; // Retorna o plano em formato JSON } catch (reconstructError) { debug("Falha na reconstrução manual do JSON: %o", reconstructError); debug("Stack: %o", reconstructError.stack); // Imprimir a pilha de erros para depuração // Retornar um plano vazio em caso de falha na reconstrução debug("Falha na reconstrução do JSON. Retornando plano vazio."); return { subTasks: [] }; } debug("JSON após correções de formato: %o", jsonContent); // Tentar parsear o JSON let planJSON; try { planJSON = JSON.parse(jsonContent); } catch (parseError) { debug("Erro ao parsear JSON: %o", parseError); debug("Conteúdo JSON problemático: %o", jsonContent); // Tentativa mais agressiva de recuperação try { // Usar uma abordagem alternativa: reconstruir o JSON manualmente debug("Tentando reconstruir o JSON manualmente..."); // Extrair subTasks usando regex const subTasksMatch = jsonContent.match(/"subTasks"\s*:\s*\[([\s\S]*?)\]/); if (!subTasksMatch) { debug("Não foi possível encontrar o array de subTasks"); return { subTasks: [] }; } const subTasksContent = subTasksMatch[1]; // Dividir em objetos de tarefas individuais const taskRegex = /{[^{}]*(?:{[^{}]*}[^{}]*)*}/g; const taskMatches = subTasksContent.match(taskRegex) || []; // Processar cada tarefa individualmente const tasks = taskMatches.map(taskStr => { try { // Corrigir formato de cada tarefa let fixedTask = taskStr .replace(/"?(\w+)"?\s*:/g, '"$1":') // Adicionar aspas em chaves .replace(/,\s*}/g, '}'); // Remover vírgulas extras // Tentar parsear a tarefa return JSON.parse(fixedTask); } catch (err) { debug(`Erro ao parsear tarefa individual: ${err.message}`); // Extrair informações básicas usando regex const idMatch = taskStr.match(/"id"\s*:\s*"([^"]*)"/); const descMatch = taskStr.match(/"taskDescription"\s*:\s*"([^"]*)"/); const roleMatch = taskStr.match(/"agentRole"\s*:\s*"([^"]*)"/); return { id: idMatch ? idMatch[1] : `task${Math.floor(Math.random() * 1000)}`, taskDescription: descMatch ? descMatch[1] : "Tarefa recuperada parcialmente", agentRole: roleMatch ? roleMatch[1] : "Agente Especialista", agentObjective: "Objetivo recuperado parcialmente", agentTaskPrompt: "Executar a tarefa conforme necessário", enableGoogleSearch: false, dependsOn: [] }; } }); planJSON = { subTasks: tasks }; debug("JSON reconstruído manualmente: %o", JSON.stringify(planJSON, null, 2)); } catch (reconstructError) { debug("Falha na reconstrução manual do JSON: %o", reconstructError); return { subTasks: [] }; } } // Verificar se o JSON tem a estrutura esperada if (!planJSON.subTasks || !Array.isArray(planJSON.subTasks)) { debug("JSON não contém a estrutura esperada com 'subTasks'"); return { subTasks: [] }; } // Garantir que cada sub-tarefa tenha um ID e um array dependsOn planJSON.subTasks.forEach((task, index) => { if (!task.id) { task.id = `task${index + 1}`; debug(`Adicionado ID automático para sub-tarefa: ${task.id}`); } if (!task.dependsOn || !Array.isArray(task.dependsOn)) { task.dependsOn = []; debug(`Inicializado array dependsOn vazio para sub-tarefa: ${task.id}`); } }); debug("JSON extraído e processado com sucesso"); return planJSON; // Retorna o plano em formato JSON } catch (error) { debug("Erro ao parsear plano do ThinkingAgent como JSON: %o", error); debug("Retornando plano vazio devido a falha no parsing JSON."); return { subTasks: [] }; // Retorna plano vazio em caso de falha no parsing JSON } } catch (error) { debug("Erro ao gerar plano de tarefas com ThinkingAgent: %o", error); return { subTasks: [] }; // Retorna plano vazio em caso de erro na chamada ao ThinkingAgent } } /** * Ordena as sub-tarefas com base em suas dependências usando ordenação topológica * * @param {Array} subTasks - Array de sub-tarefas a serem ordenadas * @returns {Array} - Array de sub-tarefas ordenadas por dependências */ orderSubTasksByDependencies(subTasks) { // Criar um grafo de dependências const graph = {}; const inDegree = {}; // Inicializar o grafo e os graus de entrada subTasks.forEach(task => { const id = task.id || task.taskDescription; graph[id] = []; inDegree[id] = 0; }); // Construir o grafo de dependências subTasks.forEach(task => { const id = task.id || task.taskDescription; if (task.dependsOn && Array.isArray(task.dependsOn)) { task.dependsOn.forEach(depId => { if (graph[depId]) { graph[depId].push(id); inDegree[id]++; } else { debug(`Aviso: Dependência ${depId} não encontrada no grafo para a tarefa ${id}`); } }); } }); // Ordenação topológica usando BFS const queue = []; const orderedTaskIds = []; // Adicionar à fila todas as tarefas sem dependências subTasks.forEach(task => { const id = task.id || task.taskDescription; if (inDegree[id] === 0) { queue.push(id); } }); // Processar a fila while (queue.length > 0) { const currentId = queue.shift(); orderedTaskIds.push(currentId); // Reduzir o grau de entrada de todos os vizinhos graph[currentId].forEach(neighborId => { inDegree[neighborId]--; if (inDegree[neighborId] === 0) { queue.push(neighborId); } }); } // Verificar se há ciclos no grafo if (orderedTaskIds.length !== subTasks.length) { debug("Aviso: Detectado ciclo de dependências no plano de tarefas! Usando ordem original."); return subTasks; // Retorna a ordem original em caso de ciclo } // Mapear os IDs ordenados de volta para os objetos de sub-tarefas const taskMap = {}; subTasks.forEach(task => { const id = task.id || task.taskDescription; taskMap[id] = task; }); return orderedTaskIds.map(id => taskMap[id]); } async executeSubTasks(subTasks) { // *** Ordenar as sub-tarefas com base nas dependências *** const orderedSubTasks = this.orderSubTasksByDependencies(subTasks); debug("--- AutoGenOrchestrator - Ordem de Execução das Sub-Tarefas ---"); debug("Ordem: %s", orderedSubTasks.map(task => task.id || task.taskDescription).join(" -> ")); // *** Implementar a lógica para executar cada sub-tarefa com agentes especializados *** const subTaskResults = {}; // Objeto para armazenar resultados de cada sub-tarefa for (const subTask of orderedSubTasks) { const taskId = subTask.id || subTask.taskDescription; debug(`--- AutoGenOrchestrator - Executando Sub-Tarefa: ${subTask.taskDescription} (ID: ${taskId}) ---`); // *** Criar Agente Dinamicamente com base no plano *** const specializedAgent = this.createSpecializedAgent(subTask); if (!specializedAgent) { debug(`Erro ao criar agente especialista para sub-tarefa: ${subTask.taskDescription}`); subTaskResults[taskId] = "Erro ao criar agente especialista."; continue; // Pular para a próxima sub-tarefa em caso de falha na criação do agente } this.agents.push(specializedAgent); // Adicionar agente à lista de agentes gerenciados // *** Preparar o prompt com os resultados das dependências *** let agentTaskPrompt = subTask.agentTaskPrompt; // Se a sub-tarefa tem dependências, adicionar os resultados ao prompt if (subTask.dependsOn && Array.isArray(subTask.dependsOn) && subTask.dependsOn.length > 0) { let dependencyContext = "\n\n**Resultados de Tarefas Anteriores:**\n"; for (const depId of subTask.dependsOn) { if (subTaskResults[depId]) { dependencyContext += `\n--- Resultado da Tarefa ${depId} ---\n${subTaskResults[depId]}\n`; } else { debug(`Aviso: Resultado da dependência ${depId} não encontrado para a tarefa ${taskId}`); } } // Adicionar o contexto de dependência ao prompt agentTaskPrompt += dependencyContext; } // *** Executar a Tarefa do Agente Especialista *** try { specializedAgent.task = agentTaskPrompt; // Define o prompt específico para o agente const agentResponse = await specializedAgent.executeTask(); subTaskResults[taskId] = agentResponse; debug(`--- AutoGenOrchestrator - Sub-Tarefa Concluída: ${subTask.taskDescription} (ID: ${taskId}) ---`); debug(`Resultado do Agente ${subTask.agentRole}: %o`, agentResponse); } catch (error) { console.error(`Erro ao executar sub-tarefa "${subTask.taskDescription}" com agente ${subTask.agentRole}:`, error); subTaskResults[taskId] = `Erro na execução da sub-tarefa: ${error.message}`; } } return subTaskResults; // Retorna objeto com resultados de todas as sub-tarefas } createSpecializedAgent(subTask) { // *** Implementar a lógica para criar dinamicamente agentes especializados com base na descrição da sub-tarefa *** // *** (Usar VertexAILLM com as configurações definidas no construtor) *** debug("--- AutoGenOrchestrator - Criando Agente Especialista: %s", subTask.agentRole); try { // Usar as configurações armazenadas no objeto this.config const specializedLLM = new VertexAILLM({ // Instancia VertexAILLM para agente especialista apiKey: this.config.apiKey, projectId: this.config.projectId, location: this.config.location, credentialsPath: this.config.credentialsPath, modelName: this.config.modelName || "gemini-2.0-flash-001", // Usa o modelo definido no construtor mode: this.config.mode || "oneshot" // Usa o modo definido no construtor }); const agent = new Agent({ // Cria instância da classe Agent (ou ThinkingAgent se precisar de capacidades thinking nos especialistas) role: subTask.agentRole, objective: subTask.agentObjective, context: `Você é um agente de IA especialista com o papel de ${subTask.agentRole}. Seu objetivo é: ${subTask.agentObjective}.`, // Contexto genérico - pode ser mais específico task: subTask.agentTaskPrompt, llm: specializedLLM, tools: [], // Agentes especialistas inicialmente sem tools - pode adicionar tools específicas no plano se necessário enableGoogleSearch: subTask.enableGoogleSearch === true // Habilita Google Search se indicado no plano }); return agent; } catch (error) { console.error("Erro ao criar agente especialista:", error); return null; // Retorna null em caso de falha na criação do agente } } async generateFinalResponse(userTask, plan, subTaskResults) { // *** Implementar a lógica para gerar a resposta final combinando os resultados das sub-tarefas *** // *** Usando o ThinkingAgent para gerar uma resposta final coesa e informativa *** // Usar a ordem de execução para apresentar os resultados const orderedSubTasks = this.orderSubTasksByDependencies(plan.subTasks); let combinedResultsText = ""; for (const subTask of orderedSubTasks) { const taskId = subTask.id || subTask.taskDescription; const taskDescription = subTask.taskDescription; const result = subTaskResults[taskId] || "Resultado não disponível"; combinedResultsText += `\n**Sub-Tarefa ${taskId}:** ${taskDescription}\n**Resultado:** ${result}\n`; // Adicionar informações sobre dependências if (subTask.dependsOn && subTask.dependsOn.length > 0) { combinedResultsText += `**Dependências:** ${subTask.dependsOn.join(", ")}\n`; } } const promptForFinalResponse = ` **Tarefa Principal do Usuário:** ${userTask} **Plano de Tarefas Gerado:** ${JSON.stringify(plan, null, 2)} **Resultados das Sub-Tarefas Executadas:** ${combinedResultsText} **Instruções:** Com base no plano de tarefas e nos resultados das sub-tarefas, gere uma **resposta final clara, concisa e completa** para a tarefa principal do usuário. Integre os resultados das sub-tarefas de forma lógica e organizada para fornecer a melhor resposta possível. Sua resposta deve ser abrangente, bem estruturada e diretamente relacionada à tarefa original do usuário. Não inclua informações sobre o processo de orquestração ou os agentes utilizados, foque apenas no conteúdo da resposta. `; debug("--- AutoGenOrchestrator - Gerando Resposta Final com ThinkingAgent ---"); debug("Prompt para Resposta Final: %o", promptForFinalResponse); try { // Definir a tarefa para o ThinkingAgent this.orchestratorAgent.task = promptForFinalResponse; // Executar a tarefa e obter a resposta bruta const rawResponse = await this.orchestratorAgent.executeTask(); // Processar a resposta usando o método processThinkingResponse const processedResponse = this.orchestratorAgent.processThinkingResponse(rawResponse); debug("--- AutoGenOrchestrator - Resposta Processada do ThinkingAgent para Resposta Final ---"); debug("Resposta Final: %s", processedResponse.finalAnswer ? "Disponível" : "Não disponível"); // Retornar a resposta final processada, ou a resposta bruta se não for possível processar let finalResponseText = processedResponse.finalAnswer || rawResponse; // Verificar se a resposta final não está vazia ou é apenas caracteres especiais if (!finalResponseText || finalResponseText.trim().length < 10 || /^[\*\s]+$/.test(finalResponseText.trim())) { console.warn("Resposta final vazia ou inválida, usando resposta bruta completa"); finalResponseText = rawResponse; } debug("--- AutoGenOrchestrator - Resposta Final Gerada ---"); debug("Texto: %o", finalResponseText); return finalResponseText; } catch (error) { console.error("Erro ao gerar resposta final com ThinkingAgent:", error); return "Erro ao gerar resposta final orquestrada."; // Retorna mensagem de erro genérica } } } module.exports = AutoGenOrchestrator;