feat: adiciona barra de botoes de atalho rapido de modo (musica, video, imagem, chat) no rodape com validacao cruzada

This commit is contained in:
2026-05-26 17:59:57 +00:00
parent 63ac641c5f
commit 19552a6078
4 changed files with 173 additions and 6 deletions
+34 -4
View File
@@ -255,7 +255,7 @@ Responda SEMPRE em português do Brasil.`
// Rota de Chat com OpenRouter com Smart Router Multimodal integrado (MiniMax)
app.post('/api/chat', requireAuth, async (req, res) => {
const { messages } = req.body;
const { messages, forcedIntent } = req.body;
if (!messages || !Array.isArray(messages)) {
return res.status(400).json({ error: 'Mensagens inválidas' });
@@ -267,10 +267,40 @@ app.post('/api/chat', requireAuth, async (req, res) => {
// 1. Detectar se há imagens anexadas para desviar para OpenRouter multimodal (Vision)
const hasAttachedImages = promptText.includes('*[Imagem anexada:');
let intent = 'TEXT';
let intent = forcedIntent || 'TEXT';
// Executar classificação apenas se houver prompt de texto e não houver imagens anexadas
if (!hasAttachedImages && promptText && (process.env.OPENROUTER_API_KEY || process.env.GROQ_API_KEY)) {
// 1.1 Validações cruzadas de coerência com a intenção forçada
if (forcedIntent && promptText) {
if (forcedIntent === 'IMAGE' && /música|musica|cantiga|canção|cancao|trilha|áudio|audio|ouvir|som|melodia/i.test(promptText)) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.write(`data: ${JSON.stringify({ content: "Ops! Você digitou uma solicitação de música/áudio, mas clicou no botão **Criar Imagem** (🎨). Para compor uma música, por favor, digite sua solicitação e clique no botão **Criar Música** (🎵)!" })}\n\n`);
res.write('data: [DONE]\n\n');
return res.end();
}
if (forcedIntent === 'AUDIO' && /imagem|desenhe|foto|ilustração|ilustracao|ilustre|desenho|figura|vídeo|video|animação|animacao/i.test(promptText)) {
const isVideo = /vídeo|video|animação|animacao/i.test(promptText);
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.write(`data: ${JSON.stringify({ content: `Ops! Você digitou uma solicitação de ${isVideo ? 'vídeo' : 'imagem'}, mas clicou no botão **Criar Música** (🎵). Para gerar um ${isVideo ? 'vídeo' : 'desenho/imagem'}, por favor, clique no botão correspondente (**${isVideo ? 'Criar Vídeo 🎬' : 'Criar Imagem 🎨'}**)!` })}\n\n`);
res.write('data: [DONE]\n\n');
return res.end();
}
if (forcedIntent === 'VIDEO' && /música|musica|cantiga|canção|cancao|trilha|áudio|audio|ouvir|som|melodia|imagem|desenhe|foto|ilustração/i.test(promptText)) {
const isMusic = /música|musica|cantiga|canção|cancao/i.test(promptText);
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.write(`data: ${JSON.stringify({ content: `Ops! Você digitou uma solicitação de ${isMusic ? 'música' : 'imagem'}, mas clicou no botão **Criar Vídeo** (🎬). Para realizar essa tarefa, por favor, clique no botão **${isMusic ? 'Criar Música 🎵' : 'Criar Imagem 🎨'}**!` })}\n\n`);
res.write('data: [DONE]\n\n');
return res.end();
}
}
// Executar classificação automática apenas se não houver intenção forçada, não houver imagens anexadas e houver prompt
if (!forcedIntent && !hasAttachedImages && promptText && (process.env.OPENROUTER_API_KEY || process.env.GROQ_API_KEY)) {
try {
const systemDetector = "Você é um classificador de intenções de prompt. Classifique a última mensagem do usuário em uma destas quatro categorias exatas: 'TEXT' (para conversas normais, perguntas, redação de relatórios, planejamentos, textos pedagógicos, respostas gerais), 'IMAGE' (se o usuário estiver pedindo explicitamente para gerar, desenhar, criar ou ilustrar uma imagem, figura, ilustração ou foto), 'AUDIO' (se o usuário estiver pedindo explicitamente para gerar uma música, melodia, trilha sonora, cantiga ou som), ou 'VIDEO' (se o usuário estiver pedindo explicitamente para gerar ou criar um vídeo ou animação). Responda APENAS com a palavra da categoria em letras maiúsculas: TEXT, IMAGE, AUDIO, VIDEO.";