Refactor: Renomeacao e modernizacao completa para Pedagog / PedagogIA

This commit is contained in:
2026-08-31 10:34:33 +00:00
parent 00341ebf64
commit f3350b0969
16 changed files with 225 additions and 176 deletions
+65 -42
View File
@@ -60,11 +60,11 @@ async function callMinimax({ messages, temperature = 0.5, max_tokens = 1500, sys
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));
app.use(cookieParser(process.env.SESSION_SECRET || 'camila-secret'));
app.use(cookieParser(process.env.SESSION_SECRET || 'pedagog-secret'));
// Middleware para verificar autenticação
const requireAuth = (req, res, next) => {
const session = req.signedCookies.camila_session || req.cookies.camila_session;
const session = req.signedCookies.pedagog_session || req.cookies.pedagog_session || req.signedCookies.camila_session || req.cookies.camila_session;
if (session === 'authenticated') {
next();
} else {
@@ -115,9 +115,9 @@ const TEMPERATURE_PRESETS = {
};
let agentConfigCache = {
agentName: "Kemily",
kemilyAvatarUrl: "assets/kemily.png",
camilaAvatarUrl: "assets/camila_prof.png",
agentName: "PedagogIA",
iaAvatarUrl: "assets/pedagog_ia.png",
userAvatarUrl: "assets/pedagog_user.png",
temperaturePreset: "equilibrado"
};
@@ -127,27 +127,27 @@ function readAgentConfig() {
async function writeAgentConfig(config) {
agentConfigCache = {
agentName: config.agentName,
kemilyAvatarUrl: config.kemilyAvatarUrl,
camilaAvatarUrl: config.camilaAvatarUrl,
agentName: config.agentName || "PedagogIA",
iaAvatarUrl: config.iaAvatarUrl || config.kemilyAvatarUrl || "assets/pedagog_ia.png",
userAvatarUrl: config.userAvatarUrl || config.camilaAvatarUrl || "assets/pedagog_user.png",
temperaturePreset: config.temperaturePreset || 'equilibrado'
};
try {
await dbPool.query(
`INSERT INTO escola.config (key, agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset, updated_at)
`INSERT INTO escola.config (key, agent_name, ia_avatar_url, user_avatar_url, temperature_preset, updated_at)
VALUES ('current', $1, $2, $3, $4, NOW())
ON CONFLICT (key) DO UPDATE SET
agent_name = EXCLUDED.agent_name,
kemily_avatar_url = EXCLUDED.kemily_avatar_url,
camila_avatar_url = EXCLUDED.camila_avatar_url,
ia_avatar_url = EXCLUDED.ia_avatar_url,
user_avatar_url = EXCLUDED.user_avatar_url,
temperature_preset = EXCLUDED.temperature_preset,
updated_at = NOW();`,
[config.agentName, config.kemilyAvatarUrl, config.camilaAvatarUrl, config.temperaturePreset || 'equilibrado']
[agentConfigCache.agentName, agentConfigCache.iaAvatarUrl, agentConfigCache.userAvatarUrl, agentConfigCache.temperaturePreset]
);
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(config, null, 2), 'utf8');
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(agentConfigCache, null, 2), 'utf8');
const botConfigDir = path.join(__dirname, '..', 'BotVPS', 'data');
if (fs.existsSync(botConfigDir)) {
fs.writeFileSync(path.join(botConfigDir, 'agent_config.json'), JSON.stringify(config, null, 2), 'utf8');
fs.writeFileSync(path.join(botConfigDir, 'agent_config.json'), JSON.stringify(agentConfigCache, null, 2), 'utf8');
}
} catch (e) {
console.error('Erro ao salvar agent_config no banco:', e);
@@ -1386,7 +1386,7 @@ app.post('/api/cartazes/generate', requireAuth, async (req, res) => {
try {
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
// 1. Gerar Conteúdo do Cartaz
const posterPrompt = `Você é a ${agentName}, assistente pedagógica da professora Camila Martella Gasparini Reifonas.
@@ -1642,7 +1642,7 @@ Return ONLY the English prompt, nothing else.`;
if (!tema) return res.status(400).json({ error: 'Tema ou layers_manual são obrigatórios.' });
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
const segmentPrompt = `Você é a ${agentName}, assistente pedagógica.
Tema: "${tema}" / Título: "${titulo || ''}"
@@ -2067,14 +2067,14 @@ app.get('/api/agent-config', requireAuth, (req, res) => {
// Rota POST para atualizar configurações do agente
app.post('/api/agent-config', requireAuth, async (req, res) => {
const { agentName, kemilyAvatarUrl, camilaAvatarUrl, temperaturePreset } = req.body;
const { agentName, iaAvatarUrl, userAvatarUrl, kemilyAvatarUrl, camilaAvatarUrl, temperaturePreset } = req.body;
if (!agentName) {
return res.status(400).json({ error: 'Nome do agente é obrigatório' });
}
const config = {
agentName: agentName.trim(),
kemilyAvatarUrl: kemilyAvatarUrl || "assets/kemily.png",
camilaAvatarUrl: camilaAvatarUrl || "assets/camila_prof.png",
iaAvatarUrl: iaAvatarUrl || kemilyAvatarUrl || "assets/pedagog_ia.png",
userAvatarUrl: userAvatarUrl || camilaAvatarUrl || "assets/pedagog_user.png",
temperaturePreset: temperaturePreset || 'equilibrado'
};
await writeAgentConfig(config);
@@ -2473,21 +2473,37 @@ async function initDatabase() {
}
// 1. Sincronizar cache de configurações do agente ou migrar
const configRes = await dbPool.query("SELECT agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset FROM escola.config WHERE key = 'current';");
try {
await dbPool.query(`
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='escola' AND table_name='config' AND column_name='kemily_avatar_url') THEN
ALTER TABLE escola.config RENAME COLUMN kemily_avatar_url TO ia_avatar_url;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='escola' AND table_name='config' AND column_name='camila_avatar_url') THEN
ALTER TABLE escola.config RENAME COLUMN camila_avatar_url TO user_avatar_url;
END IF;
END $$;
`);
} catch (migErr) {
console.warn('[Database Init] Aviso ao verificar colunas da tabela escola.config:', migErr.message);
}
const configRes = await dbPool.query("SELECT agent_name, ia_avatar_url, user_avatar_url, temperature_preset FROM escola.config WHERE key = 'current';");
if (configRes.rows.length > 0) {
agentConfigCache = {
agentName: configRes.rows[0].agent_name,
kemilyAvatarUrl: configRes.rows[0].kemily_avatar_url,
camilaAvatarUrl: configRes.rows[0].camila_avatar_url,
temperaturePreset: configRes.rows[0].temperature_preset
agentName: configRes.rows[0].agent_name || "PedagogIA",
iaAvatarUrl: configRes.rows[0].ia_avatar_url || "assets/pedagog_ia.png",
userAvatarUrl: configRes.rows[0].user_avatar_url || "assets/pedagog_user.png",
temperaturePreset: configRes.rows[0].temperature_preset || "equilibrado"
};
console.log('[Database Init] Configurações do agente carregadas do banco de dados:', agentConfigCache.agentName);
} else {
console.log('[Database Init] Migrando configurações do agente do arquivo local...');
let localConfig = {
agentName: "Kemily",
kemilyAvatarUrl: "assets/kemily.png",
camilaAvatarUrl: "assets/camila_prof.png",
agentName: "PedagogIA",
iaAvatarUrl: "assets/pedagog_ia.png",
userAvatarUrl: "assets/pedagog_user.png",
temperaturePreset: "equilibrado"
};
try {
@@ -2497,10 +2513,15 @@ async function initDatabase() {
} catch (err) {
console.error('[Database Init] Erro ao ler agent_config.json local:', err.message);
}
agentConfigCache = localConfig;
agentConfigCache = {
agentName: localConfig.agentName || "PedagogIA",
iaAvatarUrl: localConfig.iaAvatarUrl || localConfig.kemilyAvatarUrl || "assets/pedagog_ia.png",
userAvatarUrl: localConfig.userAvatarUrl || localConfig.camilaAvatarUrl || "assets/pedagog_user.png",
temperaturePreset: localConfig.temperaturePreset || "equilibrado"
};
await dbPool.query(
"INSERT INTO escola.config (key, agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (key) DO NOTHING;",
['current', localConfig.agentName, localConfig.kemilyAvatarUrl, localConfig.camilaAvatarUrl, localConfig.temperaturePreset || 'equilibrado']
"INSERT INTO escola.config (key, agent_name, ia_avatar_url, user_avatar_url, temperature_preset) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (key) DO NOTHING;",
['current', agentConfigCache.agentName, agentConfigCache.iaAvatarUrl, agentConfigCache.userAvatarUrl, agentConfigCache.temperaturePreset]
);
}
@@ -2663,7 +2684,7 @@ app.post('/api/observacao/analisar', requireAuth, async (req, res) => {
try {
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
const temperaturePreset = agentConfig.temperaturePreset || 'equilibrado';
const presetDesc = TEMPERATURE_PRESETS[temperaturePreset]?.description || TEMPERATURE_PRESETS['equilibrado'].description;
const presetLabel = TEMPERATURE_PRESETS[temperaturePreset]?.label || 'Equilibrado';
@@ -3194,7 +3215,7 @@ app.post('/api/modelos/gerar-relatorio', requireAuth, async (req, res) => {
}).join('\n\n---\n\n');
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
const isGlobal = crianca === 'todas';
const targetStudentInfo = isGlobal
@@ -3445,7 +3466,7 @@ app.get('/api/observacoes/resumo', requireAuth, async (req, res) => {
const combined = texts.join('\n\n---\n\n');
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
const compilePrompt = `Você é a ${agentName}, assistente pedagógica. Compilar um RESUMO PEDAGÓGICO consolidado a partir de várias observações de uma criança.
@@ -3551,7 +3572,7 @@ app.post('/api/upload-avatar', requireAuth, (req, res) => {
// Rota de login (página)
app.get('/login', (req, res) => {
const session = req.signedCookies.camila_session || req.cookies.camila_session;
const session = req.signedCookies.pedagog_session || req.cookies.pedagog_session || req.signedCookies.camila_session || req.cookies.camila_session;
if (session === 'authenticated') {
res.redirect('/');
} else {
@@ -3574,7 +3595,7 @@ app.post('/api/login', (req, res) => {
const { password } = req.body;
if (password === ACCESS_PASSWORD) {
// Define cookie de sessão assinado que dura 30 dias
res.cookie('camila_session', 'authenticated', {
res.cookie('pedagog_session', 'authenticated', {
signed: true,
httpOnly: true,
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 dias
@@ -3589,6 +3610,7 @@ app.post('/api/login', (req, res) => {
// API para Logout
app.post('/api/logout', (req, res) => {
res.clearCookie('pedagog_session');
res.clearCookie('camila_session');
res.json({ success: true });
});
@@ -3650,10 +3672,10 @@ app.get('/generated-media/:filename', async (req, res, next) => {
// Servir arquivos estáticos do diretório public
app.use(express.static(path.join(__dirname, 'public')));
// System prompt da Kemily (injetado em todas as conversas)
const KEMILY_SYSTEM_PROMPT = {
// System prompt da PedagogIA (injetado em todas as conversas)
const PEDAGOG_IA_SYSTEM_PROMPT = {
role: "system",
content: `Você é a Kemily, assistente virtual e extensionista digital da Profª Camila Martella Gasparini Reifonas.
content: `Você é a PedagogIA, assistente virtual e extensionista digital da Profª Camila Martella Gasparini Reifonas.
═══════════════════════════════════════════════════
IDENTIDADE — Quem é a Camila (para que você possa falar dela com precisão)
@@ -4545,7 +4567,7 @@ app.post('/api/chat', requireAuth, async (req, res) => {
// FLUXO PADRÃO DE TEXTO (OpenRouter com SSE streaming original, com fallback Groq)
// ==========================================================================
const agentConfig = readAgentConfig();
const agentName = agentConfig.agentName || "Kemily";
const agentName = agentConfig.agentName || "PedagogIA";
const temperaturePreset = agentConfig.temperaturePreset || 'equilibrado';
const temperature = TEMPERATURE_PRESETS[temperaturePreset]?.value || 0.6;
@@ -4622,7 +4644,8 @@ app.post('/api/chat', requireAuth, async (req, res) => {
const dynamicSystemPrompt = {
role: "system",
content: styleDirective + languageDirective + KEMILY_SYSTEM_PROMPT.content
content: styleDirective + languageDirective + PEDAGOG_IA_SYSTEM_PROMPT.content
.replace(/Você é a PedagogIA/g, `Você é a ${agentName}`)
.replace(/Você é a Kemily/g, `Você é a ${agentName}`)
.replace('INFORMAÇÕES PESSOAIS:', `${knowledgeText}${observationsContext}INFORMAÇÕES PESSOAIS:`) + styleDirective + languageDirective
};
@@ -4671,8 +4694,8 @@ app.post('/api/chat', requireAuth, async (req, res) => {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'HTTP-Referer': 'https://camila.reifonas.cloud',
'X-Title': 'Camila ChatGPT replica',
'HTTP-Referer': 'https://pedagog.app',
'X-Title': 'Pedagog AI',
'Content-Type': 'application/json'
},
body: JSON.stringify({