feat(secretaria): assina as respostas da IA com "*Nome:*" em negrito

A Secretária passa a prefixar cada resposta enviada com o PRIMEIRO nome do
agente em negrito (ex.: "Ana — Atendente Virtual" → "*Ana:*\n<resposta>"),
igual à assinatura do operador humano — identifica a IA na caixa compartilhada
e é por-sessão (número com agente "Ana Clínica A" assina "*Ana:*"). Aplicado no
envio e no corpo persistido, nos dois caminhos (auto-reply e painel /ask).

Testado em dev: a Ana respondeu no WhatsApp com "*Ana:*" em negrito.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Deploy Agent
2026-07-06 00:19:30 +02:00
parent 00ec9ed933
commit 9bbfe498e2
3 changed files with 28 additions and 9 deletions
@@ -205,11 +205,17 @@ function buildExtRoutes(prisma, manager, db, config, hooks, io) {
const router = (0, express_1.Router)();
// ── Helper: envia reply da IA via WA e persiste no banco principal ─────────
async function sendSecretariaReply(opts) {
const { instanceId, tenantId, chatId, jid, reply } = opts;
const { instanceId, tenantId, chatId, jid, reply, agentName } = opts;
const sock = manager?.getSocket(instanceId);
if (!sock)
return;
const sent = await sock.sendMessage(jid, { text: reply }).catch(() => null);
// Assinatura da Secretária: prefixa "*Nome:*\n" (negrito) com o PRIMEIRO nome
// do agente (ex.: "Ana — Atendente Virtual" → "Ana"). Identifica a IA na caixa
// compartilhada — como a assinatura do operador humano. O ":" fica DENTRO do
// negrito p/ todos os dispositivos verem "Ana:" em negrito consistente.
const first = (agentName ?? '').trim().split(/[\s—–-]+/).filter(Boolean)[0];
const text = first ? `*${first}:*\n${reply}` : reply;
const sent = await sock.sendMessage(jid, { text }).catch(() => null);
const persisted = await prisma.message.create({
data: {
tenantId,
@@ -219,7 +225,7 @@ function buildExtRoutes(prisma, manager, db, config, hooks, io) {
messageId: sent?.key.id ?? `sec-${Date.now()}`,
fromMe: true,
type: 'TEXT',
body: reply,
body: text,
status: 'SENT',
timestamp: new Date(),
},
@@ -345,7 +351,8 @@ function buildExtRoutes(prisma, manager, db, config, hooks, io) {
const brain = new brain_1.ProtocolEngine(db, config);
const reply = await brain.chat(conv.id, text.trim(), { tenantId, hooks, clinicaId: channel?.clinica_id, instanceId });
await sock?.sendPresenceUpdate('paused', jid).catch(() => { });
await sendSecretariaReply({ instanceId, tenantId, chatId, jid, reply });
const secAgent = await db('sec_agents').where({ id: conv.agent_id }).select('name').first();
await sendSecretariaReply({ instanceId, tenantId, chatId, jid, reply, agentName: secAgent?.name });
});
// ── Escalation notification listener ──────────────────────────────────────
// When escalar_humano tool fires, send a WA message to the configured admin phone.
@@ -1795,12 +1802,14 @@ function buildExtRoutes(prisma, manager, db, config, hooks, io) {
select: { id: true, instanceId: true },
});
if (chat) {
const secAgent = await db('sec_agents').where({ id: conv.agent_id }).select('name').first();
await sendSecretariaReply({
instanceId: chat.instanceId,
tenantId,
chatId: chat.id,
jid: chatId,
reply,
agentName: secAgent?.name,
});
}
res.json({