🔧 feat: Sistema de identidade dinâmica do agente - modal de configurações, avatares customizáveis, nome dinâmico sincronizado com Hermes/Telegram
This commit is contained in:
@@ -25,6 +25,92 @@ const requireAuth = (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const CONFIG_FILE_PATH = path.join(__dirname, 'agent_config.json');
|
||||
|
||||
function readAgentConfig() {
|
||||
try {
|
||||
if (fs.existsSync(CONFIG_FILE_PATH)) {
|
||||
return JSON.parse(fs.readFileSync(CONFIG_FILE_PATH, 'utf8'));
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erro ao ler agent_config.json:', e);
|
||||
}
|
||||
return {
|
||||
agentName: "Kemily",
|
||||
kemilyAvatarUrl: "assets/kemily.png",
|
||||
camilaAvatarUrl: "assets/camila_prof.png"
|
||||
};
|
||||
}
|
||||
|
||||
function writeAgentConfig(config) {
|
||||
try {
|
||||
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(config, null, 2), 'utf8');
|
||||
// Copiar também para o BotVPS para sincronização com o Hermes
|
||||
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');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erro ao salvar agent_config.json:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Rota GET para obter configurações do agente
|
||||
app.get('/api/agent-config', requireAuth, (req, res) => {
|
||||
const config = readAgentConfig();
|
||||
res.json(config);
|
||||
});
|
||||
|
||||
// Rota POST para atualizar configurações do agente
|
||||
app.post('/api/agent-config', requireAuth, (req, res) => {
|
||||
const { agentName, kemilyAvatarUrl, camilaAvatarUrl } = 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"
|
||||
};
|
||||
writeAgentConfig(config);
|
||||
res.json({ success: true, config });
|
||||
});
|
||||
|
||||
// Rota POST para upload de imagem em base64
|
||||
app.post('/api/upload-avatar', requireAuth, (req, res) => {
|
||||
const { avatarType, base64Data } = req.body;
|
||||
if (!avatarType || !base64Data) {
|
||||
return res.status(400).json({ error: 'Dados inválidos' });
|
||||
}
|
||||
|
||||
const matches = base64Data.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
|
||||
if (!matches || matches.length !== 3) {
|
||||
return res.status(400).json({ error: 'Formato de imagem inválido' });
|
||||
}
|
||||
|
||||
const imageBuffer = Buffer.from(matches[2], 'base64');
|
||||
const fileExt = matches[1].split('/')[1] || 'png';
|
||||
const fileName = `custom_${avatarType}_avatar_${Date.now()}.${fileExt}`;
|
||||
|
||||
// Garantir que a pasta public/assets existe
|
||||
const assetsDir = path.join(__dirname, 'public', 'assets');
|
||||
if (!fs.existsSync(assetsDir)) {
|
||||
fs.mkdirSync(assetsDir, { recursive: true });
|
||||
}
|
||||
|
||||
const filePath = path.join(assetsDir, fileName);
|
||||
|
||||
fs.writeFile(filePath, imageBuffer, (err) => {
|
||||
if (err) {
|
||||
console.error('Erro ao salvar avatar:', err);
|
||||
return res.status(500).json({ error: 'Erro ao salvar arquivo' });
|
||||
}
|
||||
return res.json({ success: true, url: `assets/${fileName}` });
|
||||
});
|
||||
});
|
||||
|
||||
// Rota de login (página)
|
||||
app.get('/login', (req, res) => {
|
||||
const session = req.signedCookies.camila_session || req.cookies.camila_session;
|
||||
@@ -737,7 +823,15 @@ app.post('/api/chat', requireAuth, async (req, res) => {
|
||||
// ==========================================================================
|
||||
// FLUXO PADRÃO DE TEXTO (OpenRouter com SSE streaming original, com fallback Groq)
|
||||
// ==========================================================================
|
||||
const enrichedMessages = [KEMILY_SYSTEM_PROMPT, ...messages];
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
|
||||
const dynamicSystemPrompt = {
|
||||
role: "system",
|
||||
content: KEMILY_SYSTEM_PROMPT.content.replace(/Você é a Kemily/g, `Você é a ${agentName}`)
|
||||
};
|
||||
|
||||
const enrichedMessages = [dynamicSystemPrompt, ...messages];
|
||||
|
||||
try {
|
||||
let chatResponse;
|
||||
|
||||
Reference in New Issue
Block a user