feat(messages): derive messagePrefix from identity.name

When identity.name is configured, use it for the default messagePrefix
instead of hardcoded '[clawdbot]'. Falls back to 'clawdbot' if not set.

This allows users to customize how their bot identifies itself in messages
by setting identity.name in their config or IDENTITY.md.
This commit is contained in:
Richard Poelderl
2026-01-09 15:45:18 +01:00
committed by Peter Steinberger
parent f436808735
commit 8112b276c0
3 changed files with 45 additions and 3 deletions

View File

@@ -891,7 +891,7 @@ export type AudioConfig = {
};
export type MessagesConfig = {
messagePrefix?: string; // Prefix added to all inbound messages (default: "[clawdbot]" if no allowFrom, else "")
messagePrefix?: string; // Prefix added to all inbound messages (default: "[{identity.name}]" or "[clawdbot]" if no allowFrom, else "")
responsePrefix?: string; // Prefix auto-added to all outbound replies (e.g., "🦞")
groupChat?: GroupChatConfig;
queue?: QueueConfig;

View File

@@ -1959,4 +1959,45 @@ describe("web auto-reply", () => {
expect(replies).toEqual(["🦞 🧩 tool1", "🦞 🧩 tool2", "🦞 final"]);
resetLoadConfigMock();
});
it("uses identity.name for messagePrefix when set", async () => {
setLoadConfigMock(() => ({
identity: { name: "Richbot", emoji: "🦁" },
}));
let capturedOnMessage:
| ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>)
| undefined;
const reply = vi.fn();
const listenerFactory = async (opts: {
onMessage: (
msg: import("./inbound.js").WebInboundMessage,
) => Promise<void>;
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
const resolver = vi.fn().mockResolvedValue({ text: "hello" });
await monitorWebProvider(false, listenerFactory, false, resolver);
expect(capturedOnMessage).toBeDefined();
await capturedOnMessage?.({
body: "hi",
from: "+1555",
to: "+2666",
id: "msg1",
sendComposing: vi.fn(),
reply,
sendMedia: vi.fn(),
});
// Check that resolver received the message with identity-based prefix
expect(resolver).toHaveBeenCalled();
const resolverArg = resolver.mock.calls[0][0];
expect(resolverArg.Body).toContain("[Richbot]");
expect(resolverArg.Body).not.toContain("[clawdbot]");
resetLoadConfigMock();
});
});

View File

@@ -1033,11 +1033,12 @@ export async function monitorWebProvider(
};
const buildLine = (msg: WebInboundMsg) => {
// Build message prefix: explicit config > default based on allowFrom
// Build message prefix: explicit config > identity name > default "clawdbot"
let messagePrefix = cfg.messages?.messagePrefix;
if (messagePrefix === undefined) {
const hasAllowFrom = (cfg.whatsapp?.allowFrom?.length ?? 0) > 0;
messagePrefix = hasAllowFrom ? "" : "[clawdbot]";
const identityName = cfg.identity?.name?.trim() || "clawdbot";
messagePrefix = hasAllowFrom ? "" : `[${identityName}]`;
}
const prefixStr = messagePrefix ? `${messagePrefix} ` : "";
const senderLabel =