mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 17:41:22 +00:00
feat: support per-channel ackReaction config (#17092) (thanks @zerone0x)
This commit is contained in:
79
src/agents/identity.test.ts
Normal file
79
src/agents/identity.test.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveAckReaction } from "./identity.js";
|
||||
|
||||
describe("resolveAckReaction", () => {
|
||||
it("prefers account-level overrides", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
messages: { ackReaction: "👀" },
|
||||
agents: { list: [{ id: "main", identity: { emoji: "✅" } }] },
|
||||
channels: {
|
||||
slack: {
|
||||
ackReaction: "eyes",
|
||||
accounts: {
|
||||
acct1: { ackReaction: " party_parrot " },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main", { channel: "slack", accountId: "acct1" })).toBe(
|
||||
"party_parrot",
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to channel-level overrides", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
messages: { ackReaction: "👀" },
|
||||
agents: { list: [{ id: "main", identity: { emoji: "✅" } }] },
|
||||
channels: {
|
||||
slack: {
|
||||
ackReaction: "eyes",
|
||||
accounts: {
|
||||
acct1: { ackReaction: "party_parrot" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main", { channel: "slack", accountId: "missing" })).toBe(
|
||||
"eyes",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses the global ackReaction when channel overrides are missing", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
messages: { ackReaction: "✅" },
|
||||
agents: { list: [{ id: "main", identity: { emoji: "😺" } }] },
|
||||
};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main", { channel: "discord" })).toBe("✅");
|
||||
});
|
||||
|
||||
it("falls back to the agent identity emoji when global config is unset", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: { list: [{ id: "main", identity: { emoji: "🔥" } }] },
|
||||
};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main", { channel: "discord" })).toBe("🔥");
|
||||
});
|
||||
|
||||
it("returns the default emoji when no config is present", () => {
|
||||
const cfg: OpenClawConfig = {};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main")).toBe("👀");
|
||||
});
|
||||
|
||||
it("allows empty strings to disable reactions", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
messages: { ackReaction: "👀" },
|
||||
channels: {
|
||||
telegram: {
|
||||
ackReaction: "",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(resolveAckReaction(cfg, "main", { channel: "telegram" })).toBe("");
|
||||
});
|
||||
});
|
||||
@@ -10,11 +10,37 @@ export function resolveAgentIdentity(
|
||||
return resolveAgentConfig(cfg, agentId)?.identity;
|
||||
}
|
||||
|
||||
export function resolveAckReaction(cfg: OpenClawConfig, agentId: string): string {
|
||||
export function resolveAckReaction(
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
opts?: { channel?: string; accountId?: string },
|
||||
): string {
|
||||
// L1: Channel account level
|
||||
if (opts?.channel && opts?.accountId) {
|
||||
const channelCfg = getChannelConfig(cfg, opts.channel);
|
||||
const accounts = channelCfg?.accounts as Record<string, Record<string, unknown>> | undefined;
|
||||
const accountReaction = accounts?.[opts.accountId]?.ackReaction as string | undefined;
|
||||
if (accountReaction !== undefined) {
|
||||
return accountReaction.trim();
|
||||
}
|
||||
}
|
||||
|
||||
// L2: Channel level
|
||||
if (opts?.channel) {
|
||||
const channelCfg = getChannelConfig(cfg, opts.channel);
|
||||
const channelReaction = channelCfg?.ackReaction as string | undefined;
|
||||
if (channelReaction !== undefined) {
|
||||
return channelReaction.trim();
|
||||
}
|
||||
}
|
||||
|
||||
// L3: Global messages level
|
||||
const configured = cfg.messages?.ackReaction;
|
||||
if (configured !== undefined) {
|
||||
return configured.trim();
|
||||
}
|
||||
|
||||
// L4: Agent identity emoji fallback
|
||||
const emoji = resolveAgentIdentity(cfg, agentId)?.emoji?.trim();
|
||||
return emoji || DEFAULT_ACK_REACTION;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user