Auto-deploy: Otimização da latência de chat (detecção rápida com Groq e streaming nativo com MiniMax M3)

This commit is contained in:
2026-06-05 01:12:05 +00:00
parent 3ca38c7436
commit 9d16105666
+71 -88
View File
@@ -2968,53 +2968,8 @@ app.post('/api/chat', requireAuth, async (req, res) => {
let detectedText = null;
let usingGroqForDetection = false;
// 1) Tentar MiniMax M3 como primário
if (process.env.MINIMAX_API_KEY) {
try {
console.log('[Smart Router] Detectando intenção via MiniMax M3...');
const r = await callMinimax({
messages: [{ role: 'user', content: promptText }],
system: systemDetector,
temperature: 0.0,
max_tokens: 20
});
detectedText = r.text;
} catch (err) {
console.error('[Smart Router] Falha na detecção via MiniMax, tentando OpenRouter...', err.message);
}
}
// 2) Fallback: OpenRouter
if (!detectedText && process.env.OPENROUTER_API_KEY) {
try {
console.log('[Smart Router] Detectando intenção via OpenRouter...');
const detectResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: process.env.OPENROUTER_MODEL || 'openai/gpt-4.1-nano',
messages: [
{ role: 'system', content: systemDetector },
{ role: 'user', content: promptText }
],
max_tokens: 20,
temperature: 0.0
})
});
if (detectResponse.ok) {
const detectData = await detectResponse.json();
detectedText = detectData.choices?.[0]?.message?.content?.toUpperCase() || null;
}
} catch (err) {
console.error('[Smart Router] Falha de detecção na OpenRouter, tentando Groq...', err.message);
}
}
// 3) Fallback final: Groq
if (!detectedText && process.env.GROQ_API_KEY) {
// 1) Tentar Groq como primário (ultrarrápido para classificação)
if (process.env.GROQ_API_KEY) {
console.log('[Smart Router] Detectando intenção via Groq (llama-3.1-8b-instant)...');
try {
const detectResponse = await fetch('https://api.groq.com/openai/v1/chat/completions', {
@@ -3039,7 +2994,52 @@ app.post('/api/chat', requireAuth, async (req, res) => {
usingGroqForDetection = !!detectedText;
}
} catch (groqErr) {
console.error('[Smart Router] Falha de detecção na API da Groq:', groqErr.message);
console.error('[Smart Router] Falha de detecção na API da Groq, tentando MiniMax...', groqErr.message);
}
}
// 2) Fallback: MiniMax M3
if (!detectedText && process.env.MINIMAX_API_KEY) {
try {
console.log('[Smart Router] Detectando intenção via MiniMax M3...');
const r = await callMinimax({
messages: [{ role: 'user', content: promptText }],
system: systemDetector,
temperature: 0.0,
max_tokens: 20
});
detectedText = r.text;
} catch (err) {
console.error('[Smart Router] Falha na detecção via MiniMax, tentando OpenRouter...', err.message);
}
}
// 3) Fallback final: OpenRouter
if (!detectedText && process.env.OPENROUTER_API_KEY) {
try {
console.log('[Smart Router] Detectando intenção via OpenRouter...');
const detectResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: process.env.OPENROUTER_MODEL || 'openai/gpt-4.1-nano',
messages: [
{ role: 'system', content: systemDetector },
{ role: 'user', content: promptText }
],
max_tokens: 20,
temperature: 0.0
})
});
if (detectResponse.ok) {
const detectData = await detectResponse.json();
detectedText = detectData.choices?.[0]?.message?.content?.toUpperCase() || null;
}
} catch (err) {
console.error('[Smart Router] Falha de detecção final na OpenRouter:', err.message);
}
}
@@ -3445,54 +3445,37 @@ app.post('/api/chat', requireAuth, async (req, res) => {
let chatResponse;
let providerUsed = 'MiniMax-M3';
// 1) Tentar MiniMax M3 (NÃO-STREAMING para o M3 porque o M3 devolve thinking blocks
// que não seguem o protocolo SSE do OpenAI; a UI consome o JSON final e faz o streaming
// via o endpoint /v1/chat/completions que vamos montar localmente).
let useMinimaxNonStream = false;
// 1) Tentar MiniMax M3 (Streaming OpenAI-compatível) para velocidade instantânea
let useMinimaxStream = false;
try {
console.log('[Smart Router] Chamando MiniMax M3 (não-streaming, JSON final)...');
const minmBase = (process.env.MINIMAX_API_BASE || 'https://api.minimax.io/v1').replace(/\/v1\/?$/, '');
const minmResp = await fetch(`${minmBase}/anthropic/v1/messages`, {
method: 'POST',
headers: {
'X-Api-Key': process.env.MINIMAX_API_KEY,
'Content-Type': 'application/json',
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: process.env.MINIMAX_MODEL || 'MiniMax-M3',
max_tokens: 4096,
temperature,
system: enrichedMessages[0].content,
messages: enrichedMessages.slice(1)
})
});
if (minmResp.ok) {
const data = await minmResp.json();
const text = (data.content || []).filter(b => b.type === 'text').map(b => b.text).join('').trim();
if (text) {
// "Transformar" resposta JSON em um objeto compatível com o resto do fluxo:
// devolvemos um Response falso com stream SSE
const sseBody =
`data: ${JSON.stringify({ choices: [{ delta: { content: text } }] })}\n\n` +
`data: [DONE]\n\n`;
chatResponse = new Response(sseBody, {
status: 200,
headers: { 'Content-Type': 'text/event-stream' }
});
useMinimaxNonStream = true;
if (process.env.MINIMAX_API_KEY) {
console.log('[Smart Router] Chamando MiniMax M3 (streaming OpenAI-compat)...');
const minmBase = (process.env.MINIMAX_API_BASE || 'https://api.minimax.io/v1').replace(/\/v1\/?$/, '');
chatResponse = await fetch(`${minmBase}/v1/chat/completions`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.MINIMAX_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: process.env.MINIMAX_MODEL || 'MiniMax-M3',
messages: enrichedMessages,
stream: true,
temperature
})
});
if (chatResponse.ok) {
useMinimaxStream = true;
} else {
console.warn('[Smart Router] M3 respondeu OK mas sem texto; caindo no OpenRouter.');
console.warn('[Smart Router] M3 streaming status', chatResponse.status, '- caindo no OpenRouter.');
}
} else {
console.warn('[Smart Router] M3 status', minmResp.status, '- caindo no OpenRouter.');
}
} catch (e) {
console.error('Erro na conexão com MiniMax M3, tentando OpenRouter...', e.message);
console.error('Erro na conexão streaming com MiniMax M3, tentando OpenRouter...', e.message);
}
// 2) Fallback: OpenRouter (streaming SSE, igual ao original)
if ((!chatResponse || !chatResponse.ok) && !useMinimaxNonStream && process.env.OPENROUTER_API_KEY) {
if ((!chatResponse || !chatResponse.ok) && !useMinimaxStream && process.env.OPENROUTER_API_KEY) {
console.log('[Smart Router] Usando OpenRouter como fallback de streaming de texto...');
providerUsed = 'OpenRouter';
try {