refactor: centralize group sender identity

This commit is contained in:
Peter Steinberger
2026-01-17 03:31:57 +00:00
parent 204309dd3c
commit 3af391eec7
21 changed files with 236 additions and 222 deletions
@@ -216,12 +216,14 @@ describe("broadcast groups", () => {
expect(resolver).toHaveBeenCalledTimes(2);
for (const call of resolver.mock.calls.slice(0, 2)) {
const payload = call[0] as { Body: string };
const payload = call[0] as { Body: string; SenderName?: string; SenderE164?: string; SenderId?: string };
expect(payload.Body).toContain("Chat messages since your last reply");
expect(payload.Body).toContain("Alice (+111): hello group");
expect(payload.Body).toContain("[message_id: g1]");
expect(payload.Body).toContain("@bot ping");
expect(payload.Body).toContain("[from: Bob (+222)]");
expect(payload.SenderName).toBe("Bob");
expect(payload.SenderE164).toBe("+222");
expect(payload.SenderId).toBe("+222");
}
await capturedOnMessage?.({
@@ -166,7 +166,9 @@ describe("web auto-reply", () => {
expect(payload.Body).toContain("Alice (+111): hello group");
expect(payload.Body).toContain("[message_id: g1]");
expect(payload.Body).toContain("@bot ping");
expect(payload.Body).toContain("[from: Bob (+222)]");
expect(payload.SenderName).toBe("Bob");
expect(payload.SenderE164).toBe("+222");
expect(payload.SenderId).toBe("+222");
});
it("bypasses mention gating for owner /new in group chats", async () => {
@@ -183,7 +183,9 @@ describe("web auto-reply", () => {
expect(payload.Body).not.toContain("Chat messages since your last reply");
expect(payload.Body).not.toContain("Alice (+111): first");
expect(payload.Body).not.toContain("[message_id: g-always-1]");
expect(payload.Body).toContain("Bob: second");
expect(payload.Body).toContain("second");
expect(payload.SenderName).toBe("Bob");
expect(payload.SenderE164).toBe("+222");
expect(reply).toHaveBeenCalledTimes(1);
await cleanup();
+1 -5
View File
@@ -22,12 +22,8 @@ export function buildInboundLine(params: {
hasAllowFrom: (cfg.channels?.whatsapp?.allowFrom?.length ?? 0) > 0,
});
const prefixStr = messagePrefix ? `${messagePrefix} ` : "";
const senderLabel =
msg.chatType === "group" ? `${msg.senderName ?? msg.senderE164 ?? "Someone"}: ` : "";
const replyContext = formatReplyContext(msg);
const baseLine = `${prefixStr}${senderLabel}${msg.body}${
replyContext ? `\n\n${replyContext}` : ""
}`;
const baseLine = `${prefixStr}${msg.body}${replyContext ? `\n\n${replyContext}` : ""}`;
// Wrap with standardized envelope for the agent.
return formatAgentEnvelope({
+16 -19
View File
@@ -9,7 +9,7 @@ import {
} from "../../../auto-reply/reply/response-prefix-template.js";
import { resolveTextChunkLimit } from "../../../auto-reply/chunk.js";
import { formatAgentEnvelope } from "../../../auto-reply/envelope.js";
import { buildHistoryContext } from "../../../auto-reply/reply/history.js";
import { buildHistoryContextFromEntries, type HistoryEntry } from "../../../auto-reply/reply/history.js";
import { dispatchReplyWithBufferedBlockDispatcher } from "../../../auto-reply/reply/provider-dispatcher.js";
import type { getReplyFromConfig } from "../../../auto-reply/reply.js";
import type { ReplyPayload } from "../../../auto-reply/types.js";
@@ -77,30 +77,27 @@ export async function processMessage(params: {
if (params.msg.chatType === "group") {
const history = params.groupHistory ?? params.groupHistories.get(params.groupHistoryKey) ?? [];
if (history.length > 0) {
const lineBreak = "\\n";
const historyText = history
.map((m) => {
const bodyWithId = m.id ? `${m.body}\n[message_id: ${m.id}]` : m.body;
const historyEntries: HistoryEntry[] = history.map((m) => ({
sender: m.sender,
body: m.body,
timestamp: m.timestamp,
messageId: m.id,
}));
combinedBody = buildHistoryContextFromEntries({
entries: historyEntries,
currentMessage: combinedBody,
excludeLast: false,
formatEntry: (entry) => {
const bodyWithId = entry.messageId ? `${entry.body}\n[message_id: ${entry.messageId}]` : entry.body;
return formatAgentEnvelope({
channel: "WhatsApp",
from: conversationId,
timestamp: m.timestamp,
body: `${m.sender}: ${bodyWithId}`,
timestamp: entry.timestamp,
body: `${entry.sender}: ${bodyWithId}`,
});
})
.join(lineBreak);
combinedBody = buildHistoryContext({
historyText,
currentMessage: combinedBody,
lineBreak,
},
});
}
// Always surface who sent the triggering message so the agent can address them.
const senderLabel =
params.msg.senderName && params.msg.senderE164
? `${params.msg.senderName} (${params.msg.senderE164})`
: (params.msg.senderName ?? params.msg.senderE164 ?? "Unknown");
combinedBody = `${combinedBody}\\n[from: ${senderLabel}]`;
shouldClearGroupHistory = !(params.suppressGroupHistoryClear ?? false);
}