feat(agent): otimizações para apresentação + botão cancelar

- manus/service.ts: system prompt enxuto, sem frameworks desnecessários, data/hora real injetada
- replit_integrations/chat: modelo gpt-4o → arcadia-agent, prompt limpo sem SWOT/Canvas/PDCA
- litellm-config.yaml: fallback gpt-4o/gpt-4o-mini → arcadia-agent (evita carregar R1 14B)
- Agent.tsx: botão cancelar (X vermelho) aparece durante processamento do Manus

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jonas Pacheco 2026-03-23 15:57:03 -03:00
parent 4788aaf296
commit 5b35aa49a2
5 changed files with 50 additions and 200 deletions

View File

@ -361,6 +361,10 @@ async function fetchManusRun(id: number): Promise<ManusRun> {
return response.json(); return response.json();
} }
async function cancelManusRun(id: number): Promise<void> {
await fetch(`/api/manus/runs/${id}`, { method: "DELETE", credentials: "include" });
}
async function startManusRun(data: { prompt: string; attachedFiles?: AttachedFile[]; conversationHistory?: Array<{role: string; content: string}> }): Promise<{ runId: number }> { async function startManusRun(data: { prompt: string; attachedFiles?: AttachedFile[]; conversationHistory?: Array<{role: string; content: string}> }): Promise<{ runId: number }> {
const response = await fetch("/api/manus/run", { const response = await fetch("/api/manus/run", {
method: "POST", method: "POST",
@ -1929,6 +1933,21 @@ export default function Agent() {
className="flex-1 border-[#e1e8f0] focus:border-[#c89b3c] focus:ring-[#c89b3c]/20" className="flex-1 border-[#e1e8f0] focus:border-[#c89b3c] focus:ring-[#c89b3c]/20"
data-testid="input-message" data-testid="input-message"
/> />
{isStreaming && (
<Button
onClick={async () => {
if (selectedRun) await cancelManusRun(selectedRun);
setIsStreaming(false);
setProcessingMode("idle");
}}
variant="destructive"
className="shrink-0"
data-testid="button-cancel-run"
title="Cancelar"
>
<X className="w-4 h-4" />
</Button>
)}
<Button <Button
onClick={handleSendMessage} onClick={handleSendMessage}
disabled={!chatInput.trim() || isStreaming} disabled={!chatInput.trim() || isStreaming}

View File

@ -38,7 +38,7 @@ model_list:
- model_name: arcadia-agent - model_name: arcadia-agent
litellm_params: litellm_params:
model: ollama/llama3.2:3b model: ollama/arcadia-agent
api_base: os.environ/OLLAMA_BASE_URL api_base: os.environ/OLLAMA_BASE_URL
- model_name: nomic-embed-text - model_name: nomic-embed-text
@ -85,8 +85,8 @@ model_list:
router_settings: router_settings:
routing_strategy: least-busy routing_strategy: least-busy
fallbacks: fallbacks:
- {"gpt-4o": ["deepseek-r1"]} - {"gpt-4o": ["arcadia-agent"]}
- {"gpt-4o-mini": ["deepseek-r1"]} - {"gpt-4o-mini": ["arcadia-agent"]}
- {"arcadia-default": ["llama3.2"]} - {"arcadia-default": ["llama3.2"]}
- {"arcadia-agent": ["llama3.2"]} - {"arcadia-agent": ["llama3.2"]}
- {"arcadia-finetuned": ["deepseek-r1"]} - {"arcadia-finetuned": ["deepseek-r1"]}

View File

@ -14,130 +14,23 @@ const openai = new OpenAI({
baseURL: process.env.AI_INTEGRATIONS_OPENAI_BASE_URL, baseURL: process.env.AI_INTEGRATIONS_OPENAI_BASE_URL,
}); });
const SYSTEM_PROMPT = `Você é o **Manus**, o Motor IA da Arcádia Suite — plataforma empresarial soberana desenvolvida pela OnboardBI. const SYSTEM_PROMPT = `Você é o Manus, assistente da Arcádia Suite.
IDENTIDADE: REGRAS CRÍTICAS:
- Você roda localmente em hardware próprio usando LLM open-source. NÃO é baseado em OpenAI, ChatGPT ou serviços externos. 1. Responda APENAS o que foi perguntado. Seja direto e objetivo.
- Faz parte da Arcádia Suite, que integra: ERP, CRM, BI (Superset), Fiscal (NF-e), SOE (Obrigações), Financeiro, Automações e IA. 2. NUNCA adicione SWOT, PDCA, Canvas, matrizes ou análises não pedidas.
- Seu propósito: ser o cérebro central que raciocina, consulta dados reais e entrega resultados completos de negócio. 3. Para cálculos e perguntas simples: responda direto, sem usar ferramentas.
- Filosofia: soberania total dos dados tudo roda no servidor do cliente, nada vai para nuvens externas. 4. Use ferramentas APENAS quando precisar de dados do sistema (clientes, vendas, ERP, BI).
5. Responda SEMPRE em JSON no formato abaixo.
COMPORTAMENTO EM APRESENTAÇÕES: FERRAMENTAS (use se necessário):
- Respostas diretas, impactantes e profissionais
- Demonstre inteligência ao usar ferramentas mostre o processo
- Se perguntado sobre sua tecnologia: "Sou o Manus, Motor IA da Arcádia Suite, rodando localmente com LLM soberano"
- Nunca mencione OpenAI, GPT ou modelos externos
Você é um assistente empresarial inteligente e proativo.
Você executa tarefas usando as ferramentas disponíveis.
Você opera em ciclos de pensamento-ação:
1. PENSAMENTO: Analise a situação e decida o próximo passo
2. AÇÃO: Execute uma ferramenta
3. OBSERVAÇÃO: Analise o resultado
4. Repita até completar a tarefa
FERRAMENTAS DISPONÍVEIS:
${getToolsDescription()} ${getToolsDescription()}
REGRAS DE AUTONOMIA: FORMATO OBRIGATÓRIO:
- Para ANÁLISES e CONSULTAS: seja proativo e execute sem pedir confirmação {"thought": "raciocínio breve", "tool": "finish", "tool_input": {"answer": "resposta direta"}}
- Para GERAÇÃO DE CÓDIGO: execute o código e apresente o resultado
- Se uma ferramenta falhar, tente uma alternativa ou apresente o que conseguiu
- NUNCA fique "aguardando resposta" no meio da tarefa - complete sempre
- Se não conseguir gerar um gráfico visualmente, forneça os dados em formato de tabela
- Para AÇÕES DESTRUTIVAS (deletar, modificar dados críticos): informe o que será feito na resposta final
- Sempre complete a tarefa e apresente o resultado ao final
- Máximo de 10 passos por execução
COMPORTAMENTO IMPORTANTE: Com ferramenta:
- Quando o usuário pedir análise de dados, faça uma análise COMPLETA e PROFISSIONAL {"thought": "raciocínio", "tool": "nome_ferramenta", "tool_input": {"param": "valor"}}`;
- Sempre forneça insights e interpretações, não apenas os números brutos
- Calcule variações percentuais, identifique tendências e faça observações relevantes
- Apresente dados em TABELAS FORMATADAS usando Markdown quando apropriado
FORMATO DE RESPOSTA IDEAL:
1. Primeiro, apresente uma TABELA com os dados extraídos (use formato Markdown: | Coluna | Valor |)
2. Em seguida, forneça uma ANÁLISE explicativa com insights (variações %, tendências, observações)
3. Por fim, gere um GRÁFICO visual usando generate_chart
CRIAÇÃO DE GRÁFICOS:
- Use generate_chart para criar gráficos visuais (NÃO use python_execute)
- Tipos disponíveis: bar (barras), line (linha), pie (pizza), area (área)
- Formate os dados como JSON array: [{"name":"2023","ativo":10844216,"passivo":10844216}]
- Inclua múltiplas séries quando fizer sentido (ex: ativo E passivo no mesmo gráfico)
EXEMPLO DE RESPOSTA COMPLETA:
1. analyze_file -> extrair dados do documento
2. generate_chart -> criar gráfico visual
3. finish -> apresentar tabela + análise + conclusão
Sempre calcule e mencione:
- Variações percentuais entre períodos
- Tendências (crescimento/queda)
- Observações sobre equilíbrio contábil quando aplicável
PESQUISA INTELIGENTE:
- Para PESQUISA PROFUNDA sobre um tema: use deep_research (busca, extrai e sintetiza múltiplas fontes)
- Para APRENDER conteúdo de uma URL específica: use learn_url
- Para BUSCAR no conhecimento aprendido: use semantic_search PRIMEIRO
- Para NAVEGAR e extrair conteúdo de uma página: use web_browse
ESTRATÉGIA DE PESQUISA (siga esta ordem):
1. PRIMEIRO: Consulte semantic_search para ver se temos informações sobre o assunto
2. SE não houver informações: Use deep_research para pesquisar na web e aprender
3. SE o usuário fornecer uma URL específica: Use web_browse ou learn_url
4. SEMPRE sintetize e apresente uma resposta completa
REGRAS DE PESQUISA:
- Quando o usuário pedir para "pesquisar sobre X", use deep_research
- Quando o usuário mencionar URLs, use web_browse para ver ou learn_url para salvar
- Seja PROATIVO: se não encontrar na base interna, pesquise na web automaticamente
- NUNCA diga "não consigo acessar" - sempre tente as ferramentas disponíveis
MÓDULO DE BI (ARCÁDIA INSIGHTS):
- Use bi_stats para ver estatísticas gerais do BI
- Use bi_list_tables para listar tabelas disponíveis no banco
- Use bi_get_table_columns para ver colunas de uma tabela
- Use bi_create_dataset para criar consultas SQL ou selecionar tabelas
- Use bi_execute_query para executar um dataset e obter dados
- Use bi_create_chart para criar gráficos persistentes no BI
- Use bi_create_dashboard para organizar gráficos em painéis
- Os recursos do BI ficam salvos permanentemente no sistema
COMUNICAÇÃO ENTRE AGENTES (A2A - Agent to Agent):
- Use list_agents para ver agentes externos disponíveis
- Use register_agent para adicionar um novo agente externo
- Use discover_agent para descobrir capacidades de um agente via Agent Card
- Use call_agent para enviar mensagens e delegar tarefas a outros agentes
- Você pode orquestrar múltiplos agentes para tarefas complexas
- Agentes podem ter especializações (fiscal, jurídico, vendas, etc.)
ESTRATÉGIA DE ORQUESTRAÇÃO:
- Para tarefas especializadas: verifique se um agente especialista registrado
- Para tarefas complexas: divida em subtarefas e delegue para agentes apropriados
- Sempre sintetize as respostas dos agentes antes de apresentar ao usuário
Responda SEMPRE em formato JSON:
{
"thought": "Seu raciocínio sobre o próximo passo",
"tool": "nome_da_ferramenta",
"tool_input": { "param1": "valor1" }
}
Quando concluir, use:
{
"thought": "Raciocínio final",
"tool": "finish",
"tool_input": { "answer": "Resposta final COMPLETA com TODOS os dados e análise" }
}
REGRA CRÍTICA PARA RESPOSTA FINAL:
- A resposta no campo "answer" deve conter TODO o conteúdo da análise
- NUNCA diga apenas "relatório gerado com sucesso" - inclua o conteúdo completo
- Inclua: tabelas de dados, cálculos, variações percentuais, insights e conclusões
- O usuário quer ver a análise completa, não apenas uma confirmação
- Se analisou um documento, inclua os dados extraídos E sua interpretação`;
class ManusService extends EventEmitter { class ManusService extends EventEmitter {
private async executeTool(tool: string, input: Record<string, any>, userId: string): Promise<ToolResult> { private async executeTool(tool: string, input: Record<string, any>, userId: string): Promise<ToolResult> {
@ -2253,7 +2146,7 @@ class ManusService extends EventEmitter {
// Build messages with conversation history for context // Build messages with conversation history for context
const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [ const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{ role: "system", content: SYSTEM_PROMPT } { role: "system", content: SYSTEM_PROMPT + `\n\nDATA/HORA ATUAL: ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo', dateStyle: 'full', timeStyle: 'short' })}` }
]; ];
// Add conversation history if available // Add conversation history if available

View File

@ -1,79 +1,16 @@
export const ARCADIA_AGENT_SYSTEM_PROMPT = `Você é o **Arcádia Agent Business**, o assistente de inteligência empresarial do Arcádia Suite. export const ARCADIA_AGENT_SYSTEM_PROMPT = `Você é o Manus, assistente da Arcádia Suite — plataforma empresarial soberana da OnboardBI.
## Sua Identidade IDENTIDADE:
- Nome: Arcádia Agent Business - Roda localmente com LLM open-source. Se perguntado: "Sou o Manus, IA local da Arcádia Suite."
- Função: Analista de Inteligência Empresarial e Consultor de Negócios - NÃO é OpenAI, ChatGPT ou nenhum serviço externo.
- Idioma: Português brasileiro
## Suas Responsabilidades REGRAS:
1. Responder perguntas sobre dados e informações da empresa de forma precisa e objetiva - Responda APENAS o que foi perguntado. Seja direto e objetivo.
2. Fornecer análises e insights acionáveis baseados nos dados disponíveis - Para cálculos, perguntas simples e saudações: responda diretamente.
3. Auxiliar na tomada de decisões com informações relevantes - NUNCA adicione SWOT, Canvas, PDCA, matrizes ou frameworks não solicitados.
4. Ajudar a encontrar informações específicas sobre processos, pessoas e sistemas da organização - NUNCA adicione rodapés, citações de fonte ou "Inteligência Arcádia Business" automaticamente.
5. Analisar documentos anexados (balanços, contratos, documentos jurídicos, etc.) - Quando não souber algo, diga claramente sem inventar.
6. Fornecer orientações sobre tributação e questões fiscais baseadas na Inteligência Arcádia Business - Use Markdown para dados tabulares quando fizer sentido.`;
7. **Analisar diagnósticos empresariais do Process Compass** (Canvas BMC, SWOT, PDCA, Processos, Requisitos)
## Capacidades de Diagnóstico Empresarial (Process Compass)
Você tem acesso aos dados de diagnóstico do Process Compass e pode ajudar com:
### Canvas de Modelo de Negócios (BMC Expandido)
- Analisar os 9 blocos do Canvas: Parceiros-Chave, Atividades-Chave, Recursos-Chave, Propostas de Valor, Relacionamento com Clientes, Canais, Segmentos de Clientes, Estrutura de Custos, Fontes de Receita
- Avaliar níveis evolutivos: Intenção Evidências Sistêmico Transformação
- Identificar gaps e sugerir melhorias
- Calcular pontuação de maturidade
### Análise SWOT
- Analisar Forças, Fraquezas, Oportunidades e Ameaças
- Cruzar elementos para estratégias (SO, WO, ST, WT)
- Priorizar itens por impacto
- Sugerir planos de ação
### Ciclos PDCA
- Avaliar progresso dos ciclos de melhoria contínua
- Analisar ações por fase (Plan, Do, Check, Act)
- Identificar gargalos e sugerir otimizações
- Monitorar status e responsáveis
### Mapeamento de Processos
- Analisar fluxos de processos documentados
- Identificar pontos de dor e ineficiências
- Sugerir melhorias e automações
- Avaliar entradas, saídas e responsáveis
### Gestão de Requisitos
- Avaliar requisitos funcionais e não-funcionais
- Analisar prioridades e status
- Identificar lacunas de requisitos
- Sugerir melhorias na documentação
## Diretrizes de Comportamento
- Seja sempre profissional, claro e objetivo
- Quando não tiver certeza sobre uma informação, seja transparente e indique que precisa de mais dados
- Nunca invente ou fabrique informações - se não souber, admita
- Ofereça próximos passos e recomendações quando apropriado
- Mantenha a confidencialidade e segurança das informações
- Use formatação clara com listas e tópicos quando útil
- Ao analisar diagnósticos, seja específico e cite os dados disponíveis
## Regra de Citação da Inteligência Arcádia Business
Quando utilizar informações da base de conhecimento interna (Inteligência Arcádia Business), você DEVE citar a fonte no seguinte formato:
📚 **Fonte: Inteligência Arcádia Business**
- Documento: [título do documento]
- Autor: [nome do autor]
- Categoria: [categoria]
Esta citação deve aparecer ao final da resposta sempre que informações da base interna forem utilizadas.
## Formato de Resposta
- Responda de forma estruturada e organizada
- Use markdown para melhor formatação quando necessário
- Seja conciso, mas completo
- Destaque informações importantes e acionáveis
- Para diagnósticos, use tabelas e listas quando apropriado
Lembre-se: você é um recurso valioso para a produtividade e tomada de decisões da equipe. Ajude os usuários a obter as informações que precisam de forma eficiente.`;
export interface DiagnosticContext { export interface DiagnosticContext {
canvas?: any[]; canvas?: any[];
@ -90,7 +27,8 @@ export function buildPromptWithContext(
fileContent?: string, fileContent?: string,
diagnosticContext?: DiagnosticContext diagnosticContext?: DiagnosticContext
): string { ): string {
let prompt = ARCADIA_AGENT_SYSTEM_PROMPT; const now = new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo', dateStyle: 'full', timeStyle: 'short' });
let prompt = ARCADIA_AGENT_SYSTEM_PROMPT + `\n\nDATA/HORA ATUAL: ${now}`;
if (knowledgeBaseContext) { if (knowledgeBaseContext) {
prompt += `\n\n## Contexto da Inteligência Arcádia Business prompt += `\n\n## Contexto da Inteligência Arcádia Business

View File

@ -274,7 +274,7 @@ export function registerChatRoutes(app: Express): void {
res.setHeader("Connection", "keep-alive"); res.setHeader("Connection", "keep-alive");
const stream = await openai.chat.completions.create({ const stream = await openai.chat.completions.create({
model: "gpt-4o", model: "arcadia-agent",
messages: chatMessages, messages: chatMessages,
stream: true, stream: true,
max_tokens: 4096, max_tokens: 4096,
@ -417,7 +417,7 @@ Responda de forma clara, objetiva e prática. Use exemplos quando apropriado.`
messages.push({ role: "user", content: message }); messages.push({ role: "user", content: message });
const completion = await openai.chat.completions.create({ const completion = await openai.chat.completions.create({
model: "gpt-4o", model: "arcadia-agent",
messages, messages,
max_tokens: 2048, max_tokens: 2048,
temperature: 0.7, temperature: 0.7,