mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 10:11:24 +00:00
fix(actions): layer per-account gate fallback
This commit is contained in:
@@ -107,13 +107,11 @@ describe("discord message actions", () => {
|
||||
expect(actions).not.toContain("ban");
|
||||
});
|
||||
|
||||
it("shallow merge: account actions object replaces base entirely", () => {
|
||||
// Base has reactions: false, account has actions: { moderation: true }
|
||||
// Shallow merge replaces the whole actions object, so reactions defaults to true
|
||||
it("inherits top-level channel gate when account overrides moderation only", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
discord: {
|
||||
actions: { reactions: false },
|
||||
actions: { channels: false },
|
||||
accounts: {
|
||||
vime: { token: "d1", actions: { moderation: true } },
|
||||
},
|
||||
@@ -122,9 +120,25 @@ describe("discord message actions", () => {
|
||||
} as OpenClawConfig;
|
||||
const actions = discordMessageActions.listActions?.({ cfg }) ?? [];
|
||||
|
||||
// vime's actions override replaces entire actions object; reactions defaults to true
|
||||
expect(actions).toContain("react");
|
||||
expect(actions).toContain("timeout");
|
||||
expect(actions).not.toContain("channel-create");
|
||||
});
|
||||
|
||||
it("allows account to explicitly re-enable top-level disabled channels", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
discord: {
|
||||
actions: { channels: false },
|
||||
accounts: {
|
||||
vime: { token: "d1", actions: { moderation: true, channels: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const actions = discordMessageActions.listActions?.({ cfg }) ?? [];
|
||||
|
||||
expect(actions).toContain("timeout");
|
||||
expect(actions).toContain("channel-create");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -473,6 +487,24 @@ describe("telegramMessageActions", () => {
|
||||
expect(actions).not.toContain("sticker-search");
|
||||
});
|
||||
|
||||
it("inherits top-level reaction gate when account overrides sticker only", () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
telegram: {
|
||||
actions: { reactions: false },
|
||||
accounts: {
|
||||
media: { botToken: "tok", actions: { sticker: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const actions = telegramMessageActions.listActions?.({ cfg }) ?? [];
|
||||
|
||||
expect(actions).toContain("sticker");
|
||||
expect(actions).toContain("sticker-search");
|
||||
expect(actions).not.toContain("react");
|
||||
});
|
||||
|
||||
it("accepts numeric messageId and channelId for reactions", async () => {
|
||||
const cfg = { channels: { telegram: { botToken: "tok" } } } as OpenClawConfig;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { createActionGate } from "../../../agents/tools/common.js";
|
||||
import type { DiscordActionConfig } from "../../../config/types.discord.js";
|
||||
import { listEnabledDiscordAccounts } from "../../../discord/accounts.js";
|
||||
import type { ChannelMessageActionAdapter, ChannelMessageActionName } from "../types.js";
|
||||
import { createDiscordActionGate, listEnabledDiscordAccounts } from "../../../discord/accounts.js";
|
||||
import { handleDiscordMessageAction } from "./discord/handle-action.js";
|
||||
|
||||
export const discordMessageActions: ChannelMessageActionAdapter = {
|
||||
@@ -13,7 +12,9 @@ export const discordMessageActions: ChannelMessageActionAdapter = {
|
||||
return [];
|
||||
}
|
||||
// Union of all accounts' action gates (any account enabling an action makes it available)
|
||||
const gates = accounts.map((a) => createActionGate(a.config.actions));
|
||||
const gates = accounts.map((account) =>
|
||||
createDiscordActionGate({ cfg, accountId: account.accountId }),
|
||||
);
|
||||
const gate = (key: keyof DiscordActionConfig, defaultValue = true) =>
|
||||
gates.some((g) => g(key, defaultValue));
|
||||
const actions = new Set<ChannelMessageActionName>(["send"]);
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import type { TelegramActionConfig } from "../../../config/types.telegram.js";
|
||||
import type { ChannelMessageActionAdapter, ChannelMessageActionName } from "../types.js";
|
||||
import {
|
||||
createActionGate,
|
||||
readNumberParam,
|
||||
readStringArrayParam,
|
||||
readStringOrNumberParam,
|
||||
readStringParam,
|
||||
} from "../../../agents/tools/common.js";
|
||||
import { handleTelegramAction } from "../../../agents/tools/telegram-actions.js";
|
||||
import type { TelegramActionConfig } from "../../../config/types.telegram.js";
|
||||
import { extractToolSend } from "../../../plugin-sdk/tool-send.js";
|
||||
import { listEnabledTelegramAccounts } from "../../../telegram/accounts.js";
|
||||
import {
|
||||
createTelegramActionGate,
|
||||
listEnabledTelegramAccounts,
|
||||
} from "../../../telegram/accounts.js";
|
||||
import { isTelegramInlineButtonsEnabled } from "../../../telegram/inline-buttons.js";
|
||||
import type { ChannelMessageActionAdapter, ChannelMessageActionName } from "../types.js";
|
||||
|
||||
const providerId = "telegram";
|
||||
|
||||
@@ -48,7 +50,9 @@ export const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
return [];
|
||||
}
|
||||
// Union of all accounts' action gates (any account enabling an action makes it available)
|
||||
const gates = accounts.map((a) => createActionGate(a.config.actions));
|
||||
const gates = accounts.map((account) =>
|
||||
createTelegramActionGate({ cfg, accountId: account.accountId }),
|
||||
);
|
||||
const gate = (key: keyof TelegramActionConfig, defaultValue = true) =>
|
||||
gates.some((g) => g(key, defaultValue));
|
||||
const actions = new Set<ChannelMessageActionName>(["send"]);
|
||||
|
||||
Reference in New Issue
Block a user